Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.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
C# 具有父/子关系的SQL批量插入是否保留顺序?_C#_Sql Server 2008_Sqlbulkcopy - Fatal编程技术网

C# 具有父/子关系的SQL批量插入是否保留顺序?

C# 具有父/子关系的SQL批量插入是否保留顺序?,c#,sql-server-2008,sqlbulkcopy,C#,Sql Server 2008,Sqlbulkcopy,与下面提到的其他问题类似,我有两个结构表: create table parent ( recno int identity(1,1) primary key not null, groupCode int, parentdata varchar(80) ); create table child ( parentrecno int not null, childdata varchar(80) ) 我需要在这些表中快速插入几十万条记录,而这些表中包含了数百万条

与下面提到的其他问题类似,我有两个结构表:

create table parent (
   recno int identity(1,1) primary key not null,
   groupCode int,
   parentdata varchar(80)
);

create table child (
   parentrecno int not null,
   childdata varchar(80)
)
我需要在这些表中快速插入几十万条记录,而这些表中包含了数百万条与此插入无关的其他记录,而且从来都不是安静的。由于父/子属性,它似乎不是SqlBulkCopy的好候选

在C语言中,使用带有INSERT的SqlCommand时,每秒插入大约400-500条记录,这有点太慢了。伪代码:

 foreach(Record r in parentRecords)
 {
      Insert Fields from r into SqlCommand Parameters but not "recno"
      Call ExecuteScalar to insert and fetch the inserted identity value (recno)
      foreach(ChildRecord cr in parentRecords.Children)
      {
          Insert Fields from cr into SqlCommand Parameters
          Insert the identity value (recno) from above into Parameters 
                                                       (as parentrecno)
          Call ExecuteNonQuery to insert the record
      }   
 }
读了那些其他的帖子后,我产生了一种想法。附加到父记录的组码对于我插入的父记录集是唯一的。它是否能够:

使用SqlBulkCopy大容量插入父记录,让插入像往常一样自动生成recno标识字段。 仅对插入的记录执行选择:

select recno from parent where groupCode = @thisgroup order by recno;
使用检索到的值为内存中的子记录填写parentrecno字段

使用SqlBulkCopy批量插入子记录 这取决于父记录进入SQL表的顺序与它们在原始DataTable中的顺序相同,以及标识值的分配顺序相同。这是我可以信赖的吗

相关问题:


创建两个与目标表具有相同结构的暂存表,但不在recno列上使用标识

create table parentTmp (
   recno int,
   groupCode int,
   parentdata varchar(80)
);

create table childTmp (
   parentrecno int not null,
   childdata varchar(80)
)
将数据大容量加载到临时表,保持recno/parentrecno值不变

然后可以使用和从临时表中移动数据

-- Table variable to hold mapping between 
-- SourceRecno and TargetRecno
declare @recno table(SourceRecno int, TargetRecno int);

-- Merge data from parentTmp to parent
-- Output old and new recno to @recno
merge parent T
using parentTmp S
on 0=1
when not matched then
  insert (groupCode, parentdata)
    values (S.groupCode, S.parentData)
output S.recno, inserted.recno into @recno;

-- Copy data from childTmp to child
-- Use @recno to get the new recno
insert into child(parentrecno, childdata)
select R.TargetRecno, C.childdata
from childTmp as C
  inner join @recno as R
    on C.parentrecno = R.SourceRecno;

我想这只适用于SQLServer2008及更高版本

这不是absolut批量插入,而是与父数据同时插入所有子数据,只进行一次到数据库的往返

insert into parent(groupcode, parentdata) values(1, 'parent data');
insert into child(parentrecno, childdata) select parentrecno, childdata from (
    select SCOPE_IDENTITY() as parentrecno, 'child data 1' as childdata
    union
    select SCOPE_IDENTITY() as parentrecno, 'child data 2' as childdata
    union
    select SCOPE_IDENTITY() as parentrecno, 'child data 3' as childdata
) childrendata;
您可以在C代码中构建这样的脚本,然后对每个父级执行一个请求


请注意,如果已知子数据量很大,则这可能不是一个好方法。我不知道细节,但我确信sql脚本的大小不能无限增长。

这是一段使用我不熟悉的语句的有趣代码。不过听起来似乎有道理给我一点时间来研究一下。@clintp你可以看看这个问题以了解更多信息。是否有一种方法可以在SQL2005中执行相同的语句。我尝试使用adaption for 2005查找合并,但无法访问源表的ID或目标表中插入的ID。除了您的语句之外,您还应该考虑在内部连接上使用opTyrReCopyF编译。