[英]How to update the source table in the MERGE statement?
I have a table tbBroker
on my local database and a table Agency
on linked server object "DIS". 我的本地数据库上有一个表
tbBroker
,而链接服务器对象“ DIS”上有一个表Agency
。
I am trying to migrate data from local's tbBroker
to DIS's Agency
table 我正在尝试将数据从本地的
tbBroker
迁移到DIS的Agency
表
Also note that 另请注意
tbBroker's Columns = Agency's Columns
BrokerCode = AgencyNumber
BusinesssName = AgencyName
City = City
tbSystemUser.EmailAddress = EmailAddress
Also, tbBroker
has two additional columns DISImportFlag bit
and DISCreatTS datetime
. 另外,
tbBroker
还有两个附加列DISImportFlag bit
和DISCreatTS datetime
。 These two fields should be updated to 1
and GETDATE()
whenever data is migrated (during insertion) from tbBroker
to Agency
table in order to determine which rows have been migrated. 每当将数据从
tbBroker
迁移到Agency
表时(插入期间),这两个字段应更新为1
和GETDATE()
,以确定已迁移的行。
I have written the following query 我写了以下查询
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];
When we execute the above query it throws error message 当我们执行上面的查询时,它会引发错误消息
A MERGE statement must be terminated by a semi-colon (;)
MERGE语句必须以分号(;)终止
after adding the following line 添加以下行后
UPDATE SET [SOURCE].[DISImportFlag] = 1,[SOURCE].[DISCreatTS] = GETDATE()
Edit from comments 根据评论编辑
The source table tbBroker
has a primary key column BrokerID
. 源表
tbBroker
具有主键列BrokerID
。
I want to update in the source table those rows that were inserted into the target table, ie those rows that didn't exist in the target table before MERGE
. 我想在源表中更新那些插入到目标表中的行,即在
MERGE
之前在目标表中不存在的那些行。
I don't think you can change some table other than TARGET
using a single MERGE
statement. 我认为您无法使用单个
MERGE
语句更改除TARGET
其他表。 But, you can use OUTPUT
clause to capture the result of the MERGE
in a helper/temporary table and then update your SOURCE
based on that. 但是,您可以使用
OUTPUT
子句在帮助器/临时表中捕获MERGE
的结果,然后基于该表更新SOURCE
。
You said that you want to update only those rows that were inserted into the Target, ie those that didn't exist in the Target before MERGE
. 您说过,您只想更新那些插入到Target中的行,即
MERGE
之前Target中不存在的那些行。
Output IDs
of inserted rows into the temporary table and then use it to update the Source
table. 插入到临时表中的行的输出
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;
Obviously, wrap this whole thing in a transaction and TRY ... CATCH
and add appropriate error handling. 显然,将整个内容包装在一个事务中并
TRY ... CATCH
并添加适当的错误处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.