Sql server 批量插入生成的ids退货订单
我希望能够非常高效地从C#应用程序向SQLServer大量插入数据表,并以正确的顺序检索插入的ID。 为了获得插入的主键的自动递增值,我在同一连接上使用以下方法:Sql server 批量插入生成的ids退货订单,sql-server,Sql Server,我希望能够非常高效地从C#应用程序向SQLServer大量插入数据表,并以正确的顺序检索插入的ID。 为了获得插入的主键的自动递增值,我在同一连接上使用以下方法: 创建表#StagingTable(..) BulkInsert DataTable到#StagingTable 在以下位置执行读卡器: insert into DestinationTable(....<columns_list>...) output inserted.ID -- primary key which is
insert into DestinationTable(....<columns_list>...)
output inserted.ID -- primary key which is auto increment
select <columns_list> from #StagingTable
假设每个表都有一个名为ID的bigint主键自动递增列。
我想知道上面的代码是否检索SQL生成的ID并将其与数据表正确关联。这里已经回答了这个问题,答案使用C#中的merge命令和ID映射解决了问题。我发送一个行ID并接收该行ID和关联的插入ID。这个解决方案排序不是更简单、更简单吗如果不使用merge命令,它是否可以与sql 2005一起工作?@RobertB。您想做什么?即使在一条语句中也没有顺序保证,除非您有一个
order BY
,更不用说跨无关语句了。您可以对数据表进行排序,并添加一个order BY
来插入您想要解决的实际问题是什么?为什么o您关心生成的ID?为什么不在客户机上生成ID、重新加载数据或只是在服务器上执行任何批量处理?您是否正在尝试处理具有关系的数据表?提高ORM的性能?我正在尝试处理具有关系的数据的批量插入,这种情况一次多个用户/计算机并行发生。I n我只需要按照我可以在客户端确定的顺序从服务器返回ID,最好是原始插入顺序。
using System.Data;
using System.Data.SqlClient;
using System.Web.UI.WebControls;
public static class SQLWrite
{
public static void BulkWrite(this DataTable table, string destinationTable, SqlConnection connection, int batchSize)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
string columnNamesAndSQLType = string.Join(", ", Enumerable.Range(0, table.Columns.Count).
Where(i => !table.Columns[i].AutoIncrement).
Select(i => "[" + table.Columns[i].ColumnName + "] " +
Parameter.ConvertTypeCodeToDbType(Type.GetTypeCode(table.Columns[i].DataType)).ToString()));
string columnNames = string.Join(", ", Enumerable.Range(0, table.Columns.Count).
Where(i => !table.Columns[i].AutoIncrement).
Select(i => "[" + table.Columns[i].ColumnName + "]"));
using (var command = connection.CreateCommand())
{
command.CommandText = @"
CREATE TABLE #StagingTable(
RowNumber INT IDENTITY(1, 1) NOT NULL,
" + columnNamesAndSQLType + @") ";
command.ExecuteNonQuery();
}
DataColumn autoIncrementColumn = null;
using (var copy = new SqlBulkCopy(connection))
{
copy.BatchSize = batchSize;
copy.DestinationTableName = destinationTable;
foreach (DataColumn column in table.Columns)
{
if (column.AutoIncrement)
{
autoIncrementColumn = column;
continue;
}
copy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(column.ColumnName, column.ColumnName));
}
copy.WriteToServer(table);
}
using (var command = connection.CreateCommand())
{
command.CommandText = @"
INSERT INTO dbo.DestinationTable(" + columnNames + @")
OUTPUT INSERTED.ID
SELECT " + columnNames + @"
FROM #StagingTable
ORDER BY RowNumber
"; //Will the inserted ID values be retrieved in the natural order of insertion - by RowNumber ?
using (var reader = command.ExecuteReader())
{
List<long> list = new List<long>();
while (reader.Read())
{
list.Add(reader.GetInt64(0));
}
list.Sort();
int rowIndex = 0;
foreach (DataRow row in table.Rows)
{
row[autoIncrementColumn] = list[rowIndex];
rowIndex++;
}
}
}
if (connection.State != ConnectionState.Closed)
{
connection.Close();
}
}
}