【问题标题】:Is it possible to insert an entire VB.NET DataTable into a SQL Server at once是否可以一次将整个 VB.NET 数据表插入 SQL Server
【发布时间】:2010-12-04 17:23:37
【问题描述】:

我在 VB.NET 中有一个 SQLClient.DataSet,我想将整个内容插入到 SQL Server 表中,而无需执行以下操作:

For Each dr as Datarow in MyDataset
  Dim sc As New SqlCommand("INSERT INTO MyNewTable " & _
                            "VALUES (@column1, @column2)", MyDBConnection)
  sc.Parameters.AddWithValue("@column1", dr.Item(0))
  sc.Parameters.AddWithValue("@column2", dr.Item(1))
  sc.ExecuteNonQuery()
Next

由于我已经接近一百万行(都很瘦,所以空间不大),我显然不想运行这个循环并生成一百万个 INSERT 语句。

我知道一个选项是在我最初获取数据时使用链接服务器,因为它来自另一个 SQL Server,然后将其从那里插入到 INSERT。但是,如果我的应用程序中已经有数据,是否有更有效的方法来批量插入它?我可以以某种方式将 DataTable 作为参数传递给 SQL Server 并让它对其进行排序并插入行吗?

【问题讨论】:

    标签: sql sql-server vb.net tsql datatable


    【解决方案1】:

    试试SqlBulkCopy

    【讨论】:

    • 这看起来正是我想要的。我什至不知道这个课程存在 - 谢谢!
    • 它在大约四秒钟内插入了所有一百万条记录——这太完美了。再次感谢!
    【解决方案2】:

    在 SQL Server 2008 中,您可以使用 Table-Valued Parameters:

    Dim sc As New SqlCommand(
      "INSERT INTO MyNewTable (field1, field2,...)"&
        "SELECT field1, field2,... FROM @MyTable;", MyDBConnection) 
    sc.Parameters.AddWithValue("@MyTable", MyDataset)  
    sc.ExecuteNonQuery()
    

    【讨论】:

    • 我碰巧在使用 2008,这是一个很棒的主意!我想知道性能与 SQLBulkCopy 相比如何——我现在通过千兆 LAN 进行,但是通过较慢的 WAN 连接,有什么比较的想法吗?
    • 性能将由传输速度(客户端到服务器)驱动,并且批量复制和 TVP 之间的数据量差异很小,因此它们的行为应该相似。更好的衡量标准。
    【解决方案3】:

    使用SqlDataAdapter 的InsertCommand 来定义您的插入查询。然后使用您的数据集作为参数调用 DataAdapter 的更新方法以使其推送数据。

    类似:

    Dim DA As SqlDataAdapter = New SqlDataAdapter
    Dim Parm As New SqlParameter
    
    DA.InsertCommand = New SqlCommand("Insert Into tbl1(fld0, fld1, fld2) Values(@fld0, @fld1, @fld2)", conn)
    Parm = DA.InsertCommand.Parameters.Add(New SqlParameter ("@fld0", NVarChar, 50, "fld0"))
    Parm = sqlDA.InsertCommand.Parameters.Add(New SqlParameter ("@fld1", SqlDbType.NVarChar, 50, "fld1"))
    Parm = sqlDA.InsertCommand.Parameters.Add(New SqlParameter ("@fld2", SqlDbType.NVarChar, 50, "fld2"))
    DA.Update(dataset1, "tbl1")
    

    【讨论】:

    • 我考虑过这个想法,但我认为它仍然会为每一行生成一个 INSERT 语句。不过,至少它是在后台执行的,所以它肯定更干净。
    • 我意识到这是一篇旧帖子,但这篇 MSDN 文章似乎与性能相关...如果源表和目标表在同一个 SQL Server 实例中,使用Transact-SQL INSERT ... SELECT 语句复制数据。 msdn.microsoft.com/en-us/library/…
    【解决方案4】:

    您可以在 DataSet 上调用 .WriteXML() 并通过一次插入将其转储到数据库中。

    【讨论】:

      【解决方案5】:

      一种更简单的方法是使用表适配器。然后您可以使用 Fill 方法将数据表作为参数:

          Dim oStronglyTypedTable As StronglyTypedDataTable = GetTable() 'A custom function that creates your table from wherever you want)
          If Not oStronglyTypedTable Is Nothing Then
              Using oAdapter As New StronglyTypedTableAdapter
                  Dim res As Integer = oAdapter.Update(oStronglyTypedTable)
                  MsgBox(res & " rows have been updated.")
              End Using
          End If
      

      不要忘记将数据库“复制到输出目录”属性更改为“进行网络复制”并正确设置连接字符串...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-15
        • 1970-01-01
        • 2019-11-22
        • 2012-01-31
        • 1970-01-01
        • 2023-01-27
        • 1970-01-01
        相关资源
        最近更新 更多