Muszę zaktualizować zapytanie, aby sprawdzało, czy duplikat nie istnieje przed wstawieniem. W MySQL mogę po prostu użyć INSERT IGNORE, więc jeśli znajdzie się duplikat, to po prostu pominie wstawkę, ale nie mogę znaleźć odpowiednika dla Oracle. Jakieś sugestie?Oracle równoważne z MySQL INSERT IGNORE?
Odpowiedz
Sprawdź instrukcję MERGE. Powinno to zrobić, co chcesz - jest to klauzula WHEN NOT MATCHED
, która to zrobi.
uwagi na brak Oracle wsparcia dla prawdziwego wartości() Klauzula składni dla pojedynczego rekordu ze stałymi wartościami jest dość niezdarny choć:
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);
Inne podejście (jeśli np robi luzem załadunek z inna tabela) jest użycie funkcji "Rejestrowanie błędów" w Oracle. Oświadczenie będzie wyglądać następująco:
INSERT INTO your_table (col1, col2, col3)
SELECT c1, c2, c3
FROM staging_table
LOG ERRORS INTO errlog ('some comment') REJECT LIMIT UNLIMITED;
Następnie wszystkie wiersze, które zostały rzucone błąd dostępne są w tabeli errlog
. Trzeba ręcznie utworzyć tabelę (lub dowolną nazwę) przed uruchomieniem wstawki przy użyciu DBMS_ERRLOG.CREATE_ERROR_LOG
.
Zobacz instrukcję szczegóły
Nie sądzę, istnieje tylko zaoszczędzić czas można próbować wkładkę i ignorować nieunikniony błąd:
begin
insert into table_a(col1, col2, col3)
values (1, 2, 3);
exception when dup_val_on_index then
null;
end;
/
To będzie tylko ignorować wyjątki podniesione przez specjalnie duplikatu klucza podstawowego lub unikalnych kluczowych ograniczeń; wszystko inne zostanie podniesione jak zwykle.
Jeśli nie chcesz tego robić, musisz najpierw wybrać z tabeli, która nie jest tak skuteczna.
Jak o po prostu dodanie indeksu ze cokolwiek pól trzeba sprawdzić powtórzeń na i powiedzieć to musi być wyjątkowa? Zapisuje sprawdzenie odczytu.
Ponieważ to nie powiedzie się wstawić, jeśli istnieją duplikaty, kiedy naprawdę może po prostu chcesz je pominąć. –
Jeśli jesteś na 11g można skorzystać z podpowiedzi 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.
dzięki temu zadziałało! ale wydaje się takie niestandardowe rozwiązanie .. jak każdy będzie kiedykolwiek pamiętać ten zapis. –
@SonicSoul Masz rację, to jest niezwykły sposób kodowania. W instrukcji zauważono również, że podpowiedzi normalnie nie mają efektu semantycznego. Podobnie jak wszystkie wskazówki, ten musi być używany ostrożnie. Na przykład, jeśli wskazówka została błędnie napisana, nie wystąpiłby błąd czasu kompilacji, funkcja po prostu nie działałaby po cichu. –
Tak, niedawno przybył do rozwoju Oracle i jestem dość zaskoczony ilością tych sztuczek, aby osiągnąć to, co myślałem, były proste rzeczy z SQL :) –
proste rozwiązanie
insert into t1
select from t2
where not exists
(select 1 from t1 where t1.id= t2.id)
Inny wariant
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)
czy można zrobić
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
To nie jest moja, ale przyszedł w bardzo przydatne podczas korzystania sqlloader:
utworzyć widok, który wskazuje na stole:
CREATE OR REPLACE VIEW test_view AS SELECT * FROM test_tab
utworzyć wyzwalacz:
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;
oraz w pliku ctl, wstaw do widoku zamiast:
OPTIONS(ERRORS=0) LOAD DATA INFILE 'file_with_duplicates.csv' INTO TABLE test_view FIELDS TERMINATED BY ',' (id, field1)
błędy dziennika będzie nadal wyjątek na unikalnych lub łamania podstawowych kluczowych, chyba wiele się zmieniło od: http://asktom.oracle.com/pls/apex/f?p=100:11: 0 :::: P11_QUESTION_ID: 1500471500346067777 –
@ShannonSeverance: To działa dla 'INSERT's czyli co Bad Programista prosi. Ale dzięki za link nie był świadomy, że to nie działa do aktualizacji na PK (używam go tylko do wkładek) –
Should'nt Opcja 'FROM' kluczowe zostać zastąpione przez' USING' hasła? Zajrzyj na http://stackoverflow.com/questions/16414747/oracle-equivalent-of-insert-ignore w razie potrzeby. – Wis