由于没有Sqlserver数组参数,最好的方法是什么?

我需要在sqlserver中创建多个记录,每个记录在列A中具有相同的值,但在列B中具有唯一值。我在列中具有列B的值。

我正在使用VS2008,aspnet,c#3.5,sqlserver 2005。

我最好过

选项1。

从c#代码中调用sqlserver中的存储过程,然后在tsql中执行存储过程中的所有处理工作?

这将涉及将c#数组中的所有值组合成一个逗号分隔的字符串,并将字符串作为参数传递给tsql,然后循环并将字符串拆分为单个值并为每个值插入记录,所有这些都在存储过程中。

从我所看到的,如果需要,这将涉及轻松回滚,但在tsql中非常笨拙的字符串处理。

要么

选项2。

在c#中循环并将数据作为sqlparams从c#一次传递到存储过程以插入每个记录。

即,foreach(myarray中的int键)…插入一条记录

我可以在睡眠中执行此代码,但如果在处理过程中发生了某些事情,我将如何能够回滚? 我应该在一个单独的connection.open和connection.close中进行循环吗?

这样做有没有其他选择?

这里广泛介绍了这个主题: SQL 2005中的数组和列表

实现此目的的最简单方法是使用选项1:将数组作为分隔字符串传递。 我曾经在sql2005之前的日子里和这个TSQL分割函数一起做这个。 我会使用“|”传递数组 作为分隔符。

这些天,我将数组序列化为XML,然后将内容插入到表变量中,以便使用sp_xml_preparedocument存储过程进行处理。

我不会使用选项2,因为它会对数据库进行多次调用。

两个选项都有它们的优点(选项1是单个往返,选项2不使用hokey字符串处理),但我可能最终选择2.选项1受varchars的大小限制(8000除非你使用varchar(MAX) ;我不知道在逗号分隔的varchar(MAX)字符串上的性能是多么长。

至于回滚,是的,只需在单个打开的连接上执行所有操作并使用SqlTransaction对象。

例如…

 using(SqlConnection conn = new SqlConnection("connection string")) { conn.Open(); using(SqlTransaction trans = conn.BeginTrasnaction()) { try { using(SqlCommand cmd = new SqlCommand("command text", conn, trans)) { SqlParameter aParam = new SqlParameter("a", SqlDbType.Int); SqlParameter bParam = new SqlParameter("b", SqlDbType.Int); cmd.Parameters.Add(aParam); cmd.Parameters.Add(bParam); aParam.Value = 1; foreach(int value in bValues) { bValue = value; cmd.ExecuteNonQuery(); } } trans.Commit(); } catch { trans.Rollback(); throw; // so the exception can propogate up } } } 

不确定这是否完全适合您的情况,但很多时候,当我们需要将N大小的数据数组传递到存储过程时,我们将使用临时表技巧。 单独的东西:

 using (SqlConnection connection = new SqlConnection(connectionstring)) { connection.Open(); string sql = "CREATE TABLE #foo (myvalue [INT]) "; using (SqlCommand command = connection.CreateCommand()) { command.CommandText = sql; command.CommandType = CommandType.Text; command.ExecuteNonQuery(); // create the temp table foreach (int value in myValuesList) { command.CommandText = "INSERT INTO #foo ([myvalue]) VALUES (" + value + ") "; command.ExecuteNonQuery(); } command.CommandType = CommandType.StoredProcedure; command.CommandText = "StoredProcThatUsesFoo"; // fill in any other parameters command.ExecuteNonQuery(); } } 

如果你想在C#循环中进行多次插入 – 请查看TransactionScope。 这将允许您使用回滚function将对存储过程的多个调用滚动到事务中。 另一种选择是您可以将数组作为XML传递,并且在存储过程中,您可以将该XML分解为临时表以在proc中使用。

您应该做的最后一件事是将表值参数添加到您希望的原因列表中,以升级到下一版本的SQL Server。 随着愿望清单的增长,您花钱升级的理由变得更容易。