c#-将CSV上载到SQL Server
作者:互联网
我正在建立一个每月读取5个CSV文件的系统.这些文件应遵循某种格式和顺序.我有一个主表和5个临时表.首先读取每个CSV文件,然后将其批量插入其相应的临时表中.将5个csv文件批量插入各自的临时表后,我再次将所有记录从临时表插入到主表中.这样可以确保在将数据插入主表之前先上传所有文件.
我使用ASP.net构建了该系统,并且在调试和测试期间一切正常.每当我将应用程序部署到生产服务器时,就会发生此问题.部署应用程序后,我使用了在开发和测试期间上传的相同的csv文件,并且系统显示了从字符串到日期时间格式的数据转换错误.
我尝试了许多方法来解决此问题,但问题似乎仍然存在.我尝试将生产数据库的排序规则更改为开发期间使用的排序规则.我还尝试了更改生产服务器中的某些区域设置,但仍然无法正常工作.
我以为也许我可以通过编程方式来处理此问题,而不是将其从临时表批量插入主表中,所以我会编写某种for循环,将每个记录手动插入主表中,但是我想它会产生性能问题,因为我每次都会插入100,000条记录.
我想知道在部署过程中是否有人遇到过类似的问题.在我看来,应用程序的行为在部署后发生了变化,这仍然很奇怪.
以下是代码的一部分,在该代码中,它将stocking.csv文件上传到服务器,然后将csv批量插入到临时表TB_TEMP_INVENTORY中,然后将记录从temp插入到主表TB_CATTLE中.这是对其他4个文件执行的操作,几乎与此相同.
OleDbConnection conn = new OleDbConnection(ConfigurationManager.AppSettings["LivestockConnectionString"]);
OleDbCommand comm;
OleDbDataAdapter adapter;
DataTable table = new DataTable();
string file = string.Empty;
string content = string.Empty;
StreamReader reader;
StreamWriter writer;
string month = monthDropDownList.SelectedValue;
string year = yearDropDownList.SelectedItem.Text;
// upload inventory file
file = System.IO.Path.GetFileName(inventoryFileUpload.PostedFile.FileName);
inventoryFileUpload.PostedFile.SaveAs("C://LivestockCSV//" + file);
// clean inventory file
file = "C://LivestockCSV//" + file;
reader = new StreamReader(file);
content = reader.ReadToEnd();
reader.Close();
writer = new StreamWriter(file);
writer.Write(content.Replace("\"", "")); // remove quotation
writer.Close();
writer = new StreamWriter(file);
writer.Write(content.Replace(",NULL,", ",,")); // remove NULL
writer.Close();
writer = new StreamWriter(file);
writer.Write(content.Replace(",0,", ",,")); // remove 0 dates
writer.Close();
writer = new StreamWriter(file);
writer.Write(content.Replace(",0", ",")); // remove 0 dates at eol
writer.Close();
try
{
conn.Open();
comm = new OleDbCommand("TRUNCATE TABLE TB_TEMP_INVENTORY", conn); // clear temp table
comm.ExecuteNonQuery();
// bulk insert from csv to temp table
comm = new OleDbCommand(@"SET DATEFORMAT DMY;
BULK INSERT TB_TEMP_INVENTORY
FROM '" + file + "'" +
@" WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)", conn);
comm.ExecuteNonQuery();
// check if data for same month exists in cattle table
comm = new OleDbCommand(@"SELECT *
FROM TB_CATTLE
WHERE Report='Inventory' AND Month=" + month + " AND Year=" + year, conn);
if (comm.ExecuteScalar() != null)
{
comm = new OleDbCommand(@"DELETE
FROM TB_CATTLE
WHERE Report='Inventory' AND Month=" + month + " AND Year=" + year, conn);
comm.ExecuteNonQuery();
}
// insert into master cattle table
comm = new OleDbCommand(@"SET DATEFORMAT MDY;
INSERT INTO TB_CATTLE(ID, Sex, BirthDate, FirstCalveDate, CurrentUnit, OriginalCost, AccumulatedDepreciation, WrittenDownValue, NetRealizableValue, CapitalGainLoss, Month, Year, Report, Locked, UploadedBy, UploadedAt)
SELECT DISTINCT ID, Sex, BirthDate, FirstCalveDate, CurrentUnit, 0, 0, 0, 0, 0, " + month + ", " + year + @", 'Inventory', 0, 'Admin', '" + DateTime.Now + @"'
FROM TB_TEMP_INVENTORY", conn);
comm.ExecuteNonQuery();
conn.Close();
}
catch (Exception ex)
{
ClientScript.RegisterStartupScript(typeof(string), "key", "<script>alert('" + ex.Message + "');</script>");
return;
}
解决方法:
您没有指定如何进行插入,但是这里的一个合理选择是类似于SqlBulkCopy,它可以将DataTable或IDataReader用作输入.这将为您提供充分的机会来处理数据-内存(DataTable)或通过流API(IDataReader),同时仍使用有效的导入. CsvReader
是加载CSV的不错选择.
另一个选择是在登台表中使用非常基本的插入,然后通过TSQL代码处理数据.
为什么在开发/生产之间进行了更改?最可能的答案是:
>您在开发人员中使用的数据不具有代表性
>两者之间在环境/配置方面存在差异
标签:asp-net,sql-server-2008,c,sql-server 来源: https://codeday.me/bug/20191102/1989947.html