Oracle MERGE:仅触发NOT MATCHED

时间:2014-08-22 16:36:10

标签: sql oracle merge match on-clause

数据库: Oracle

表:

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

MERGE:

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)我第二次运行MERGE

  • 结果:意外 INSERT ),预期:更新(仅适用于sqlfiddle)

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

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

1 个答案:

答案 0 :(得分: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。