繁体   English   中英

如何在MERGE语句中更新源表?

[英]How to update the source table in the MERGE statement?

我的本地数据库上有一个表tbBroker ,而链接服务器对象“ DIS”上有一个表Agency

我正在尝试将数据从本地的tbBroker迁移到DIS的Agency

另请注意

tbBroker's Columns  =  Agency's Columns
BrokerCode          =  AgencyNumber
BusinesssName       =  AgencyName
City                =  City
tbSystemUser.EmailAddress = EmailAddress

另外, tbBroker还有两个附加列DISImportFlag bitDISCreatTS datetime 每当将数据从tbBroker迁移到Agency表时(插入期间),这两个字段应更新为1GETDATE() ,以确定已迁移的行。

我写了以下查询

       USE [DISTemp];
       MERGE INTO
       [dbo].[Agency] AS [TARGET]
       USING
       [aginbr].[dbo].[tbBroker] AS [SOURCE]
       ON
       [TARGET].[AgencyNumber] COLLATE Latin1_General_CI_AI = [SOURCE].[BrokerCode]
       WHEN NOT MATCHED BY TARGET THEN
       INSERT (    
       [AgencyName]
       , [Address1]
       , [Address2]
       , [PostalCode]
       , [City]
       , [Phone]
       , [EmailAddress]  
       )
       VALUES (
       [SOURCE].[BUSINESSNAME]
       , [SOURCE].[ADDRESS]
       , [SOURCE].[AddressLine2]
       , [SOURCE].[Zip]
       , [SOURCE].[City]
       , [SOURCE].[Phone]
       , [SOURCE].[Email]
       )
       UPDATE SET [SOURCE].[DISImportFlag] = 1,[SOURCE].[DISCreatTS] = GETDATE()
       WHEN MATCHED THEN
       UPDATE SET
       [TARGET].[AgencyName] = [SOURCE].[BUSINESSNAME]
        , [TARGET].[Address1] = [SOURCE].[ADDRESS]
        , [TARGET].[Address2] = [SOURCE].[AddressLine2]
        , [TARGET].[PostalCode] = [SOURCE].[Zip]
        , [TARGET].[City] = [SOURCE].[City]
        , [TARGET].[Phone] = [SOURCE].[Phone]
        , [TARGET].[EmailAddress] = [SOURCE].[Email];

当我们执行上面的查询时,它会引发错误消息

MERGE语句必须以分号(;)终止

添加以下行后

   UPDATE SET [SOURCE].[DISImportFlag] = 1,[SOURCE].[DISCreatTS] = GETDATE()

根据评论编辑

源表tbBroker具有主键列BrokerID

我想在源表中更新那些插入到目标表中的行,即在MERGE之前在目标表中不存在的那些行。

我认为您无法使用单个MERGE语句更改除TARGET其他表。 但是,您可以使用OUTPUT子句在帮助器/临时表中捕获MERGE的结果,然后基于该表更新SOURCE

您说过,您只想更新那些插入到Target中的行,即MERGE之前Target中不存在的那些行。

插入到临时表中的行的输出IDs ,然后使用它来更新Source表。

CREATE TABLE #Temp(
    BrokerID int NOT NULL,
CONSTRAINT [PK_Broker] PRIMARY KEY CLUSTERED
(
    BrokerID ASC
));

INSERT INTO #Temp (BrokerID)
SELECT TableChanges.BrokerID
FROM
    (
        MERGE INTO [dbo].[Agency] AS [TARGET]
        USING [aginbr].[dbo].[tbBroker] AS [SOURCE]
        ON [TARGET].[AgencyNumber] COLLATE Latin1_General_CI_AI = [SOURCE].[BrokerCode]
        WHEN NOT MATCHED BY TARGET THEN
        INSERT
        (
            [AgencyName]
            , [Address1]
            , [Address2]
            , [PostalCode]
            , [City]
            , [Phone]
            , [EmailAddress]
        )
        VALUES
        (
            [SOURCE].[BUSINESSNAME]
            , [SOURCE].[ADDRESS]
            , [SOURCE].[AddressLine2]
            , [SOURCE].[Zip]
            , [SOURCE].[City]
            , [SOURCE].[Phone]
            , [SOURCE].[Email]
        )
        WHEN MATCHED THEN
        UPDATE SET
            [TARGET].[AgencyName] = [SOURCE].[BUSINESSNAME]
            , [TARGET].[Address1] = [SOURCE].[ADDRESS]
            , [TARGET].[Address2] = [SOURCE].[AddressLine2]
            , [TARGET].[PostalCode] = [SOURCE].[Zip]
            , [TARGET].[City] = [SOURCE].[City]
            , [TARGET].[Phone] = [SOURCE].[Phone]
            , [TARGET].[EmailAddress] = [SOURCE].[Email]
        OUTPUT $action, [SOURCE].BrokerID
    ) AS TableChanges (MergeAction, BrokerID)
WHERE TableChanges.MergeAction = 'INSERT'
;

UPDATE [aginbr].[dbo].[tbBroker]
SET
    [DISImportFlag] = 1
    ,[DISCreatTS] = GETDATE()
WHERE
    BrokerID IN 
    (
        SELECT T.BrokerID FROM #Temp AS T
    )
;

DROP TABLE #Temp;

显然,将整个内容包装在一个事务中并TRY ... CATCH并添加适当的错误处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM