2017-05-09 87 views
3

我已經創建瞭如下Oracle序列:使用Oracle在同一個表MERGE根據病情

CREATE SEQUENCE TASK_ID_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE; 

我有如下一個數據庫表TASK

TASK_ID nextval from TASK_ID_SEQ 
TASK_DATE SYSDATE 
TASK_TYPE <value fed from data> 

我需要插入一個新的TASK如果TASK_TYPE尚未出現在TASK_DATE日期的TASK表中,則記錄它,否則忽略它。

以下語法是否正確?

MERGE INTO TASK a 
USING (SELECT b.task_date FROM TASK b) 
ON (a.task_type = b.task_type) 
WHEN NOT MATCHED THEN 
[INSERT INTO TASK] 

還是應爲:

MERGE INTO TASK a 
USING (SELECT b.task_date FROM TASK b) 
ON (a.task_type = b.task_type) 
WHEN MATCHED THEN 
[] 
WHEN MATCHED THEN 
[INSERT INTO TASK] 

我可以交替使用

MERGE INTO TASK USING (select 1 from DUAL) . . . 

請不要建議。

+0

如果它只是一個插入,那麼爲什麼不使用select語句插入語句? – user75ponic

+0

@ user75ponic有兩個原因,一個是爲了適應未來的最新更新,其次是你預計Merge將比插入更慢?如果不是,那爲什麼不呢? –

回答

3

您的商業規則表明DATE和TYPE上的匹配。因此,您的代碼有兩個錯誤:

  1. USING子句需要選擇確定匹配所需的所有條件。
  2. ON子句需要測試確定匹配所需的所有條件。

此外,如果您不需要更新現有記錄,則可以省略WHEN MATCHED分支。所以你的MERGE聲明應該看起來像這樣:

merge into task 
using ( 
    select date '2017-05-08' as dt, 'BATTLE' as typ from dual union all 
    select date '2017-05-08' as dt, 'JUGGLE' as typ from dual union all 
    select date '2017-05-08' as dt, 'PLOT' as typ from dual) q 
on (task.task_date = q.dt 
    and task.task_type = q.typ) 
when not matched then 
    insert values (task_id_seq.nextval, q.dt, q.typ) 
/ 

演示。給定此起點...

SQL> select * from task; 

    TASK_ID TASK_DATE TASK_TYPE 
---------- ---------- ---------- 
     1 2017-05-06 CLEAN 
     2 2017-05-06 BATTLE 
     3 2017-05-06 JUGGLE 
     4 2017-05-07 JUGGLE 
     5 2017-05-07 CLEAN 
     6 2017-05-07 NAP 
     7 2017-05-08 BATTLE 

7 rows selected. 
SQL> 

...上述MERGE應插入兩行(數據源中的一行與現有行匹配)。

SQL> merge into task 
    2 using ( 
    3  select date '2017-05-08' as dt, 'BATTLE' as typ from dual union all 
    4  select date '2017-05-08' as dt, 'JUGGLE' as typ from dual union all 
    5  select date '2017-05-08' as dt, 'PLOT' as typ from dual) q 
    6 on (task.task_date = q.dt 
    7  and task.task_type = q.typ) 
    8 when not matched then 
    9  insert values (task_id_seq.nextval, q.dt, q.typ) 
10/ 

2 rows merged. 

SQL> select * from task 
    2/

    TASK_ID TASK_DATE TASK_TYPE 
---------- ---------- ---------- 
     1 2017-05-06 CLEAN 
     2 2017-05-06 BATTLE 
     3 2017-05-06 JUGGLE 
     4 2017-05-07 JUGGLE 
     5 2017-05-07 CLEAN 
     6 2017-05-07 NAP 
     7 2017-05-08 BATTLE 
     9 2017-05-08 JUGGLE 
     10 2017-05-08 PLOT 

9 rows selected. 

SQL> 

數據源是不完全清楚。所以在上面的例子中,我使用DUAL生成了一組任務。如果你想要的是從集合昨日創建一組新的任務對今天的使用條款是這樣的:

merge into task 
using ( 
    select trunc(sysdate) as dt, task_type as typ 
    from task 
    where task_date = trunc(sysdate) - 1) q 
on (task.task_date = q.dt 
    and task.task_type = q.typ) 
when not matched then 
    insert values (task_id_seq.nextval, q.dt, q.typ) 
/

使用了同一起跑線數據,在此之前的版本中插入三行:

SQL> select * from task; 

    TASK_ID TASK_DATE TASK_TYPE 
---------- ---------- ---------- 
     1 2017-05-06 CLEAN 
     2 2017-05-06 BATTLE 
     3 2017-05-06 JUGGLE 
     4 2017-05-07 JUGGLE 
     5 2017-05-07 CLEAN 
     6 2017-05-07 NAP 
     7 2017-05-08 BATTLE 
     11 2017-05-08 CLEAN 
     12 2017-05-08 JUGGLE 
     13 2017-05-08 NAP 

10 rows selected. 

SQL>