我工作在一个控制台应用程序将数据插入到MS SQL Server 2005数据库。 我必须要插入对象的列表。 这里我使用Employee类为例:
List<Employee> 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();
}
或者,我可以建立一个田埂插入查询是这样的:
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();
我想以后的情况会在一次插入数据行。 但是,如果我有几个数据KS,是有SQL查询字符串任何限制吗?
我不知道,如果一个插入多行比一个插入数据的一排更好,在性能方面?
任何建议,以做一个更好的办法?
其实,你有它编写的方式,你的第一选择会更快。
你的第二个例子中有一个问题。 你正在做的sql = + SQL +等,这会导致对循环的每个迭代要创建一个新的字符串对象。 (退房StringBuilder类)。 从技术上讲,你将要创建的初审一个新的字符串对象太多,但不同的是,它并没有从较字符串选项复制所有信息。
你有它设置方式时,SQL Server将不得不潜在评估时,你终于把它这是肯定会需要一些时间来弄清楚什么是应该做的一个巨大的查询。 我要说明,这取决于你需要插入的数目有多大的事。 如果n很小,你可能会是好的,但因为它的增长您的问题只会变得更糟。
批量插入比由于SQL服务器如何处理批量交易个人更快。 如果你要插入从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表UDT将包含表
CREATE TYPE MyUdt AS TABLE (Id int, Name nvarchar(50), salary int)
然后,你可以在你的存储过程和您的с#-code到批量插入使用该UDT。 SP:
CREATE PROCEDURE uspInsert
(@MyTvp AS MyTable READONLY)
AS
INSERT INTO [MyTable]
SELECT * FROM @MyTvp
C#(想象一下记录你需要插入已经包含在表“MyTable的”数据集DS的):
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-注射执行的这种方式。
批量复制通常比你自己做的插入更快。
如果您仍然想这样做在你建议的方式之一,你应该让这个你可以很容易地改变你发送到服务器的查询的大小。 这样,你可以在生产环境中优化速度以后。 查询时间可能v根据查询大小进制很多。
对于SQL Server查询批量大小列在被65536 *网络数据包大小。 网络数据包大小为默认4kbs,但可以改变。 退房的最大容量articl 2008年SQL E要得到的范围。 2005年SQL似乎也有相同的限制。