Votre règle métier indique une correspondance sur DATE et TYPE. Il y a donc deux problèmes avec votre code:
- La clause USING doit sélectionner tous les critères nécessaires pour déterminer une correspondance.
- La clause ON doit tester tous les critères nécessaires pour déterminer une correspondance.
De même, si vous n'avez pas besoin de mettre à jour les enregistrements existants, vous pouvez omettre la branche WHEN MATCHED. Votre instruction MERGE doit donc ressembler à ceci:
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)
/
Une démo. Compte tenu de ce point de départ ...
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 ci-dessus doivent y insérer deux lignes (une ligne de la source de données correspond à une ligne existante).
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>
La source de données ne sont pas tout à fait clair. Donc, dans l'exemple ci-dessus, j'ai généré un ensemble de tâches en utilisant DUAL. Si ce que vous voulez est de créer une nouvelle série de tâches pour aujourd'hui de l'ensemble d'hier la clause USING ressemblerait à ceci:
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)
/
En utilisant les mêmes données de départ comme avant cette version insère trois lignes:
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>
S'il s'agit seulement d'un insert alors pourquoi ne pas utiliser une instruction insert en utilisant select? – user75ponic
@ user75ponic deux raisons, l'une pour s'adapter à la mise à jour à l'avenir avec des changements minimes et d'autre part pensez-vous que la fusion sera plus lente que l'insertion? Si non, alors pourquoi pas? –