Utwórz zewnętrzną tabelę w swoim pliku CSV. Są to bardzo zgrabne rzeczy, które pozwalają nam odpytywać zawartość pliku systemu operacyjnego w SQL. Dowiedz się więcej .
Następnie wystarczy wysłać zapytanie:
select csv.id
, case ( when tgt.id is null then 'invalid' else 'valid') end as valid_id
from your_external_tab csv
left join target_table tgt on (csv.id = tgt.id)
Wydajność jest kwestią kontekstu. W tym przypadku zależy to od tego, jak często zmieniają się dane w CSV i jak często musimy je odpytywać. Jeśli plik jest tworzony raz dziennie i wystarczy sprawdzić wartości po jego dostarczeniu, wówczas najbardziej wydajnym rozwiązaniem jest tabela zewnętrzna. Ale jeśli ten zestaw danych jest stałym repozytorium, do którego należy często odpytywać, wówczas obciążenie związane z zapisem do tabeli sterty jest oczywiście uzasadnione.
Dla mnie plik CSV składający się z wielu identyfikatorów i nic więcej nie brzmi jak dane przejściowe i pasuje do przypadku użycia dla tabel zewnętrznych. Ale PO może mieć dodatkowe wymagania, o których nie wspomnieli.
Oto alternatywne podejście, które nie wymaga tworzenia stałych obiektów bazy danych. W związku z tym jest mniej elegancki i prawdopodobnie będzie działał gorzej.
Odczytuje plik CSV pracowicie przy użyciu UTL_FILE i wypełnia kolekcję opartą na SYSTEM.NUMBER_TBL_TYPE, predefiniowanej kolekcji (zagnieżdżonej tabeli NUMBER), która powinna być dostępna w Twojej bazie danych Oracle.
declare
ids system.number_tbl_type;
fh utl_file.file_handle;
idx pls_integer := 0;
n pls_integer;
begin
fh := utl_file.fopen('your_data_directory', 'your_data.csv', 'r');
begin
utl_file.get_line(fh, n);
loop
idx := idx + 1;
ids.extend();
ids(idx) := n;
utl_file.get_line(fh, n);
end loop;
exception
when no_data_found then
if utl_file.is_open(fh) then
utl_file.fclose(fh);
end if;
when others then
raise;
end;
for id_recs in in ( select csv.column_value
, case ( when tgt.id is null then 'invalid' else 'valid') end as valid_id
from (select * from table(ids)) csv
left join target_table tgt on (csv.column_value = tgt.id)
) loop
dbms_output.put_line '(ID '||id_recs.column_value || ' is '||id_recs.valid_id);
end loop;
end;
Uwaga:nie testowałem tego kodu. Zasada jest dobra, ale szczegóły mogą wymagać debugowania;)