Oracle эквивалентно MySQL INSERT IGNORE? - PullRequest
23 голосов
/ 17 февраля 2012

Мне нужно обновить запрос, чтобы он проверял, что дублирующая запись не существует перед вставкой. В MySQL я могу просто использовать INSERT IGNORE, чтобы в случае обнаружения дублирующейся записи она просто пропускала вставку, но я не могу найти эквивалентную опцию для Oracle. Есть предложения?

Ответы [ 8 ]

28 голосов
/ 17 февраля 2012

Проверьте оператор MERGE. Это должно делать то, что вы хотите - это предложение WHEN NOT MATCHED, которое сделает это.

Из-за отсутствия поддержки Oracle для истинного предложения VALUES (), синтаксис для одной записи с фиксированными значениями довольно неуклюжий:

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

Другой подход (если вы, например, выполняете массовую загрузку из другой таблицы) - это использовать функцию «Регистрация ошибок» в Oracle. Заявление будет выглядеть так:

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

Впоследствии все строки, которые вызвали бы ошибку, доступны в таблице errlog. Вам нужно создать эту таблицу errlog (или любое другое имя по вашему выбору) перед запуском вставки, используя DBMS_ERRLOG.CREATE_ERROR_LOG.

Подробнее см. В руководстве

20 голосов
/ 18 февраля 2012

Если вы на 11g, вы можете использовать подсказку 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.
8 голосов
/ 17 февраля 2012

Я не думаю, что есть, но чтобы сэкономить время, вы можете попытаться вставить и проигнорировать неизбежную ошибку:

begin

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

   exception when dup_val_on_index then 
      null;

end;
/

Это будет игнорировать только исключения, вызванные дублированием первичного ключа или ограничений уникального ключа; все остальное будет поднято как обычно.

Если вы не хотите этого делать, сначала вам нужно выбрать из таблицы, что не очень эффективно.

4 голосов
/ 20 февраля 2013

Другой вариант

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)

или вы можете сделать

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 
1 голос
/ 18 января 2013

Простое решение

insert into t1
  select from t2 
  where not exists 
    (select 1 from t1 where t1.id= t2.id)
0 голосов
/ 11 января 2019

еще один вариант "где не существует" с использованием дуала ...

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 голосов
/ 23 октября 2015

Это не мое, но очень удобно при использовании sqlloader:

  1. создать представление, указывающее на вашу таблицу:

    CREATE OR REPLACE VIEW test_view
    AS SELECT * FROM test_tab
    
  2. создайте триггер:

    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. и в файле ctl вместо этого вставьте в представление:

    OPTIONS(ERRORS=0)
    LOAD DATA
    INFILE 'file_with_duplicates.csv'
    INTO TABLE test_view
    FIELDS TERMINATED BY ','
    (id, field1)
    
0 голосов
/ 17 февраля 2012

Как насчет простого добавления индекса с любыми полями, в которых нужно проверить наличие дупликов, и сказать, что он должен быть уникальным?Сохраняет проверку на чтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...