Rechercher dans une base de données Oracle des tables avec des noms de colonnes spécifiques?

94

Nous avons une grande base de données Oracle avec de nombreuses tables. Existe-t-il un moyen d'interroger ou de rechercher s'il existe des tables avec certains noms de colonnes?

IE montre-moi toutes les tables qui ont les colonnes: id, fname, lname, address

Détail que j'ai oublié d'ajouter: je dois pouvoir rechercher dans différents schémas. Celui que je dois utiliser pour me connecter ne possède pas les tables que je dois parcourir.

David Oneill
la source

Réponses:

198

Pour rechercher toutes les tables avec une colonne particulière:

select owner, table_name from all_tab_columns where column_name = 'ID';

Pour rechercher des tables contenant une ou toutes les 4 colonnes:

select owner, table_name, column_name
from all_tab_columns
where column_name in ('ID', 'FNAME', 'LNAME', 'ADDRESS');

Pour rechercher des tables contenant les 4 colonnes (aucune ne manque):

select owner, table_name
from all_tab_columns
where column_name in ('ID', 'FNAME', 'LNAME', 'ADDRESS')
group by owner, table_name
having count(*) = 4;
Tony Andrews
la source
2
Vous devriez probablement utiliser DBA_TAB_COLUMNS au lieu de ALL_TAB_COLUMNS pour effectuer cette recherche, au cas où l'utilisateur auquel vous vous connectez n'a pas accès à certaines tables.
Jeffrey Kemp
Vrai, mais uniquement si l'utilisateur auquel vous êtes connecté dispose du privilège SELECT ANY TABLE.
Tony Andrews
2
Ajoutez column_name+ likesi vous n'êtes pas sûr du nom exact:select owner, table_name, column_name from all_tab_columns where column_name like 'someField%';
Mike R
10

Les données souhaitées se trouvent dans le tableau de métadonnées "cols":

SELECT * FROM COLS WHERE COLUMN_NAME = 'id'

Celui-ci vous donnera une liste de tables contenant toutes les colonnes souhaitées:

select distinct
  C1.TABLE_NAME
from
  cols c1
  inner join
  cols c2
  on C1.TABLE_NAME = C2.TABLE_NAME
  inner join
  cols c3
  on C2.TABLE_NAME = C3.TABLE_NAME
  inner join
  cols c4
  on C3.TABLE_NAME = C4.TABLE_NAME  
  inner join
  tab t
  on T.TNAME = C1.TABLE_NAME
where T.TABTYPE = 'TABLE' --could be 'VIEW' if you wanted
  and upper(C1.COLUMN_NAME) like upper('%id%')
  and upper(C2.COLUMN_NAME) like upper('%fname%')
  and upper(C3.COLUMN_NAME) like upper('%lname%')
  and upper(C4.COLUMN_NAME) like upper('%address%')  

Pour ce faire dans un schéma différent, spécifiez simplement le schéma devant la table, comme dans

SELECT * FROM SCHEMA1.COLS WHERE COLUMN_NAME LIKE '%ID%';

Si vous souhaitez combiner les recherches de nombreux schémas en un seul résultat de sortie, vous pouvez le faire:

SELECT DISTINCT
  'SCHEMA1' AS SCHEMA_NAME
 ,TABLE_NAME
FROM SCHEMA1.COLS
WHERE COLUMN_NAME LIKE '%ID%'
UNION
SELECT DISTINCT
  'SCHEMA2' AS SCHEMA_NAME
 ,TABLE_NAME
FROM SCHEMA2.COLS
WHERE COLUMN_NAME LIKE '%ID%'
JosephStyons
la source
Comment utiliser cela pour regarder un schéma différent? (J'ai oublié de mentionner cette demande dans ma question initiale)
David Oneill
Ajoutez simplement le nom du schéma au début de chaque nom de table ... c'est-à-dire myschema.c1. De toute évidence, vous devez avoir certains privilèges sur l'autre schéma
wadesworld
SELECT * FROM COLSne renvoie rien de mon schéma. Je n'ai que certains privilèges sur les tables. La sélection ne suffirait-elle pas pour me permettre de l'afficher via COLS?
David Oneill
select * from schema1.colsme donne une table or view does not existerreur. Cela aurait-il à voir avec la façon dont les privilèges sont établis?
David Oneill
Oui, ça le ferait. Il semble que la réponse de Tony Andrew soit probablement meilleure pour votre situation. J'avais oublié la vue "all_tab_columns".
JosephStyons
10

Pour rechercher un nom de colonne, utilisez la requête ci-dessous si vous connaissez le nom de colonne avec précision:

select owner,table_name from all_tab_columns where upper(column_name) =upper('keyword');

Pour rechercher un nom de colonne si vous ne connaissez pas la colonne précise, utilisez ci-dessous:

select owner,table_name from all_tab_columns where upper(column_name) like upper('%keyword%');
utilisateur3141191
la source
0

En voici un que nous avons sauvegardé dans findcol.sql afin que nous puissions l'exécuter facilement à partir de SQLPlus

set verify off
clear break
accept colnam prompt 'Enter Column Name (or part of): '
set wrap off
select distinct table_name, 
                column_name, 
                data_type || ' (' || 
                decode(data_type,'LONG',null,'LONG RAW',null,
                       'BLOB',null,'CLOB',null,'NUMBER',
                       decode(data_precision,null,to_char(data_length),
                              data_precision||','||data_scale
                             ), data_length
                      ) || ')' data_type
  from all_tab_columns
 where column_name like ('%' || upper('&colnam') || '%');
set verify on
Doug Porter
la source