是否可以一次将整个 VB.NET DataTable 插入到 SQL Server 中

Is it possible to insert an entire VB.NET DataTable into a SQL Server at once

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

1
2
3
4
5
6
7
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 并让它排序并插入行吗?


尝试使用 SqlBulkCopy


在 SQL Server 2008 中,您可以使用表值参数:

1
2
3
4
5
Dim sc AS NEW SqlCommand(
 "INSERT INTO MyNewTable (field1, field2,...)"&
   "SELECT field1, field2,... FROM @MyTable;", MyDBConnection)
sc.Parameters.AddWithValue("@MyTable", MyDataset)  
sc.ExecuteNonQuery()


使用 SqlDataAdapter\\ 的 InsertCommand 来定义您的插入查询。然后使用您的数据集作为参数调用 DataAdapter\\'s Update Method 以使其推送数据。

类似:

1
2
3
4
5
6
7
8
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")


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


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

1
2
3
4
5
6
7
    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

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