我正在使用SQL Server 2014.我的网络应用程序的一个功能是上传CSV文件,并将数据导入我的数据库中的一个表(称为TF
)(称为{{ 1}})。
我不知道该怎么做。
TMPA
我尝试了这段代码,但它无法运行。
PS:string excelPath = Server.MapPath("~/Files/") + Path.GetFileName(FileUpload2.PostedFile.FileName);
FileUpload1.SaveAs(excelPath);
SqlConnection con = new SqlConnection(@"Data Source=SAMSUNG-PC\SQLEXPRESS;Initial Catalog=TMPA;Persist Security Info=True");
StreamReader sr = new StreamReader(excelPath);
string line = sr.ReadLine();
string[] value = line.Split(',');
DataTable dt = new DataTable();
DataRow row;
foreach (string dc in value)
{
dt.Columns.Add(new DataColumn(dc));
}
while (!sr.EndOfStream)
{
value = sr.ReadLine().Split(',');
if (value.Length == dt.Columns.Count)
{
row = dt.NewRow();
row.ItemArray = value;
dt.Rows.Add(row);
}
}
SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
bc.DestinationTableName = "TF";
bc.BatchSize = dt.Rows.Count;
con.Open();
bc.WriteToServer(dt);
bc.Close();
con.Close();
的列数比CSV文件多:有些列是计算出来的,应该在每次插入后自动计算..
这是我的CSV文件的画布:4列:
TF
IdProduit,Mois,Reel,Budget
是字符串,IdProduit
是日期,Mois
和Reel
是浮点数。
另一方面,我的SQL Server表如下所示:
Budget
所有其他列应为空或自动计算。
帮助我!
答案 0 :(得分:1)
你走在正确的道路上。在将数据插入SQL Server时,使用SqlBulkCopy将提供最佳性能。但是,与编写自己的Csv解析器相反,我将通过Microsoft.VisualBasic程序集中的TextFieldParser类使用.NET Framework中提供的恒星解析器。您可能需要进行一些挖掘以查看SqlBulkCopy是否允许使用部分数据集。我不相信它,但您可以将缺少的列添加到DataTable中,然后再将其作为解决方法发送到SqlBulkCopy。
答案 1 :(得分:1)
我使用名为Filehelpers的开源.net库修复了它。 这是链接:http://www.filehelpers.net/
这就是我的所作所为:
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" OnClick = "UploadF" runat="server" Text="Importer" />
这是背后的代码:
[DelimitedRecord("|")]
public class TBFtable
{
public string IdProduit;
public DateTime Mois;
public float Reel;
public float Budget;
}
protected void UploadF(object sender, EventArgs e)
{
string excelPath = Server.MapPath("~/Files/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
FileUpload1.SaveAs(excelPath);
SqlServerStorage storage = new SqlServerStorage(typeof(TBFtable),ConfigurationManager.ConnectionStrings["bd"].ConnectionString);
storage.InsertSqlCallback = new InsertSqlHandler(GetInsertSqlCust);
TBFtable[] res = CommonEngine.ReadFile(typeof(TBFtable), excelPath) as TBFtable[];
storage.InsertRecords(res);
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('Données enregistrées avec succès !')", true);
}
protected string GetInsertSqlCust(object record)
{
TBFtable obj = (TBFtable) record;
return String.Format("INSERT INTO TF (IdProduit, Mois, Reel, Budget ) " + " VALUES ( '{0}' , '{1}' , '{2}' , '{3}' ); ", obj.IdProduit, obj.Mois,obj.Reel, obj.Budget );
}
答案 2 :(得分:0)
我知道这是一个古老的问题,但是对于任何可能感兴趣的人。
除非您确定文件永远不会很大,否则应避免像DataTable方法和(我认为)您接受的答案一样,将整个批处理加载到内存中并立即将其全部发送到SQL Server。 。您可能会冒着在客户端(在这种情况下,您的文件处理服务器)的内存不足异常的风险,或者更糟的是,在SQL Server方面。通过使用SqlBulkCopy类和IDataReader接口的实现,可以避免这种情况。
我写了一个程序包,我认为在您这样的情况下可能会引起您的兴趣。代码如下所示:
var dataReader = new CsvDataReader("pathToYourCsv",
new List<TypeCode>(4)
{
TypeCode.String, //IdProduit
TypeCode.DateTime, //Mois
TypeCode.Double, //Reel
TypeCode.Double //Budget
});
this.bulkCopyUtility.BulkCopy("tableName", dataReader);
对于更复杂的情况(灵活的列映射,csv文件中不存在的其他静态列值,值转换),还有其他配置选项。 package是开放源代码(project on Github),应该可以在.NET Core和.NET Framework上使用。
作为补充,进行大量SQL导入时,SQL Server恢复模式可能很重要。尽可能使用“简单日志记录”或“大容量日志记录”以避免大量事务文件。