Przeszukać bazę danych Oracle pod kątem tabel z określonymi nazwami kolumn?

95

Mamy dużą bazę danych Oracle z wieloma tabelami. Czy istnieje sposób wykonywania zapytań lub wyszukiwania, aby znaleźć tabele z określonymi nazwami kolumn?

IE pokaż mi wszystkie tabele, które mają kolumny: id, fname, lname, address

Zapomniałem dodać szczegół: muszę mieć możliwość przeszukiwania różnych schematów. Ten, którego muszę użyć do połączenia, nie jest właścicielem tabel, które muszę przeszukać.

David Oneill
źródło

Odpowiedzi:

201

Aby znaleźć wszystkie tabele z określoną kolumną:

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

Aby znaleźć tabele zawierające dowolną lub wszystkie z 4 kolumn:

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

Aby znaleźć tabele, które mają wszystkie 4 kolumny (bez żadnej):

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
źródło
2
Prawdopodobnie powinieneś użyć DBA_TAB_COLUMNS zamiast ALL_TAB_COLUMNS, aby przeprowadzić to wyszukiwanie, na wypadek, gdyby użytkownik, którego się logujesz, nie ma dostępu do niektórych tabel.
Jeffrey Kemp
Prawda, ale tylko wtedy, gdy użytkownik, z którym jesteś połączony, ma uprawnienie SELECT ANY TABLE.
Tony Andrews
2
Dodaj column_name+, likejeśli nie jesteś pewien dokładnej nazwy:select owner, table_name, column_name from all_tab_columns where column_name like 'someField%';
Mike R
10

Potrzebne dane znajdują się w tabeli metadanych „cols”:

SELECT * FROM COLS WHERE COLUMN_NAME = 'id'

Ten daje listę tabel, które mają wszystkie żądane kolumny:

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

Aby to zrobić w innym schemacie, po prostu określ schemat przed tabelą, jak w

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

Jeśli chcesz połączyć wyszukiwania wielu schematów w jeden wynik wyjściowy, możesz to zrobić:

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
źródło
Jak tego użyć, aby spojrzeć na inny schemat? (Zapomniałem wspomnieć o tym wymaganiu w moim pierwotnym pytaniu)
David Oneill
Po prostu umieść nazwę schematu na początku każdej nazwy tabeli ... tj. Myschema.c1. Oczywiście musisz mieć wybrane uprawnienia na innym schemacie
wadesworld
SELECT * FROM COLSnic nie zwraca z mojego schematu. Mam tylko wybrane uprawnienia przy stołach. Czy wybór nie byłby wystarczający, aby umożliwić mi wyświetlenie go za pośrednictwem COLS?
David Oneill
select * from schema1.colsdaje mi table or view does not existbłąd. Czy miałoby to związek z konfiguracją przywilejów?
David Oneill
Tak, będzie. Wygląda na to, że odpowiedź Tony'ego Andrew jest prawdopodobnie lepsza w twojej sytuacji. Zapomniałem o widoku „all_tab_columns”.
JosephStyons,
10

Aby wyszukać nazwę kolumny, użyj poniższego zapytania, jeśli znasz dokładną nazwę kolumny:

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

Aby wyszukać nazwę kolumny, jeśli nie znasz dokładnej kolumny, użyj poniżej:

select owner,table_name from all_tab_columns where upper(column_name) like upper('%keyword%');
user3141191
źródło
0

Oto jeden, który zapisaliśmy w findcol.sql, abyśmy mogli go łatwo uruchomić z poziomu 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
źródło