【问题标题】:Using multiple statements in WHEN MATCHED在 WHEN MATCHED 中使用多个语句
【发布时间】:2018-02-18 20:03:52
【问题描述】:

我正在使用MERGE 语句将XML 输入插入到SQL Server 数据库表中。如何在WHEN MATCHED 块中执行多个条件。请参考以下代码。

USING TableRelationship AS new
  ON (new.TableRelationshipTypeID = old.TableRelationshipTypeID) AND old.ToRoleID = @RoleID

WHEN MATCHED THEN 
   UPDATE 
       SET old.FromRoleID = new.FromRoleID
   -- Condition 2
   -- Condition 3

目前WHEN MATCHED 它只执行这个old.FromRoleID = new.FromRoleID 行。如何在WHEN NOT MATCHED 条件内执行所有 3 行 (-- Condition 2 and 3)。

例如:

这是我所期望的。 WHEN MATCHED 我只想更新旧字段 (old.ThruDate = GETDATE()) 并在同一张表中插入一条记录。我不能用逗号分隔这些语句。 SQL 发出

语法错误

MERGE INTO Party.TableRelationship AS old
USING TableRelationship AS new ON (new.TableRelationshipTypeID = old.TableRelationshipTypeID) AND old.ToRoleID = @RoleID

WHEN MATCHED THEN 
   UPDATE 
       SET old.ThruDate = GETDATE(),
   INSERT (FromRoleID, ToRoleID, TableRelationshipTypeID)
   VALUES (new.FromRoleID, new.ToRoleID, new.TableRelationshipTypeID);

谢谢。

【问题讨论】:

  • 请显示第二个和第三个条件的代码(如果它不运行也没关系,只需显示那里的逻辑即可)。
  • 可能相关(或重复),具体取决于此处实际询问的内容:stackoverflow.com/questions/25848219/…

标签: sql sql-server tsql merge sql-update


【解决方案1】:

您可以使用 INSERT over DML 来实现它:

INSERT INTO tab_name(FromRoleID, ToRoleID, TableRelationshipTypeID)
SELECT FromRoleID, ToRoleID, TableRelationshipTypeID
FROM (
  MERGE INTO Party.TableRelationship AS old
  USING TableRelationship AS new 
     ON new.TableRelationshipTypeID = old.TableRelationshipTypeID 
    AND old.ToRoleID = @RoleID
  WHEN MATCHED THEN 
    UPDATE SET old.ThruDate = GETDATE()
    OUTPUT $action, FromRoleID, ToRoleID, TableRelationshipTypeID
) sub(action, FromRoleID, ToRoleID, TableRelationshipTypeID)
WHERE action = 'UPDATE';

请记住,此方法有一些限制更多信息: MS Connect

【讨论】:

  • @HarshaW 它应该适用于您的情况。如果您准备rextester.com 示例数据,我可以提供工作演示。
【解决方案2】:

不能这样做 - SQL Server 的MERGE 语句只是不支持

WHEN MATCHED 的情况下,您可以执行一个UPDATE(或DELETE)语句 - 您不能有多个不同的语句一个接一个。

查看official MSDN documentation for MERGE - 它详细说明了哪些是可能的,哪些是不支持的:

语法:

MERGE   
    USING <table_source> ON <merge_search_condition>  
    [ WHEN MATCHED [ AND <clause_search_condition> ]  
        THEN <merge_matched> ] [ ...n ]  
;  

<merge_matched>::=  
    { UPDATE SET <set_clause> | DELETE }  

MERGE 语句最多可以有两个 WHEN MATCHED 子句。如果两个 指定子句,则第一个子句必须附有 AND 子句。对于任何给定的行,第二个 WHEN MATCHED 子句仅在第一个不是时才应用。如果有两个 WHEN MATCHED 子句,则必须指定一个 UPDATE 操作和一个 必须指定 DELETE 操作

【讨论】:

    【解决方案3】:

    这不是合并语句的用途。如果记录已经存在(WHEN MATCHED THEN),merge 语句要么更新记录,要么在记录不存在时插入记录(WHEN NOT MATCHED THEN)。它不是为了在找到匹配项时插入记录而设计的

    (旁注:sqlserver 合并语句可以指定 WHEN MATCHED 两次,也许您会使用它的目的是其中一个匹配从目标中删除与某些附加条件匹配的记录,另一个指定要如果附加逻辑测试为假,则更新)

    如果您想在匹配记录时混合并匹配插入和更新,则需要使用其他东西,例如对更新做出反应的存储过程或触发器

    或者,如果您只是询问合并语句的语法,您的插入指令需要在前面加上 WHEN NOT MATCHED THEN INSERT ...

    【讨论】:

      【解决方案4】:

      那些不是条件,它们是赋值子句。你用逗号分隔它们,如update:

      USING TableRelationship AS new
        ON (new.TableRelationshipTypeID = old.TableRelationshipTypeID) AND 
           old.ToRoleID = @RoleID
        WHEN MATCHED THEN UPDATE
            SET old.FromRoleID = new.FromRoleID,
                <assignment 2>,
                <assignment 3>;
      

      【讨论】:

      • 我修改了问题。在这里我不能使用,。它说语法错误。我发布了整个代码。请看一看。
      猜你喜欢
      • 2016-05-10
      • 1970-01-01
      • 2016-04-30
      • 2022-07-06
      • 2013-05-26
      • 2015-09-17
      • 2016-01-15
      • 1970-01-01
      • 2017-02-13
      相关资源
      最近更新 更多