我正在使用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
问题1:我想有条件地插入记录"当不匹配时"火。
例如如果源表列refSrNo_StockCompany
为null,则它不应插入目标。
问题2:万一目标表"股票"与来源不匹配"当不按来源匹配时"火,它应该更新源表 - > IsSoldOut ='是'。
请建议我如何实现这一目标。
由于
答案 0 :(得分:5)
对于问题1:只需在AND
子句中添加WHEN NOT MATCHED
条件:
WHEN NOT MATCHED AND Source.[refSrNo_StockCompany] IS NOT NULL THEN
# Insert record to target table
对于问题2:不能直接完成,因为只能修改TARGET表。但是,它可以在第二步中间接完成。诀窍是使用OUTPUT
子句将更新的记录捕获到临时表中(而不是使用$action
来区分INSERT和UPDATE,我们从deleted
抓取根据定义,在INSERT操作中永远不会填充的表)。然后,在源表上执行UPDATE时,将该列表用作JOIN,以过滤掉该列表中的任何内容。临时表中的记录是匹配后不需要更新的记录。源表中WHEN NOT MATCHED BY SOURCE
条件下匹配的所有记录。当然,通过WHEN NOT MATCHED
子句插入的记录都会在临时表中显示为NULL
个记录(因为deleted
表中没有任何INSERT操作),并且这些可以很容易地从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;
如果你想确保这两个语句的一致性是单个操作,就像使用MERGE时那样(有效),然后将MERGE
和UPDATE
包装在一个{ {1}}和BEGIN TRAN
。