如果您决定在您的 C# 应用程序中实现自己的传输机制,并且您确实在处理大量数据,那么请小心选择一种最终不会将数据逐行插入 SQL Server 的方法。显然是这样的方法
OdbcDataReader rdrAccess = cmdAccess.ExecuteReader();
while (rdrAccess.Read())
{
// insert a row into SQL Server
}
几乎肯定会很慢,但即使是单个 Access SQL 语句,例如
using (var cmd = new OdbcCommand())
{
cmd.Connection = connAccess;
cmd.CommandText =
$"INSERT INTO [ODBC;{connStrSqlOdbc}].[BulkTable] (id, txtcol) " +
$"SELECT ID, TextField AS txtcol FROM Table1 WHERE ID<=1000";
cmd.ExecuteNonQuery();
}
最终将发送 1000 条单独的 T-SQL 语句
exec sp_executesql N'INSERT INTO "dbo"."BulkTable" ("id","txtcol") VALUES (@P1,@P2)',N'@P1 int,@P2 nvarchar(50)',1,N'record000000'
exec sp_executesql N'INSERT INTO "dbo"."BulkTable" ("id","txtcol") VALUES (@P1,@P2)',N'@P1 int,@P2 nvarchar(50)',2,N'record000001'
exec sp_executesql N'INSERT INTO "dbo"."BulkTable" ("id","txtcol") VALUES (@P1,@P2)',N'@P1 int,@P2 nvarchar(50)',3,N'record000002'
...
exec sp_executesql N'INSERT INTO "dbo"."BulkTable" ("id","txtcol") VALUES (@P1,@P2)',N'@P1 int,@P2 nvarchar(50)',1000,N'record000999'
到 SQL Server。
您最好的选择可能是使用System.Data.SqlClient 和SqlBulkCopy 对象,就像这样
using (var cmd = new OdbcCommand())
{
cmd.Connection = connAccess;
cmd.CommandText = "SELECT ID, TextField AS txtcol FROM Table1 WHERE ID<=1000";
using (OdbcDataReader rdr = cmd.ExecuteReader())
{
using (var sbc = new SqlBulkCopy(connStrSqlClient))
{
sbc.DestinationTableName = "BulkTable";
sbc.WriteToServer(rdr);
}
}
}
在我的测试网络上,SqlBulkCopy 方法始终在不到 INSERT INTO ... SELECT 方法所用时间的十分之一内完成。