如何批量调用存储过程?我想做一些像批量复制的事情。
存储过程所做的全部是8选择唯一约束和8个插入。没有回头的价值。
答案 0 :(得分:7)
你做不到。
批量复制是将数据转储到表中,您无法调用sprocs或其他任何内容,而只是将其转储到现有表中。
然而,您可以做的是使用批量复制将数据转储到具有正确结构的临时表中,然后调用您的sproc将该数据移动到真实表中,可能通过修改现有数据而不是插入它或者诸如此类的。
答案 1 :(得分:4)
如果您使用的是SQL Server 2008,则Table-Valued Parameters是可行的选择。
首先,在SQL Server端创建一个包含所有预期列和数据类型的user-defined table type:
create type dbo.MyTableType as table
(
foo int,
bar varchar(100)
);
然后使用上面的内容作为存储过程的表类型参数:
create procedure uspInsertMyBulkData
(
@myTable dbo.MyTableType readonly
)
as
/* now in here you can use the multi-row data from the passed-in table
parameter, @myTable, to do your selects and inserts*/
然后,在C#/ .NET客户端,通过ADO.NET调用此存储过程并传入DataTable
,一个继承自DbDataReader
的对象(例如DataTableReader
})或类型为IEnumerable<SqlDataRecord>
的对象:
// create my source DataTable
object [] row1 = {1, "a"};
object [] row2 = {2, "b"};
var myDataTable = new DataTable();
myDataTable.Columns.Add(new DataColumn("foo"));
myDataTable.Columns.Add(new DataColumn("bar"));
myDataTable.LoadDataRow(row1, true);
myDataTable.LoadDataRow(row2, true);
// bulk send data to database
var conn = new SqlConnection(connectionString);
var cmd = new SqlCommand("uspInsertMyBulkData", conn)
{
CommandType = CommandType.StoredProcedure
};
SqlParameter param = cmd.Parameters.AddWithValue("@myTable", myDataTable);
param.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery();
答案 2 :(得分:1)
如果要将数据批量加载到表(插入)中,SqlBulkCopy类就可以了。
或者,您可以使用SqlDataAdapter。将InsertCommand设置为将执行插入的存储过程,并将数据表字段映射到sproc参数。如果您已在数据表中更新了记录,则还可以指定将为每个更新的行触发的UpdateCommand。然后在SqlDataAdapter上调用Update方法,将数据表传递给它。您可以设置UpdateBatchSize属性以定义每次往返中要发送到数据库的记录数。
答案 3 :(得分:0)
SqlServer存储过程可以接受xml,因此您可以将批量数据准备为xml文件,并将其传递给专用存储过程,然后为每行调用原始存储过程。您需要OPENXML功能。
我对推荐SqlServer的xml功能犹豫不决,但这可能是适当的情况。
答案 4 :(得分:0)
我不是说我推荐它,但你可以在你正在批量复制的表上插入一个插入触发器插入到那些8个单独的表而不是原始的表中。你可能需要一个足够大的tempdb来存储所有数据......
CREATE TRIGGER TRG_REPLACETRIGGER
ON BULK_TABLE
INSTEAD OF INSERT
AS BEGIN
INSERT TABLE1 (ID, VALUE) SELECT ID, VALUE1 FROM INSERTED
INSERT TABLE2 (ID, VALUE) SELECT ID, VALUE2 FROM INSERTED
-- ... TABLE3-7
INSERT TABLE8 (ID, VALUE) SELECT ID, VALUE8 FROM INSERTED
END