我尝试执行此交易:
GO
BEGIN TRAN;
MERGE A AS t
USING B AS tmp
ON (t.domain = tmp.domain and t.link=tmp.link)
WHEN NOT MATCHED BY A
THEN INSERT(ipVal, domain, dateStart, dateUpdate, dateFinish, link) VALUES(tmp.ipVal, tmp.domain, tmp.dateStart, tmp.dateUpdate, tmp.dateFinish, tmp.link)
WHEN MATCHED
THEN UPDATE SET t.dateupdate = tmp.dateupdate
WHEN NOT MATCHED BY B
THEN UPDATE SET t.datefinish="a"
ROLLBACK TRAN;
GO
我从here获取此代码,但是当我尝试执行此操作时出现错误:
Incorrect syntax near 'A'
可能是什么问题?
答案 0 :(得分:6)
根据MSDN,WHEN NOT MATCHED
分支的简化语法是
[ WHEN NOT MATCHED [ BY TARGET ] [...]
THEN <merge_not_matched> ]
[ WHEN NOT MATCHED BY SOURCE [...]
THEN <merge_matched> ] [ ...n ]
解决方案是将WHEN NOT MATCHED BY A
替换为WHEN NOT MATCHED BY TARGET
,将WHEN NOT MATCHED BY B
替换为WHEN NOT MATCHED BY SOURCE
。
TARGET
和SOURCE
是T-SQL关键字而不是占位符。
答案 1 :(得分:0)
我刚刚开始使用MERGE我使用这种语法来理解它:
MERGE A AS target
USING B AS source
ON (target.domain = source.domain and target.link=source.link)
WHEN NOT MATCHED BY TARGET
THEN INSERT(ipVal, domain, dateStart, dateUpdate, dateFinish, link)
VALUES(source.ipVal, source.domain, source.dateStart, source.dateUpdate, source.dateFinish, source.link)
WHEN MATCHED
THEN UPDATE SET target.dateupdate = source.dateupdate
WHEN NOT MATCHED BY SOURCE
THEN UPDATE SET target.datefinish="a"
我知道这是一种不好的做法,但一旦开始 - 有很多帮助。
由于@BogdanSahlean积分TARGET
和SOURCE
是关键字,因此在您确定匹配/不匹配的陈述时需要。
答案 2 :(得分:0)
看起来您正在尝试使用不能转换为日期或日期时间类型的char或varchar类型数据更新日期或日期时间类型列。 &#39;一个&#39;不可转换为日期或日期时间。看看我在下面的第一个和第二个合并。如果你没有提到匹配时或者没有匹配源或目标,默认它会考虑目标。
--DROP TABLE #A;
--DROP TABLE #B;
CREATE TABLE #A
(
ipval VARCHAR(50)
, domain CHAR(5)
, dateStart DATE
, dateUpdate DATE
, dateFinish DATE
, link VARCHAR(50)
);
CREATE TABLE #B
(
ipval VARCHAR(50)
, domain CHAR(5)
, dateStart DATE
, dateUpdate DATE
, dateFinish DATE
, link VARCHAR(50)
);
INSERT INTO #B
( ipval, domain, dateStart, dateUpdate, dateFinish, link )
VALUES ( '42.130.239.56' -- ipval - varchar(50)
, '.com' -- domain - char(5)
, GETDATE() -- dateStart - date
, DATEADD(DAY, 1, GETDATE()) -- dateUpdate - date
, DATEADD(DAY, 5, GETDATE()) -- dateFinish - date
, 'www.stackoverflow' -- link - varchar(50)
),
( '78.188.136.74' -- ipval - varchar(50)
, '.com' -- domain - char(5)
, GETDATE() -- dateStart - date
, DATEADD(DAY, 2, GETDATE()) -- dateUpdate - date
, DATEADD(DAY, 10, GETDATE()) -- dateFinish - date
, 'www.msdn' -- link - varchar(50)
);
INSERT INTO #A
( ipval, domain, dateStart, dateUpdate, dateFinish, link )
VALUES ( '30.48.111.20' -- ipval - varchar(50)
, '.com' -- domain - char(5)
, GETDATE() -- dateStart - date
, DATEADD(DAY, 5, GETDATE()) -- dateUpdate - date
, DATEADD(DAY, 10, GETDATE()) -- dateFinish - date
, 'www.msdn' -- link - varchar(50)
),
( '30.48.111.20' -- ipval - varchar(50)
, '.com' -- domain - char(5)
, GETDATE() -- dateStart - date
, DATEADD(DAY, 5, GETDATE()) -- dateUpdate - date
, DATEADD(DAY, 10, GETDATE()) -- dateFinish - date
, 'www.gmail' -- link - varchar(50)
);
--First Merge
BEGIN TRAN;
MERGE #A AS T
USING #B AS tmp
ON T.domain = tmp.domain
AND T.link = tmp.link
WHEN NOT MATCHED BY TARGET THEN
INSERT ( ipval
, domain
, dateStart
, dateUpdate
, dateFinish
, link
)
VALUES ( tmp.ipval
, tmp.domain
, tmp.dateStart
, tmp.dateUpdate
, tmp.dateFinish
, tmp.link
)
WHEN MATCHED THEN
UPDATE SET T.dateUpdate = tmp.dateUpdate
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET T.dateFinish =''a'';
COMMIT TRAN;
GO
SELECT *
FROM #A;
SELECT *
FROM #B;
--Second Merge
BEGIN TRAN;
MERGE #A AS T
USING #B AS tmp
ON T.domain = tmp.domain
AND T.link = tmp.link
WHEN NOT MATCHED BY TARGET THEN
INSERT ( ipval
, domain
, dateStart
, dateUpdate
, dateFinish
, link
)
VALUES ( tmp.ipval
, tmp.domain
, tmp.dateStart
, tmp.dateUpdate
, tmp.dateFinish
, tmp.link
)
WHEN MATCHED THEN
UPDATE SET T.dateUpdate = tmp.dateUpdate
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET T.dateFinish = CAST(GETDATE() AS DATE);
COMMIT TRAN;
GO
SELECT *
FROM #A;
SELECT *
FROM #B;