Suchen Sie in einer Oracle-Datenbank nach Tabellen mit bestimmten Spaltennamen?

94

Wir haben eine große Oracle-Datenbank mit vielen Tabellen. Gibt es eine Möglichkeit, nachzufragen oder zu suchen, ob Tabellen mit bestimmten Spaltennamen vorhanden sind?

IE zeigt mir alle Tabellen, die die Spalten haben: id, fname, lname, address

Detail, das ich vergessen habe hinzuzufügen: Ich muss in der Lage sein, verschiedene Schemata zu durchsuchen. Diejenige, die ich zum Verbinden verwenden muss, besitzt nicht die Tabellen, die ich durchsuchen muss.

David Oneill
quelle

Antworten:

197

So finden Sie alle Tabellen mit einer bestimmten Spalte:

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

So finden Sie Tabellen mit einer oder allen der 4 Spalten:

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

So finden Sie Tabellen mit allen 4 Spalten (wobei keine fehlt):

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
quelle
2
Sie sollten wahrscheinlich DBA_TAB_COLUMNS anstelle von ALL_TAB_COLUMNS verwenden, um diese Suche durchzuführen, falls der Benutzer, bei dem Sie sich anmelden, keinen Zugriff auf einige Tabellen hat.
Jeffrey Kemp
True, aber nur, wenn der Benutzer, mit dem Sie verbunden sind, über die Berechtigung SELECT ANY TABLE verfügt.
Tony Andrews
2
Fügen Sie column_name+ hinzu, likewenn Sie sich über den genauen Namen nicht sicher sind:select owner, table_name, column_name from all_tab_columns where column_name like 'someField%';
Mike R
10

Die gewünschten Daten befinden sich in der Metadatentabelle "cols":

SELECT * FROM COLS WHERE COLUMN_NAME = 'id'

Diese gibt Ihnen eine Liste von Tabellen, die alle gewünschten Spalten enthalten:

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%')  

Um dies in einem anderen Schema zu tun, geben Sie einfach das Schema vor der Tabelle an, wie in

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

Wenn Sie die Suche vieler Schemas zu einem Ausgabeergebnis kombinieren möchten, können Sie Folgendes tun:

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
quelle
Wie verwende ich dies, um ein anderes Schema zu betrachten? (Ich habe vergessen, diese Anforderung in meiner ursprünglichen Frage zu erwähnen)
David Oneill
Stellen Sie einfach den Schemanamen vor jeden Tabellennamen ... dh myschema.c1. Offensichtlich müssen Sie ausgewählte Berechtigungen für das andere Schema haben
wadesworld
SELECT * FROM COLSgibt nichts von meinem Schema zurück. Ich habe nur ausgewählte Berechtigungen für die Tabellen. Würde die Auswahl nicht ausreichen, um sie über COLS anzeigen zu können?
David Oneill
select * from schema1.colsgibt mir einen table or view does not existFehler. Hätte das damit zu tun, wie die Berechtigungen eingerichtet werden?
David Oneill
Ja es würde. Es scheint, als ob Tony Andrews Antwort wahrscheinlich besser für Ihre Situation ist. Ich hatte die Ansicht "all_tab_columns" vergessen.
JosephStyons
10

Um einen Spaltennamen zu suchen, verwenden Sie die folgende Abfrage, wenn Sie den Spaltennamen genau kennen:

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

So suchen Sie einen Spaltennamen, wenn Sie die genaue Spaltenverwendung unten nicht kennen:

select owner,table_name from all_tab_columns where upper(column_name) like upper('%keyword%');
user3141191
quelle
0

Hier ist eine, die wir in findcol.sql gespeichert haben, damit wir sie problemlos in SQLPlus ausführen können

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
quelle