我需要在sqlserver中创建多个记录,每个记录在A列中具有相同的值,但在列B中具有唯一值。我在列中具有列B的值。
我正在使用VS2008,aspnet,c#3.5,sqlserver 2005.
我最好离开
选项1.
从c#代码中调用sqlserver中的存储过程,然后在tsql中执行存储过程中的所有处理工作?
这将涉及将c#数组中的所有值组合成一个逗号分隔的字符串,并将字符串作为参数传递给tsql,然后循环并将字符串拆分为单个值并为每个值插入一条记录,所有这些都在一个存储过程。
从我所看到的,如果有必要,这将涉及轻松回滚,但在tsql中非常笨拙的字符串处理。
或
选项2.
在c#中进行循环,并将数据作为sqlparams从c#one记录一次传递到存储过程以插入每条记录。
即foreach(myarray中的int键)...插入记录
我可以在睡眠中执行此代码,但如果在处理过程中发生了某些事情,我将如何能够回滚?我应该在一个单独的连接中进行循环.open和connection.close?
任何人都有其他选择吗?
答案 0 :(得分:7)
此主题在此广泛涵盖:Arrays and lists in SQL 2005
答案 1 :(得分:2)
实现此目的的最简单方法是使用选项1:将数组作为分隔字符串传递。我曾经在sql2005之前的日子里与 TSQL Split Function 一起做这件事。我会使用“|”传递数组作为分隔符。
现在,我将数组序列化为XML,然后将内容插入到表变量中,以便使用 sp_xml_preparedocument
存储过程进行处理。
我不会使用选项2,因为它会多次调用数据库。
答案 2 :(得分:1)
两个选项都有它们的优点(选项1是单个往返,选项2不使用hokey字符串处理),但我可能最终选择2.选项1的大小限制为{{ 1}}(8000除非你使用varchars
;我不知道在逗号分隔的varchar(MAX)
字符串上的性能会是多么长。)
就回滚而言,是的,只需在单个打开的连接上执行所有操作并使用varchar(MAX)
对象。
例如......
SqlTransaction
答案 3 :(得分:1)
不确定这是否完全适合您的情况,但很多时候,当我们需要将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();
}
}
答案 4 :(得分:1)
如果您想在C#循环中进行多次插入 - 请查看TransactionScope。这将允许您使用回滚功能将对存储过程的多个调用滚动到事务中。另一种选择是您可以将数组作为XML传递,并且在存储过程中,您可以将该XML分解为临时表,以便在您的过程中使用。
您应该做的最后一件事是将Table Valued Parameters添加到您希望的原因列表中,以升级到下一版本的SQL Server。随着愿望清单的增长,你花钱升级的理由变得容易一些。