小编典典

Oracle MERGE:仅触发NOT MATCHED

sql

数据库: Oracle

桌子:

CREATE TABLE TABLE_FOR_TESTS (
    d DATE,
    t NUMBER(8)
)

合并:

MERGE INTO TABLE_FOR_TESTS
    USING DUAL
    ON ((SELECT COUNT(*) FROM TABLE_FOR_TESTS) = 1)
    WHEN MATCHED THEN
        UPDATE SET T = T+1
    WHEN NOT MATCHED THEN         
        INSERT (D, T) VALUES (sysdate, 1)

或者

    ...
    ON ((SELECT T FROM TABLE_FOR_TESTS) is not null)
    ...

我将参考MERGE的第一个版本,但是第二个版本具有相同的效果。

1)我第一次运行MERGE

  • 结果: 预期 (因为没有任何元素,所以ON条件为false => INSERT

2)我在这里运行:

SELECT COUNT(*) FROM TABLE_FOR_TESTS

它的输出为“ 1”。

3)我第二次运行该合并

  • 结果: 意外INSERT ),预期:UPDATE(仅在sqlfiddle上有效)

为什么在第N次运行(N> 1)时 ON 条件为假?(如果在输出2时为“ 1”)

(只是测试:如果我将条件更改为ON (1=1)第二次运行之前,则效果很好:UPDATE已完成)


阅读 293

收藏
2021-05-16

共1个答案

小编典典

我认为您误解了合并的目的。

我希望您的桌子像这样:

CREATE TABLE TABLE_FOR_TESTS (
    d DATE,
    t NUMBER(8),
    CONSTRAINT TABLE_FOR_TESTS_PK PRIMARY KEY (d)
)

然后合并语句可能是:

MERGE INTO TABLE_FOR_TESTS t
  USING (SELECT trunc(sysdate) d FROM DUAL) s
    ON (s.d = t.d)
  WHEN MATCHED THEN
    UPDATE SET t = t+1
  WHEN NOT MATCHED THEN         
    INSERT (d, t) VALUES (trunc(sysdate), 1)

联接在表的主键上的位置,并根据该PK值的记录是否存在而更新或插入。

每天最多有一个记录,并且t将保存每天该语句的执行次数(假设TABLE_FOR_TESTS上没有其他DML)。

注意:sysdate本身包含一个时间成分。trunc(sysdate)会将其删除并将时间设置为00:00:00。

2021-05-16