web-dev-qa-db-fra.com

Oracle équivalent à MySQL INSERT IGNORE?

Je dois mettre à jour une requête afin qu'elle vérifie qu'une entrée en double n'existe pas avant l'insertion. Dans MySQL, je peux simplement utiliser INSERT IGNORE pour que, si un enregistrement en double est trouvé, il saute simplement l'insertion, mais je ne trouve pas l'option équivalente pour Oracle. Aucune suggestion?

21
Bad Programmer

Découvrez la déclaration MERGE. Cela devrait faire ce que vous voulez - c'est la clause WHEN NOT MATCHED qui le fera. 

En raison du manque de prise en charge par Oracle d'une vraie clause VALUES (), la syntaxe d'un enregistrement unique avec des valeurs fixes est assez maladroite:

MERGE INTO your_table yt
USING (
   SELECT 42 as the_pk_value, 
          'some_value' as some_column
   FROM dual
) t on (yt.pk = t.the_pke_value) 
WHEN NOT MATCHED THEN 
   INSERT (pk, the_column)
   VALUES (t.the_pk_value, t.some_column);

Une approche différente (si vous effectuez par exemple un chargement en vrac à partir d’une autre table) consiste à utiliser la fonction "Enregistrement des erreurs" d’Oracle. La déclaration ressemblerait à ceci:

 INSERT INTO your_table (col1, col2, col3)
 SELECT c1, c2, c3
 FROM staging_table
 LOG ERRORS INTO errlog ('some comment') REJECT LIMIT UNLIMITED;

Ensuite, toutes les lignes qui auraient généré une erreur sont disponibles dans la table errlog. Vous devez créer cette table errlog (ou le nom de votre choix) manuellement avant d'exécuter l'insertion à l'aide de DBMS_ERRLOG.CREATE_ERROR_LOG.

Voir le manuel pour plus de détails

26
a_horse_with_no_name

Si vous êtes sur 11g, vous pouvez utiliser l'indice IGNORE_ROW_ON_DUPKEY_INDEX :

SQL> create table my_table(a number, constraint my_table_pk primary key (a));

Table created.

SQL> insert /*+ ignore_row_on_dupkey_index(my_table, my_table_pk) */
  2  into my_table
  3  select 1 from dual
  4  union all
  5  select 1 from dual;

1 row created.
18
Jon Heller

Je ne pense pas qu'il y en ait un, mais pour gagner du temps, vous pouvez tenter l'insertion et ignorer l'erreur inévitable:

begin

   insert into table_a( col1, col2, col3 )
   values ( 1, 2, 3 );

   exception when dup_val_on_index then 
      null;

end;
/

Cela ignorera uniquement les exceptions générées spécifiquement par une clé primaire en double ou des contraintes de clé uniques; tout le reste sera soulevé comme d'habitude.

Si vous ne voulez pas faire cela, vous devez d'abord sélectionner dans le tableau, ce qui n'est pas vraiment efficace.

6
Ben

Une autre variante

Insert into my_table (student_id, group_id)
select distinct p.studentid, g.groupid 
from person p, group g
where NOT EXISTS (select 1
                 from my_table a
                 where a.student_id = p.studentid
                 and a.group_id = g.groupid)

ou tu pourrais faire 

Insert into my_table (student_id, group_id)
select distinct p.studentid, g.groupid 
from person p, group g
MINUS
select student_id, group_id
from my_table 
4
rt.jar

Une solution simple

insert into t1
  select from t2 
  where not exists 
    (select 1 from t1 where t1.id= t2.id)
1
knagaev

encore un autre "où pas existe" -variant utilisant dual ...

insert into t1(id, unique_name)
  select t1_seq.nextval, 'Franz-Xaver' from dual 
    where not exists (select 1 from t1 where unique_name = 'Franz-Xaver');
0
dev-null

Celui-ci n'est pas le mien, mais s'est avéré très utile avec sqlloader:

  1. créez une vue qui pointe vers votre table:

    CREATE OR REPLACE VIEW test_view
    AS SELECT * FROM test_tab
    
  2. créer le déclencheur:

    CREATE OR REPLACE TRIGGER test_trig
     INSTEAD OF INSERT ON test_view
     FOR EACH ROW
      BEGIN
       INSERT INTO test_tab VALUES
        (:NEW.id, :NEW.name);
      EXCEPTION
       WHEN DUP_VAL_ON_INDEX THEN NULL;
      END test_trig;
    
  3. et dans le fichier ctl, insérez plutôt dans la vue:

    OPTIONS(ERRORS=0)
    LOAD DATA
    INFILE 'file_with_duplicates.csv'
    INTO TABLE test_view
    FIELDS TERMINATED BY ','
    (id, field1)
    
0
vinnyman

Que diriez-vous simplement d'ajouter un index avec tous les champs dont vous avez besoin pour rechercher les dupes et dire qu'il doit être unique? Enregistre un contrôle de lecture.

0
spootdev