2016-08-30 80 views
0

目前我有一个使用Cursor的大存储过程,里面有两个合并语句。简而言之,我想从一张大桌子填充2张桌子。子查询返回了多个值。使用merge和tsql

现在,我对sql很陌生,并且阅读了一些内容以扩展我的知识。在这项研究中,我遇到了很多讨论游标和他们可能给出的性能问题的主题。

当前的SP(使用光标)工作正常,但我坚持尝试使用我的代码而不使用游标(其他POV),它会让我感到困惑。

所以现在我被这个小小的垃圾代码卡住了。我认为不可能以我想要的方式去做,但是我可以尝试。

错误:子查询返回多个值。这当子查询跟随不允许=,=,<,...

代码:

MERGE CONTACTS as target 
USING STAGING_CONTACTS as source 
ON (target.ID = source.ID) 
WHEN MATCHED THEN 
    UPDATE SET 
     MAIL = (SELECT MAIL FROM STAGING_CONTACTS), 
     NAME = (SELECT NAME FROM STAGING_CONTACTS), 
     BRAND = (SELECT BRAND FROM STAGING_CONTACTS), 
     ID = (SELECT ID FROM STAGING_CONTACTS) 
WHEN NOT MATCHED THEN 
    INSERT (MAIL, NAME, BRAND, CORESOLEIL_ID) 
    VALUES ((SELECT MAIL FROM STAGING_CONTACTS), 
     (SELECT NAME FROM STAGING_CONTACTS), 
     (SELECT BRAND FROM STAGING_CONTACTS), 
     (SELECT ID FROM STAGING_CONTACTS)); 

这是两个合并报表我有一个,这是一个更小。

欢迎任何反馈!

感谢提前:)

+1

合并是一个有缺陷的实现,是非常困难的调试后,当有潜在的数据问题。我永远不会允许任何人在我们的生产数据库中使用它。更好地使用更新语句后跟一个插入(顺序很重要) – HLGEM

+1

https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ –

回答

2

删除选择statements..Below声明照顾其表的使用该表进行更新。

MERGE CONTACTS as target 
USING STAGING_CONTACTS as source 

所以你的查询可以像下面

UPDATE SET 
     MAIL = MAIL , 
     and so on... 
WHEN NOT MATCHED THEN 
    INSERT (MAIL, NAME, BRAND, CORESOLEIL_ID) 
    VALUES (mail,name,brand,id) 

你也可以像别名一样

MERGE CONTACTS as target 
USING STAGING_CONTACTS as source 
ON (target.ID = source.ID) 
WHEN MATCHED THEN 
    UPDATE SET 
     target.MAIL = source.MAIL, 
     and so on.. 
WHEN NOT MATCHED THEN 
    INSERT (MAIL, NAME, BRAND, CORESOLEIL_ID) 
    VALUES (source.all columns....) 
+0

这工作完美我,谢谢你! –

0

使用下面的脚本..

MERGE CONTACTS as target 
USING STAGING_CONTACTS as source 
ON (target.ID = source.ID) 
WHEN MATCHED THEN 
    UPDATE SET 
     target.MAIL = source.MAIL , 
     target.NAME = source.Name, 
     target.BRAND = source.BRAND , 
     target.ID = source.ID 
WHEN NOT MATCHED THEN 
    INSERT (MAIL, NAME, BRAND, CORESOLEIL_ID) 
    VALUES (source.MAIL , source.Name, source.BRAND ,source.ID);