2010-08-30 4 views
0

j'ai une procédure PL/SQL en utilisant MERGE:MERGE - En cas de non apparié l'exception de INSERT

MERGE INTO 
    table_dest d 
USING 
    (SELECT * FROM my_Table) s 
ON 
    (s.id = d.id) 
when matched  then UPDATE set d.col1 = s.col1 
when not matched then INSERT (id, col1) values (s.id, s.col1); 

Maintenant, supposons que la requête s retourne mutiple lignes avec la même Wich identifiant volonté retourne un ORA-00001: Contraindre uniques erreur

ce que je veux faire est d'envoyer les colonnes dupliquées à une autre table my_Table_recyledbin pour obtenir un succès INSERT, puis-je utiliser EXCEPTION WHEN DUP_VAL_ON_INDEX? Si oui, comment l'utiliser avec l'instruction MERGE?

Merci à l'avance

Répondre

2

Pourquoi ne pas gérer l'archivage des lignes en double à la table de la corbeille dans une déclaration distincte? Commencez par effectuer une fusion (regrouper les lignes en double pour éviter l'erreur de contrainte unique). J'ai supposé une fonction d'agrégat MAX sur col1, mais vous pouvez utiliser ce qui convient à vos besoins - vous n'avez pas spécifié comment décider quelle ligne utiliser quand il y a des doublons.

MERGE INTO 
    table_dest d 
USING 
    (SELECT a.id, MAX(a.col1) as col1 
    FROM my_Table a 
    GROUP BY a.id) s 
ON 
    (s.id = d.id) 
WHEN MATCHED THEN UPDATE SET d.col1 = s.col1 
WHEN NOT MATCHED THEN INSERT (id, col1) VALUES (s.id, s.col1); 

Puis, gérer les lignes en double. Je suppose que votre table de corbeille ne permet en double ids à insérer:

INSERT INTO my_Table_recyledbin r (id, col1) 
SELECT s.id, s.col1 
    FROM my_Table s 
WHERE EXISTS (SELECT 1 
       FROM my_Table t 
       WHERE t.id = s.id 
        AND t.ROWID != s.ROWID) 

Espérons que cela devrait répondre à vos besoins. Vous ne pouvez pas simplement utiliser une clause de consignation des erreurs?

+0

Merci Tom cela est vraiment utile, je vais essayer dès maintenant! – mcha

+0

@mcha Content d'aider, laissez-moi savoir comment cela fonctionne. – Tom

+0

fonctionne parfaitement! thx – mcha

1

À savoir, ajoutez cette ligne à la fin de votre déclaration MERGE:

LOG ERRORS INTO my_Table_recycledbin 
+0

Merci dave, je ne savais pas sur les LOG ERRORS, je lisais à ce sujet et malheureusement, il dit que: > La fonctionnalité d'enregistrement d'erreur DML n'est pas appelée lorsque: - opérations UPDATE ou ** MERGE ** déclenche une ** contrainte unique ou une violation d'index **. – mcha