如何使用合并语句在不更改项目顺序的情况下插入批量数据

时间:2018-12-24 09:22:52

标签: sql sql-server sql-merge

我编写了一个存储过程,可以使用merge语句将批量数据插入表中。

问题在于,当我按此顺序插入itemid 1024,1000,1012,1025时,SQL Server会自动更改itemid 1000,1012,1024,1025的顺序。

我想插入我实际传递的数据。

这是示例代码。这会将XML字符串解析为表对象:

DECLARE @tblPurchase TABLE
            (
              Purchase_Detail_ID INT ,
              Purchase_ID INT ,
              Head_ID INT ,
              Item_ID INT 
            );


INSERT INTO @tblPurchase (Purchase_Detail_ID, Purchase_ID, Head_ID, Item_ID)
    SELECT  
        Tbl.Col.value('Purchase_Detail_ID[1]', 'INT') AS Purchase_Detail_ID,
        Tbl.Col.value('Purchase_ID[1]', 'INT') AS Purchase_ID,
        Tbl.Col.value('Head_ID[1]', 'INT') AS Head_ID,
        Tbl.Col.value('Item_ID[1]', 'INT') AS Item_ID 
    FROM    
        @PurchaseDetailsXML.nodes('/documentelement/TRN_Purchase_Details') Tbl(Col) 

这会将批量数据插入TRN_Purchase_Details表中:

MERGE TRN_Purchase_Details MTD
USING (SELECT    
           Purchase_Detail_ID,
           Id AS Purchase_ID,
           Head_ID, Item_ID 
       FROM      
           @tblPurchase
       LEFT JOIN 
           @ChangeResult ON 1 = 1) AS TMTD ON MTD.Purchase_Detail_ID = TMTD.Purchase_Detail_ID
                                           AND MTD.Purchase_ID = TMTD.Purchase_ID

WHEN MATCHED THEN
    UPDATE SET MTD.Head_ID = TMTD.Head_ID,
               MTD.Item_ID = TMTD.Item_ID 

WHEN NOT MATCHED BY TARGET THEN
    INSERT (Purchase_ID, Head_ID, Item_ID)
    VALUES (Purchase_ID, Head_ID, Item_ID)

WHEN NOT MATCHED BY SOURCE AND       
     MTD.Purchase_ID = (SELECT TOP 1 Id
                        FROM @ChangeResult
                        WHERE Id > 0) THEN
    DELETE;   

2 个答案:

答案 0 :(得分:3)

SQL表中的行没有任何顺序。除非您指定order by,否则它们将以不确定的顺序返回。

尝试在您的临时表中添加一个身份列?

DECLARE @tblPurchase TABLE
        (
          ID int identity,
          Purchase_Detail_ID INT ,

identity列可能捕获XML元素的顺序。

如果这不起作用,则可以calculate the position of the elements in the XML并将该位置存储在临时表中。

答案 1 :(得分:0)

如其他地方所述,表中的数据存储为无序集合。如果您需要在插入数据后能够返回表并确定其插入顺序,则必须在表模式中添加一列以记录该信息。

这可能很简单,例如添加一个IDENTITY列,该列将在每次添加行时增加,或者添加一列具有DATETIME数据类型和一个GETDATE()默认值的列,因此您不仅知道添加了订单行,还知道添加的确切时间。