Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL大容量存储过程调用C#_C#_.net_Sql_Bulkinsert - Fatal编程技术网

SQL大容量存储过程调用C#

SQL大容量存储过程调用C#,c#,.net,sql,bulkinsert,C#,.net,Sql,Bulkinsert,如何批量调用存储过程?我想做一些像批量复制的事情 存储过程只需选择8个唯一约束和8个插入。没有返回值。您不能这样做 大容量复制是将数据快速转储到表中,您不能调用存储过程或其他任何操作,而只能将其转储到现有表中 但是,您可以做的是使用大容量复制将数据转储到具有正确结构的临时表中,然后调用存储过程将数据移动到实际表中,可能是通过修改现有数据而不是插入数据,或者诸如此类。如果要将数据大容量加载到表中(插入),上课是最好的选择 或者,您可以使用。将设置为将执行插入的存储过程,并将datatable字段映

如何批量调用存储过程?我想做一些像批量复制的事情

存储过程只需选择8个唯一约束和8个插入。没有返回值。

您不能这样做

大容量复制是将数据快速转储到表中,您不能调用存储过程或其他任何操作,而只能将其转储到现有表中


但是,您可以做的是使用大容量复制将数据转储到具有正确结构的临时表中,然后调用存储过程将数据移动到实际表中,可能是通过修改现有数据而不是插入数据,或者诸如此类。

如果要将数据大容量加载到表中(插入),上课是最好的选择


或者,您可以使用。将设置为将执行插入的存储过程,并将datatable字段映射到存储过程参数。如果datatable中有更新的记录,还可以指定为每个更新的行激发的。然后调用SqlDataAdapter上的方法,并将其传递给datatable。您可以设置属性以定义每次往返中要发送到db的记录数。

SqlServer存储过程可以接受xml,因此您可以将批量数据准备为xml文件,并将其传递给专用存储过程,该存储过程随后将为每行调用原始存储过程。你需要这个功能


我不太愿意推荐SqlServer的xml功能,但在这种情况下,它们可能是合适的。

如果您使用的是SQLServer2008,那么这是一个可行的选择

首先,在SQL Server端创建一个包含所有预期列和数据类型的

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
类型的对象:


我不是说我推荐它,但是你可以在你批量复制到的表上放一个insert触发器,插入到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

这是一个优雅的解决方案吗?如果我将存储过程的参数更改为数组,然后一次向其中发射1000个对象,然后让存储过程遍历数组,会怎么样?为什么不试试看呢?如果这两种解决方案都有效,我会称之为优雅,因为它们在理论上都没有问题。对我来说,就我所知,执行大容量复制+存储过程比使用数组执行多个存储过程更容易,因为我还没有这样做,但您应该尝试一下。您是必须维护代码的人,因此只有您知道什么对您最有利。我也会看性能特征,但我真的不知道其中一个是否会比另一个好得多。好奇:哪一个更适合你?(将所有内容转储到临时表中,而不是“分块”更新并使用存储的proc accept数组?)是创建表值参数作为存储过程输入变量的一个好例子……我尝试了这种方法。当我将1400万个单列
int
值插入该
DataTable
时,它会消耗2GB的RAM,而且非常长。然而,理论上,14M
int
s仅为14M*4=56m。DataTable产生了太多的开销。
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