par , 15/10/2017 à 21h55 (1508 Affichages)
En aparté, nous sommes bien d'accord : un modèle de donnée est censé être connu et maîtrisé.
Cependant,il peut arriver que l'on se retrouve avec une application dont le modèle nous est inconnu... Aller à la pêche à l'information peut alors être utile.
J'ai écrit le petit bout de code suivant qui permet de retrouver une chaîne de caractères quelconque dans toute une base Oracle.
ATTENTION : cela va générer un tablescan sur une grande quantité de tables, ce qui pourrait mettre à mal les performances de votre base.
Veillez donc à n'utiliser ce type de script que pendant les périodes creuses ET sur une copie de la base de production (et pas la base de production elle-même.)
Plus la chaîne recherche sera longue est plus la recherche sera rapide.
Si vous recherchez une chaîne exacte (donc sans caractères jocker), les performances s'en retrouverons amélioriées.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| declare
s_lstCol varchar2(4000) ;
s_sql varchar2(4000) ;
s_filtre varchar2(3000) ;
s_nombre integer ;
s_taille integer ;
s_like integer ;
begin
-- déterminiation de la chaîne à trouver
s_filtre := '%Un bout de chaîne à rechercher%' ;
s_taille := length(s_filtre) ;
s_like := instr(s_filtre,'%')+instr(s_filtre,'_') ;
-- recherche des tables ayant une colonne de type caractères
for tb in (select distinct owner, table_name, data_type from all_tab_columns where owner not in ('SYS','SYSTEM','XDB') and (data_type like '%CHAR%' or data_type='CLOB') and DATA_LENGTH >= s_taille)
loop
dbms_output.put_line ('Traitement de '||tb.owner||'.'||tb.table_name);
s_lstCol := '1=2' ;
-- recherche, pour chaque table, de la liste des colonnes
for col in (select column_name from all_tab_columns where owner=tb.owner and data_type=tb.data_type and tb.table_name=table_name)
loop
if s_like = 0 then
s_lstCol := s_lstCol ||' OR '|| col.column_name||' = '''||s_filtre||'''' ;
else
s_lstCol := s_lstCol ||' OR '|| col.column_name||' LIKE '''||s_filtre||'''' ;
end if ;
end loop ;
s_sql := 'select count(*) from '||tb.owner||'.'||tb.table_name ||' where '||s_lstCol ;
execute immediate s_sql into s_nombre ;
if s_nombre > 0 then
dbms_output.put_line('Valeur trouvée '||s_nombre||' fois dans '||tb.owner||'.'||tb.table_name);
end if ;
end loop ;
end ;
/ |