簡體   English   中英

根據條件在同一個表上使用Oracle MERGE

[英]Using Oracle MERGE on same table based on condition

我創建了一個Oracle序列如下:

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中的日期表TASK_DATE ,否則忽略它。

以下語法是否正確?

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) . . .

請建議。

您的業​​務規則表示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生成了一組任務。 如果你想要的是從昨天的集合為今天創建一組新的任務,USING子句將如下所示:

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> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM