【发布时间】:2011-11-09 15:29:07
【问题描述】:
我正在构建一个每月读取 5 个 CSV 文件的系统。这些文件应该遵循一定的格式和顺序。我有一个主表和 5 个临时表。首先读取每个 CSV 文件,然后将其批量插入到其相应的临时表中。在将 5 个 csv 文件批量插入到它们各自的临时表中后,我再次将临时表中的所有记录插入到主表中。这样可以确保在将数据插入主表之前先上传所有文件。
我使用 ASP.net 构建了这个系统,在调试和测试期间一切正常。每当我将应用程序部署到生产服务器时,就会出现问题。部署应用程序后,我使用了在开发和测试期间上传的相同 csv 文件,系统显示从字符串到日期时间格式的数据转换错误。
我尝试了很多方法来解决此问题,但问题似乎仍然存在。我尝试将生产数据库的排序规则更改为我在开发过程中使用的排序规则。我也尝试在生产服务器中更改一些区域设置,但仍然无法正常工作。
我想也许我可以以编程方式处理这个问题,而不是从临时表批量插入到主表中,我会编写某种 for 循环,将每条记录手动插入到主表中,但我想它会造成性能问题,因为我每次将插入大约 100,000 条记录。
我想知道是否有人在部署过程中遇到过类似的问题。部署后应用程序的行为发生了变化,这对我来说仍然很奇怪。
以下是代码的一部分,它将 inventory.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;
}
【问题讨论】:
-
您的环境发生了变化,因此您的应用程序的行为也发生了变化。什么是 SQL 错误 - 尝试提供一些示例数据,即在开发/测试中有效但在生产中失败的时间字段示例。
-
出色的帖子@Siva。 SSIS 绝对是我想学习的工具。我浏览了帖子并创建了一个小型测试项目,插入进行得很顺利。有没有办法在我已经完成的应用程序中包含 SSIS 的功能。有没有办法可以实例化或调用 ssis 对象来触发将 csvs 读取到我的数据库中。谢谢你指点我这个
-
@moeabdol:我觉得最好把所有SQL代码封装成一个存储过程,有两个参数
CREATE PROCEDURE pImportLiveStock (@pMonth TINYINT, @pYear SMALLINT) AS TRUNCATE TABLE TB_TEMP_INVENTORY;...。
标签: c# asp.net sql-server sql-server-2008