2016-05-31 30 views
2

我尝试执行此交易:合并在SQLSERVER - 不正确的语法

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

一个可以理解的错误,因为在TechNet页面链接到您的用途'Target'和'Source'作为例如表名,从而与'TARGET'和'SOURCE'关键字将它们混合。 – Heinzi

回答

6

根据MSDNWHEN NOT MATCHED为分支的简化语法是

[ WHEN NOT MATCHED [ BY TARGET ] [...] 
     THEN <merge_not_matched> ] 
    [ WHEN NOT MATCHED BY SOURCE [...] 
     THEN <merge_matched> ] [ ...n ] 

溶液与WHEN NOT MATCHED BY TARGETWHEN NOT MATCHED BY BWHEN NOT MATCHED BY SOURCE取代WHEN NOT MATCHED BY A

TARGETSOURCE是不是占位符的T-SQL关键字。

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点TARGETSOURCE是关键字,当您确定匹配/不匹配的语句时需要。

0

看起来你正在试图用char或varchar类型的数据更新日期或日期时间类型列,这些数据不可转换为日期或日期时间类型。 'a'不能转换为日期或日期时间。查看下面的第一个和第二个合并。如果您没有提及何时匹配或何时不匹配源或目标,默认情况下它会考虑Target。

--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;