Créez une table externe sur votre fichier CSV. Ce sont des choses très intéressantes qui nous permettent d'interroger le contenu d'un fichier OS en SQL. En savoir plus .
Il suffit ensuite d'émettre une requête :
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)
La performance est une question de contexte. Dans ce cas, cela dépend de la fréquence à laquelle les données du CSV changent et de la fréquence à laquelle nous devons les interroger. Si le fichier est produit une fois par jour et que nous n'avons besoin de vérifier les valeurs qu'après sa livraison, une table externe est la solution la plus efficace. Mais si cet ensemble de données est un référentiel permanent qui doit être interrogé souvent, la surcharge d'écriture dans une table de tas est évidemment justifiée.
Pour moi, un fichier CSV composé d'un tas d'ID et de rien d'autre ressemble à des données transitoires et correspond au cas d'utilisation des tables externes. Mais le PO peut avoir des exigences supplémentaires qu'ils n'ont pas mentionnées.
Voici une approche alternative qui ne nécessite pas la création d'objets de base de données permanents. Par conséquent, il est moins élégant et sera probablement moins performant.
Il lit laborieusement le fichier CSV en utilisant UTL_FILE et remplit une collection basée sur SYSTEM.NUMBER_TBL_TYPE, une collection prédéfinie (table imbriquée de NUMBER) qui devrait être disponible dans votre base de données 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;
Remarque :je n'ai pas testé ce code. Le principe est solide mais les détails peuvent nécessiter un débogage;)