【问题标题】:How to insert bulk data without changing order of item into table using merge statement如何使用合并语句在不更改项目顺序的情况下将批量数据插入表中
【发布时间】:2018-12-24 09:22:51
【问题描述】:

我编写了一个存储过程,可以使用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;   

【问题讨论】:

  • 关系表根据定义是一个无序的数据集 - 你不能除了/保留任何“排序”插入后。 ONLY 获取排序的方法是,当您从该表运行 SELECT明确指定 ORDER BY 子句时。其他任何事情都只是巧合的“排序”-不可靠,不可重现-只是巧合

标签: sql sql-server sql-merge


【解决方案1】:

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

尝试在临时表中添加标识列?

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

标识列可能会捕获 XML 元素的顺序。

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

【讨论】:

  • 。 .它们以 indeterminate 顺序返回,而不是 random 顺序。后者定义得很好,SQL 通常会随机化结果集。
  • @GordonLinoff:随机的dictionary definition 是“没有明确的目标、方向、规则或方法”,这似乎很合适。同意不确定是一个更好的术语,我会更新答案
【解决方案2】:

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

它可以像添加IDENTITY 列一样简单,每添加一行就会递增,或者可能是具有DATETIME 数据类型和GETDATE() 默认值的列,这样您不仅知道顺序添加了行,但正是发生这种情况的时间。

【讨论】:

    猜你喜欢
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多