将 Excel 文件逐行导入到 SQL Server

发布于 2024-09-29 13:34:24 字数 2397 浏览 7 评论 0原文

我正在将 Excel 文件(仅大约 1000 条记录)导入到专用 SQL Server 数据库。由于我需要处理来自 Excel 的传入数据(每行添加 GUID,一些数据转换),因此我想逐行进行操作,并且不想批量导入(不过,我对事务没有任何反对意见)。

我对如何正确地做到这一点感到困惑。我可以使用带有参数的 SQLCommand,如下所示:

SqlCommand sqlCommand = new SqlCommand("insert into TestTable(GUID,Name,Pricing) values(@GUID,@Name,@Pricing)", sqlConn);
foreach (DataRow dr in ds.Tables[0].Rows) //<-- this is my Excel file to iterate through
{
 sqlCommander.Parameters.Clear();
 String refGUID = Guid.NewGuid().ToString();
 sqlCommander.Parameters.AddWithValue("GUID", refGUID);
 sqlCommander.Parameters.AddWithValue("Name", dr.ItemArray[0]);
 sqlCommander.Parameters.AddWithValue("Pricing", dr.ItemArray[1]);
 sqlCommander.ExecuteNonQuery();
}

或者我可以使用“连接”模式,如下所示:

SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT GUID, Name, Pricing FROM TestTable", sqlConn);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);

DataSet myDataSet = new DataSet();
dataAdapter.Fill(myDataSet, "TestTable");
foreach (DataRow dr in ds.Tables[0].Rows) //<-- this is my Excel file to iterate through
{
 DataRow row = myDataSet.Tables[0].NewRow();
 row["GUID"] = refGUID;
 row["Name"] = dr.ItemArray[0];
 row["Pricing"] = dr.ItemArray[1];
 myDataSet.Tables[0].Rows.Add(row);
 dataAdapter.Update(myDataSet);
}

现在我的问题如下:

  1. 发送一个命令是否更好?每行的 INSERT 命令(即 SqlCommand 方法)还是填充特殊的 DataSet(第二种方法)更好?我想向 SQL 服务器进行 1000 次插入是相当“愚蠢”的?
  2. dataAdapter.Update(myDataSet) <-- 我应该在迭代所有 Excel 行或每一行之后执行此操作(如上面的示例代码所示),这会神奇地创建一个事务吗?
  3. 我应该使用哪种方法? 还有 LINQ to SQL - 为什么不使用它(也许性能,因为另一层)?
  4. 当读取 Excel 文件时发生一些错误时,DataSet 会发生什么情况 - 更新是否仍推送到 SQL Server 还是所有内容都丢失了?


