使用存储过程将批量数据插入主/明细表的最佳方法?

Posted

技术标签:

【中文标题】使用存储过程将批量数据插入主/明细表的最佳方法?【英文标题】:the best method for insert bulk data into master/detail tables with stored-procedure? 【发布时间】:2017-04-24 07:39:18 【问题描述】:

假设,我有一个名为 Order 的主表和一个名为 OrderDetail 的详细表,其中 OrderId 是身份密钥并在 OrderDetail 中用作外部钥匙。现在我想将带有存储过程的 批量数据 插入到 Order 中,然后将相关详细信息插入到 OrderDetail 表中。 谁能告诉我最好的方法?如何从我使用的 master 和 detail 表中获取标识值?

【问题讨论】:

在这里查看答案:(***.com/questions/10999396/…) @rigerta 注意!我同时批量插入主表。 您是否询问如何将多个订单插入到具有identityOrderIdOrder 表中,然后将新分配的OrderId 值与OrderDetail 行相关联?表模式和示例数据会使其更加清晰。请阅读this,了解一些改进问题的技巧。 【参考方案1】:

您可以按如下方式使用OUTPUT 子句:

BULK INSERTOrders 表中,并将BULK INSERT 中的所有Id's 存储到表变量中。 之后,将详细信息插入OrderDetail,从您已经存储它们的表变量中获取OrderId

您可以查看此代码here 的工作演示。

     DECLARE @outputtbl TABLE ( id INT );
     --here you will store the bulk inserted id's 
     --here you will do the bulk insert (note that i used a union all of several      
         selects as a "source" for your bulk insert)
     INSERT INTO Orders
     OUTPUT inserted.id
            INTO @outputtbl ( id )
     SELECT *
     FROM   ( SELECT    1 AS id ,
                        GETDATE() AS dt
              UNION ALL
              SELECT    2 AS id ,
                        GETDATE() AS dt
              UNION ALL
              SELECT    3 AS id ,
                        GETDATE() AS dt
              UNION ALL
              SELECT    4 AS id ,
                        GETDATE() AS dt
            ) t;

     --inserting into OrderDetail, OrderId's from the table variable and other fields as per your logic. (`item name` here it's just an example)
     INSERT INTO OrderDetail
            ( orderid, itemname )
     SELECT id ,
            'itemx'
     FROM   @outputtbl;

我创建了两个简单的表OrdersOrderDetail 来模拟问题。

【讨论】:

旁白:您可能想阅读this 的答案,了解在查询中重复调用GetDate() 谢谢! :) 在提供给当前问题的答案中, getdate() 值绝对不重要,因为它可能是任何恒定值,甚至根本不存在。它用于插入“示例”列。非常好的链接!【参考方案2】:

这只是一个示例表,我将在我的表中插入大量示例数据

DECLARE @Counter INT 
SET @Counter = 1
    WHILE @Counter < 50000
        BEGIN 
         INSERT [SampleTableName] VALUES(Id)
            SELECT 
                NEWID() -- i have a column sample_id so i am entrying random 
                newid() into that
                ABS (CHECKSUM(NEWID())) % 60 + 1,
                DATEADD ( DAY, ABS(CHECKSUM(NEWID()) % 3650), '2007-04-01')
                -- i have a sample date field as well and i am entrying 10 
                   years of date in that
            SET @Counter += 1
        END

【讨论】:

以上是关于使用存储过程将批量数据插入主/明细表的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

mysql 存储过程 若主键冲突则更新,不冲突则插入数据

等待批量插入存储过程完成

sQL数据库表的主键列设为标识,增量为1,下次插入数据时能不插入主键列吗

C# Oracle 转换为批量上传

mysql存储过程批量向表插入数据

postgres 使用存储过程批量插入数据