Jesteś już w połowie drogi do rozwiązania:
To nie jest niespodzianka. Twoja bieżąca implementacja wykonuje wiele jednowierszowych instrukcji SELECT dla każdego wiersza, który wstawiasz do tabeli B. To nieuchronnie da ci słaby profil wydajności. SQL jest językiem opartym na zbiorach i działa lepiej w operacjach wielowierszowych.
Musisz więc znaleźć sposób na zastąpienie wszystkich instrukcji SELECT bardziej wydajnymi alternatywami. Wtedy będziesz mógł na stałe upuścić wyzwalacze. Na przykład zastąp wyszukiwania w słowniku kluczami obcymi między kolumnami tabeli A a tabelą referencyjną. Ograniczenia integralności relacyjnej, będące wewnętrznym kodem Oracle, działają znacznie lepiej niż jakikolwiek kod, który możemy napisać (i pracować również w środowiskach wielu użytkowników).
Bardziej problematyczna jest reguła o niewstawianiu do tabeli A, jeśli kombinacja kolumn już istnieje w tabeli B. Nie dlatego, że jest to trudne, ale dlatego, że brzmi to jak kiepski projekt relacyjny. Jeśli nie chcesz ładować rekordów w tabeli A, gdy już wychodzą z tabeli B, dlaczego nie ładujesz bezpośrednio do tabeli B? A może masz podzbiór kolumn, które należy wyodrębnić z tabeli A i tabela B i uformowana w tabelę C (która miałaby relacje klucza obcego z A i B)?
W każdym razie, pozostawiając to na boku, możesz to zrobić za pomocą SQL opartego na zbiorach, zastępując SQL*Loader tabelą zewnętrzną. Zewnętrzna tabela pozwala nam zaprezentować plik CSV w bazie danych tak, jakby była to zwykła tabela. Oznacza to, że możemy go używać w normalnych instrukcjach SQL. Dowiedz się więcej.
Tak więc, z ograniczeniami klucza obcego w słowniku i zewnętrznej tabeli, możesz zastąpić kod programu ładującego SQL tą instrukcją (z zastrzeżeniem wszelkich innych reguł, które są zawarte w "...i tak dalej"):
insert into table_a
select ext.*
from external_table ext
left outer join table_b b
on (ext.name = b.name and ext.last_name = b.last_name and ext.dept=b.dept)
where b.name is null
log errors into err_table_a ('load_fail') ;
Wykorzystuje to składnię rejestrowania błędów DML do przechwytywania błędów ograniczeń dla wszystkich wierszy w sposób oparty na zestawie. Dowiedz się więcej . Nie wywoła wyjątków dla wierszy, które już istnieją w tabeli B. Możesz użyć wielostołowy WSTAW WSZYSTKO przekierować wiersze do tabeli przepełnienia lub użyć operacji zestawu MINUS po zdarzeniu, aby znaleźć wiersze w tabeli zewnętrznej, których nie ma w tabeli A. Zależy od celu końcowego i sposobu raportowania.
Być może bardziej złożona odpowiedź, niż się spodziewałeś. Oracle SQL to bardzo rozbudowana implementacja SQL, z wieloma funkcjami poprawiającymi wydajność operacji masowych. Naprawdę opłaca się nam przeczytać Concepts Guide i SQL Reference, aby dowiedzieć się, jak wiele możemy zrobić z Oracle.