SQL Bulk insert with parent/child relationships, is order preserved?

后端 未结 2 1955
后悔当初
后悔当初 2021-01-03 05:41

Similar to these other questions noted below, I have two tables with the structure:

create table parent (
   recno int identity(1,1) primary key not null,
           


        
相关标签:
2条回答
  • 2021-01-03 06:12

    Create two staging tables with the same structure as your target tables but don't use identity on recno column.

    create table parentTmp (
       recno int,
       groupCode int,
       parentdata varchar(80)
    );
    
    create table childTmp (
       parentrecno int not null,
       childdata varchar(80)
    )
    

    Bulk load your data to the staging tables, keeping the recno/parentrecno values as is.

    Then you can use merge and output to move the data from the staging tables.

    -- 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;
    

    This will only work in SQL Server 2008 (and later I presume).

    0 讨论(0)
  • 2021-01-03 06:16

    This is not an absolut bulk insert, but instead it inserts all child data at the same time with the parent data, making only 1 round trip to the DB.

    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;
    

    You can build scripts like this in your C# code, and then perform one request per parent.

    Be aware that this may not be a good approach if the amount of child data is known to be large. Don't know the details, but I'm sure that the size of the sql script can't grow indefinitely.

    0 讨论(0)
提交回复
热议问题