代码之家  ›  专栏  ›  技术社区  ›  Dennis G

逐行将Excel文件导入SQL Server

  •  3
  • Dennis G  · 技术社区  · 14 年前

    我正在将一个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
    2. dataAdapter.Update(myDataSet) <--我应该在遍历所有Excel行或每一行(如上面的示例代码所示)之后这样做,这会神奇地创建一个事务吗?
    3. 我应该用哪种方法?
    4. 发生了什么 数据集 当读取Excel文件时发生错误时-更新是否仍被推送到SQL服务器上,或者所有内容都丢失了?


    简而言之: 在对要导入的数据进行更改时,我希望逐行将Excel文件导入到SQL server中(而且我不希望使用SSIS包[因为除了数据转换之外,我对Excel文件做了更多的操作,如将其导入到Sharepoint并启动工作流]或BizTalk)
    怎么做得漂亮?
    最后我继续买了 Aspose Cells . Aspose有一套很好的工具供他们使用。
    5 回复  |  直到 13 年前
        1
  •  4
  •   Marc Gravell    14 年前

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

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

        3
  •  1
  •   Eduardo Molteni    14 年前

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

        4
  •  0
  •   Chris    14 年前

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

        5
  •  -1
  •   Grant    14 年前
    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$]