【问题标题】:MERGE with multiple UPDATE statementsMERGE 与多个 UPDATE 语句
【发布时间】:2020-04-12 01:53:58
【问题描述】:

我们能否使用单个 MERGE 语句实现以下场景:

源表 - table1 目标表-table2

当 table1.id 在 table2.id 然后更新table1 SET phone_number=123456

当 table1.id 不在 table2.id 中时 然后更新 table1 SET phone_number=555555

注意:- 我可以使用以下查询来获得结果。

MERGE INTO table1 tbl1
USING table2 tbl2 
ON (tbl1.id = tbl2.id) 
WHEN MATCHED THEN 
  UPDATE SET tbl1.phone_number=123456;

update table1 set phone_number = 555555 where id not in (select id from table2);

有没有办法只使用 MERGE 语句来实现它?

【问题讨论】:

  • 不匹配的时候可以试试?
  • @ErsinGülbahar WHEN NOT MATCHED 适用于值在 table2 中但不在 table1 中的情况。 OP 似乎想要等效于 SQL Server 语法 WHEN NOT MATCHED BY [SOURCE|TARGET](在 Oracle 中不存在),以便当 table2 中没有值时,它们可以更新 table1 中的值。

标签: sql oracle


【解决方案1】:

如果没有匹配的行,则不能使用UPDATE(在WHEN NOT MATCHED 中)。由于没有匹配的行,那么应该更新哪些数据?

正常的合并语句必须具有以下结构:

MERGE <hint> INTO <table_name>
USING <table_view_or_query>
ON (<condition>)
WHEN MATCHED THEN <update_clause>
DELETE <where_clause>
WHEN NOT MATCHED THEN <insert_clause>
[LOG ERRORS <log_errors_clause> <reject limit <integer | unlimited>];

当没有匹配项时,oracle 没有在您的target 表中找到与使用ON 条件匹配的source 表的行,那么它如何更新记录?它将更新哪条记录?

WHEN NOT MATCHEDoracle documentation中说明如下:

您可以使用 MERGE 处理您的场景,如下所示:

-- Oracle 数据创建

SQL> CREATE TABLE table1 ( id number, phone_number number );

Table created.

SQL> INSERT INTO table1
  2  SELECT 1, 111 from dual UNION ALL
  3  SELECT 2, 222 from dual UNION ALL
  4  SELECT 3, 333 from dual UNION ALL
  5  SELECT 4, 444 from dual;

4 rows created.

SQL> drop table table2;

Table dropped.

SQL> CREATE TABLE table2 ( id number );

Table created.

SQL> INSERT INTO table2
  2  SELECT 1 from dual UNION ALL
  3  SELECT 2 from dual;

2 rows created.

-- 你的合并声明

SQL> MERGE INTO TABLE1 TBL1
  2  USING (
  3           SELECT T1.ID, T2.ID AS T2ID
  4           FROM TABLE1 T1
  5               LEFT JOIN TABLE2 T2 ON T1.ID = T2.ID
  6       )
  7  TBL2 ON ( TBL1.ID = TBL2.ID )
  8  WHEN MATCHED THEN
  9  UPDATE SET TBL1.PHONE_NUMBER = NVL2(TBL2.T2ID, 123456, 555555);

4 rows merged.

--结果

SQL> SELECT * FROM TABLE1;

        ID PHONE_NUMBER
---------- ------------
         1       123456
         2       123456
         3       555555
         4       555555

SQL>

干杯!!

【讨论】:

    【解决方案2】:

    只需使用UPDATE 声明:

    Oracle 设置

    CREATE TABLE table1 ( id, phone_number ) AS
    SELECT 1, 1 FROM DUAL UNION ALL
    SELECT 2, 2 FROM DUAL;
    
    CREATE TABLE table2 ( id ) AS
    SELECT 1 FROM DUAL UNION ALL
    SELECT 3 FROM DUAL;
    

    更新

    UPDATE table1 t1
    SET    phone_number = COALESCE(
                            (
                              SELECT 123456
                              FROM   table2 t2
                              WHERE  t1.id = t2.id
                            ),
                            555555
                          )
    

    输出

    SELECT *
    FROM   table1
    
    身份证 |电话号码 -: | ------------: 1 | 123456 2 | 555555

    db小提琴here


    您在MERGE 语句中查找的语法存在于 SQL Server 中,但在 Oracle 中有效:

    MERGE INTO table1 t1
    USING table2 t2
    ON ( t1.id = t2.id )
    WHEN MATCHED THEN
      UPDATE SET phone_number = 123456
    WHEN NOT MATCHED BY SOURCE THEN
      UPDATE SET phone_number = 555555;
    

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 2016-04-30
      • 2018-09-01
      • 2013-06-11
      • 1970-01-01
      • 2020-02-09
      相关资源
      最近更新 更多