0

数据库:甲骨文

桌子:

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

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

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

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

4

1 回答 1

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。

于 2014-08-22T17:36:48.503 回答