SQL插入一行或多行数据?

我正在使用控制台应用程序将数据插入到MS SQL Server 2005数据库。 我有一个要插入的对象列表。 这里我使用Employee类作为示例:

List employees; 

我能做的是在这个时间插入一个对象:

 foreach (Employee item in employees) { string sql = @"INSERT INTO Mytable (id, name, salary) values ('@id', '@name', '@salary')"; // replace @par with values cmd.CommandText = sql; // cmd is IDbCommand cmd.ExecuteNonQuery(); } 

或者我可以像这样构建一个balk插入查询:

 string sql = @"INSERT INTO MyTable (id, name, salary) "; int count = employees.Count; int index = 0; foreach (Employee item in employees) { sql = sql + string.format( "SELECT {0}, '{1}', {2} ", item.ID, item.Name, item.Salary); if ( index != (count-1) ) sql = sql + " UNION ALL "; index++ } cmd.CommandType = sql; cmd.ExecuteNonQuery(); 

我想后一种情况是一次插入数据行。 但是,如果我有几个k的数据,SQL查询字符串是否有任何限制?

在性能方面,我不确定一行插入多行是否优于一行插入一行数据?

有什么建议以更好的方式做到这一点?

实际上,你写它的方式,你的第一个选择将更快。

  1. 你的第二个例子有一个问题。 你正在做sql = + sql +等。这将导致为循环的每次迭代创建一个新的字符串对象。 (查看StringBuilder类)。 从技术上讲,您将在第一个实例中创建一个新的字符串对象,但区别在于它不必复制上一个字符串选项中的所有信息。

  2. 你设置它的方式,当你最终发送它时,SQL Server将不得不潜在地评估一个大规模的查询,这肯定需要一些时间来弄清楚它应该做什么。 我应该说,这取决于你需要做多大的插入。 如果n很小,你可能会好起来,但随着它的增长你的问题只会变得更糟。

由于SQL Server处理批处理事务的方式,批量插入比单个插入更快。 如果要从C#插入数据,则应采用第一种方法并将每500次插入包装说明并提交,然后执行下一次500,依此类推。 这也有一个好处,如果一个批处理失败,你可以捕获它们并找出出错的地方并重新插入那些。 还有其他方法可以做到,但这绝对是对所提供的两个示例的改进。

 var iCounter = 0; foreach (Employee item in employees) { if (iCounter == 0) { cmd.BeginTransaction; } string sql = @"INSERT INTO Mytable (id, name, salary) values ('@id', '@name', '@salary')"; // replace @par with values cmd.CommandText = sql; // cmd is IDbCommand cmd.ExecuteNonQuery(); iCounter ++; if(iCounter >= 500) { cmd.CommitTransaction; iCounter = 0; } } if(iCounter > 0) cmd.CommitTransaction; 

在MS SQL Server 2008中,您可以创建包含表的.Net table-UDT

 CREATE TYPE MyUdt AS TABLE (Id int, Name nvarchar(50), salary int) 

然后,您可以在存储过程中使用此UDT,并将с#-code用于批量插入。 SP:

 CREATE PROCEDURE uspInsert (@MyTvp AS MyTable READONLY) AS INSERT INTO [MyTable] SELECT * FROM @MyTvp 

C#(想象一下你需要插入的记录已包含在DataSet ds的表“MyTable”中):

 using(conn) { SqlCommand cmd = new SqlCommand("uspInsert", conn); cmd.CommandType = CommandType.StoredProcedure; SqlParameter myParam = cmd.Parameters.AddWithValue ("@MyTvp", ds.Tables["MyTable"]); myParam.SqlDbType = SqlDbType.Structured; myParam.TypeName = "dbo.MyUdt"; // Execute the stored procedure cmd.ExecuteNonQuery(); } 

所以,这就是解决方案。

最后,我想阻止你使用像你这样的代码(构建字符串然后执行这个字符串),因为这种执行方式可以用于SQL注入。

看看这个post ,我已经回答了关于表值参数的问题。

批量复制通常比自己进行插入更快。

如果您仍希望以您建议的方式执行此操作,则应该可以轻松更改发送到服务器的查询的大小。 这样,您可以在以后优化生产环境中的速度。 查询时间可能很长,具体取决于查询大小。

SQL Server查询的批处理大小列为65,536 *网络包大小。 网络数据包大小默认为4kbs,但可以更改。 查看SQL 2008的最大容量 ,以获得范围。 SQL 2005似乎也有相同的限制。