SQL Server:可以合并插入或更新源表吗?

Hi *_*Ten 2 t-sql sql-server

我正在使用SQL Server 2008并在两个表之间同步数据,如下所示:

    MERGE into Stock as Target
    using StockHistory as Source on Target.SrNo = Source.SrNo
    When Matched then
            # Update record to target table
    When Not Matched then
            # Insert record to target table
    When Not Matched By Source Then
            # Update Source Table - Current Record
Run Code Online (Sandbox Code Playgroud)

问题1:我想有条件地插入记录"When Not Matched Then"fire.例如,如果Source表列为refSrNo_StockCompanynull,则不应在目标中插入.

问题2:如果目标表"Stock"与源"当未按源匹配时"匹配,则它应该更新源表 - > IsSoldOut ='Yes'.

请建议我如何实现这一目标.

谢谢

Sol*_*zky 5

对于问题1:只需ANDWHEN NOT MATCHED条款中添加条件:

WHEN NOT MATCHED AND Source.[refSrNo_StockCompany] IS NOT NULL THEN
    # Insert record to target table
Run Code Online (Sandbox Code Playgroud)

对于问题2:它不能直接完成,因为只能修改TARGET表.但是,它可以在第二步中间接完成.诀窍是使用该OUTPUT子句将更新的记录捕获到临时表中(而不是用于$action区分INSERT和UPDATE,我们从deleted表中获取,根据定义,它永远不会在INSERT操作中填充).然后,在源表上执行UPDATE时,将该列表用作JOIN,以过滤掉该列表中的任何内容.临时表中的记录是匹配后不需要更新的记录.源表中不在该临时表中的任何记录表示将在该WHEN NOT MATCHED BY SOURCE条件上匹配的所有记录.当然,通过WHEN NOT MATCHED子句插入的记录都将显示为NULL临时表中的记录(因为表中没有任何deletedINSERT操作),并且可以很容易地从UPDATE中过滤掉这些记录.

-- do this before the MERGE
CREATE TABLE #UpdatedRecords (SrNo INT);

BEGIN TRY
  BEGIN TRAN;

  MERGE ...
  -- add this to the end of the MERGE query
  OUTPUT DELETED.SrNo
  INTO  #UpdatedRecords (SrNo);

  -- optionally do this after the MERGE
  DELETE upd
  FROM   #UpdatedRecords upd
  WHERE  upd.SrNo IS NULL;

  -- do this after the MERGE
  UPDATE sh
  SET    sh.IsSoldOut = 'Yes'
  FROM StockHistory sh
  WHERE NOT EXISTS (
          SELECT upd.SrNo
          FROM   #UpdatedRecords upd
          WHERE  upd.SrNo = sh.SrNo
       );

  COMMIT TRAN;

END TRY
BEGIN CATCH
  ROLLBACK TRAN;
  DECLARE @Error NVARCHAR(4000) = ERROR_MESSAGE();
  RAISERROR(@Error, 16, 1);
END CATCH;
Run Code Online (Sandbox Code Playgroud)

如果你想确保这两个说法是一个单一的操作使用合并时,他们会一直的一致性(有这样的工作),然后包裹MERGEUPDATEBEGIN TRANCOMMIT TRAN.