SQL 2008 R2:尝试在存储过程中使用T-SQL MERGE语句

Dav*_*.id 2 sql t-sql insert-update sql-server-2008

我已经查看了SQL Merge语句的各种示例..所有这些都看起来很棒,虽然由于某些原因我似乎无法从我的Merge测试中获得正确/预期的结果.

快速概述: 我有一个包含一些设计数据的简单表格.阅读MERGE似乎指向一种更有效的方法来进行 'upsert'(即:根据记录是否存在,插入或更新).

所以SQL 2008代码就是这样的(对不起,如果它还没有完全完成,因为我正在处理它!):

这将是一个存储过程,所以@values显然是传递的参数..

merge designs as ds
using ( select designname, designcode from designs) as dsi
on (@passedDesignName = dsi.designname and @passedDesignCode = dsi.designcode)
when matched then
    update set ds.designname = @passedDesignName, ds.designcode = @passedDesignCode
when not matched then
    insert (designname, designcode)
    values (@passedDesignName, @passedDesignCode)
Run Code Online (Sandbox Code Playgroud)

这个问题似乎超出了我正在测试的7条记录中,所有这些记录似乎都在更新,显然我只能看到一条与更新相匹配的记录..而奇怪的是,如果我传递一些新数据(designname)和设计代码),我似乎得到一个重复插入...从我上次的测试看起来似乎有7个新的插入,我猜不只是一个侥幸..

希望我已经正确解释了这一点.攻击新事物的一部分主要是让上下文正确吗?

提前感谢您的任何反馈.

PS:对不起,合并声明结尾有一个分号!完成解析检查/语法.

And*_*mar 5

您正在使用designs目标和源表:

merge designs as ds
using ( select designname, designcode from designs) as dsi
Run Code Online (Sandbox Code Playgroud)

这相当于:

merge designs as ds
using designs as dsi
Run Code Online (Sandbox Code Playgroud)

相反,尝试将变量作为源表传递:

merge designs as ds
using (
      select  @passedDesignName as designname
      ,       @passedDesignCode as designcode
      ) as dsi
on (ds.esignName = dsi.designname and ds.designCode = dsi.designcode)
Run Code Online (Sandbox Code Playgroud)