In short: I want to import an Excel file to an SQL server row-by-row whilst making changes on the data to be imported (and I don't want to use SSIS packages [because besides data conversion I am doing a lot more with the Excel file like importing it to Sharepoint and firing of Workflows] or BizTalk)
»» How to do that beautifully?
In the end I went ahead and bought Aspose Cells. Aspose has a very nice set of tools at their disposal.

I'm importing an Excel file (about 1000 records only) to a dedicated SQL Server database. As I need to work on the incoming data from Excel (add a GUID per row, some data conversions) I want to do it row by row and don't want to bulk import (I have nothing against transactions, though).

I'm confused on how to do it correctly. I can either use an SQLCommand with parameters like so:

SqlCommand sqlCommand = new SqlCommand("insert into TestTable(GUID,Name,Pricing) values(@GUID,@Name,@Pricing)", sqlConn);
foreach (DataRow dr in ds.Tables[0].Rows) //<-- this is my Excel file to iterate through
{
 sqlCommander.Parameters.Clear();
 String refGUID = Guid.NewGuid().ToString();
 sqlCommander.Parameters.AddWithValue("GUID", refGUID);
 sqlCommander.Parameters.AddWithValue("Name", dr.ItemArray[0]);
 sqlCommander.Parameters.AddWithValue("Pricing", dr.ItemArray[1]);
 sqlCommander.ExecuteNonQuery();
}

Or I can use the "connected" mode like so:

SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT GUID, Name, Pricing FROM TestTable", sqlConn);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);

DataSet myDataSet = new DataSet();
dataAdapter.Fill(myDataSet, "TestTable");
foreach (DataRow dr in ds.Tables[0].Rows) //<-- this is my Excel file to iterate through
{
 DataRow row = myDataSet.Tables[0].NewRow();
 row["GUID"] = refGUID;
 row["Name"] = dr.ItemArray[0];
 row["Pricing"] = dr.ItemArray[1];
 myDataSet.Tables[0].Rows.Add(row);
 dataAdapter.Update(myDataSet);
}

Now my questions are the following:

  1. Is it better to send an INSERT command for each row (that would be the SqlCommand method) or is it better to fill a special DataSet (2nd Method)? I guess it is rather "stupid" to have 1000's of inserts to an SQL server?
  2. dataAdapter.Update(myDataSet) <-- should I do that AFTER iterating through all Excel rows or for each row (as shown in the example code above), would this magically create a transaction?
  3. Which method should I use? There also is LINQ to SQL - why not use that (performance maybe, because of another layer)?
  4. What happens to the DataSet when some error occurs when reading out the Excel file - is the update still pushed to the SQL server or is everything lost?


In short: I want to import an Excel file to an SQL server row-by-row whilst making changes on the data to be imported (and I don't want to use SSIS packages [because besides data conversion I am doing a lot more with the Excel file like importing it to Sharepoint and firing of Workflows] or BizTalk)
»» How to do that beautifully?


In the end I went ahead and bought Aspose Cells. Aspose has a very nice set of tools at their disposal.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

征﹌骨岁月お 2024-10-06 13:34:24

您提到不想使用 SSIS - 但您考虑过 SqlBulkCopy 吗?那么除了 .NET 之外不需要任何东西,但您仍然可以使用最快/最直接的导入。

这将接受一个数据表,因此您可以在数据表中准备数据,然后触发。交易可选择支持 IIRC。对于更大的数据,您还可以实现 IDataReader 以提供完全流式上传(同时仍在传输中处理每一行)。

You mention not wanting to use SSIS - but have you considered SqlBulkCopy? Then there is no need for anything except .NET yet you can still use the fastest/most-direct import.

This will accept a DataTable, so you can prepare your data in a DataTable and then pull the trigger. Transactions are optionally supported IIRC. For larger data you can also implement IDataReader to provide fully streaming upload (while still processing each row in transit).

牵强ㄟ 2024-10-06 13:34:24

鉴于您对问题的描述:“我想将 Excel 文件逐行导入到 SQL 服务器,同时对要导入的数据进行更改” - SSIS 是完成这项工作的完美工具。

使用 SQL Server Integration Services SSIS 导入 Excel 数据时出现 unicode 和非 unicode 数据问题

Given your description of your problem: "I want to import an Excel file to an SQL server row-by-row whilst making changes on the data to be imported" - SSIS is the perfect tool for the job.

Importing Excel data with SQL Server Integration Services SSIS with unicode and non-unicode data issues

旧竹 2024-10-06 13:34:24

数据集可能最终会将 INSERT 语句发送到服务器,因此在我看来,最好只发送不包含数据集的 INSERT 语句。您还可以对流程进行更多控制,例如检查各个行是否有错误、日志记录等。

The dataSet will probably ending up sending the INSERT statements to the server, so in my opinion, is better to to just send the INSERT statements without the DataSet. You also can have more control over the process, like checking for individual rows for errors, logging, etc.

胡渣熟男 2024-10-06 13:34:24

您可以将处理后的数据表转换为 XML,并将其传递给 Sql 服务器中的存储过程(在一个查询中),然后让存储过程解析 XML 以创建记录。

You could convert your processed data table into XML and pass that to a stored procedure in Sql server (in one query) and have your stored procedure parse the XML to create the records.

静谧 2024-10-06 13:34:24
INSERT INTO [dbo].[TableName]
           ([ColumnName1]
           ,[ColumnName2])
)
SELECT [ColumnName1]
           ,[ColumnName2]

FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0','Data Source= PathToFile.xls;Extended Properties=Excel 8.0')...[Sheet1$]
INSERT INTO [dbo].[TableName]
           ([ColumnName1]
           ,[ColumnName2])
)
SELECT [ColumnName1]
           ,[ColumnName2]

FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0','Data Source= PathToFile.xls;Extended Properties=Excel 8.0')...[Sheet1$]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文