Pesquisar um banco de dados Oracle para tabelas com nomes de coluna específicos?

94

Temos um grande banco de dados Oracle com muitas tabelas. Existe uma maneira de consultar ou pesquisar para descobrir se há alguma tabela com determinados nomes de coluna?

O IE mostra-me todas as tabelas que possuem as colunas: id, fname, lname, address

Detalhe que esqueci de acrescentar: preciso ser capaz de pesquisar em diferentes esquemas. O que devo usar para conectar não possui as tabelas que preciso pesquisar.

David Oneill
fonte

Respostas:

198

Para encontrar todas as tabelas com uma coluna específica:

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

Para encontrar tabelas que tenham uma ou todas as 4 colunas:

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

Para encontrar tabelas com todas as 4 colunas (sem nenhuma faltando):

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
fonte
2
Você provavelmente deve usar DBA_TAB_COLUMNS ao invés de ALL_TAB_COLUMNS para fazer esta pesquisa, caso o usuário com o qual você está se autenticando não tenha acesso a algumas tabelas.
Jeffrey Kemp
Verdadeiro, mas apenas se o usuário ao qual você está conectado tiver o privilégio SELECT ANY TABLE.
Tony Andrews
2
Adicione column_name+ likese não tiver certeza do nome exato:select owner, table_name, column_name from all_tab_columns where column_name like 'someField%';
Mike R
10

Os dados que você deseja estão na tabela de metadados "cols":

SELECT * FROM COLS WHERE COLUMN_NAME = 'id'

Este lhe dará uma lista de tabelas que têm todas as colunas que você deseja:

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

Para fazer isso em um esquema diferente, basta especificar o esquema na frente da tabela, como em

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

Se quiser combinar as pesquisas de muitos esquemas em um resultado de saída, você pode fazer isso:

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
fonte
Como faço para usar isso para ver um esquema diferente? (Esqueci de mencionar essa solicitação na minha pergunta original)
David Oneill
Basta anexar o nome do esquema na frente de cada nome de tabela ... ou seja, myschema.c1. Obviamente, você deve selecionar privilégios no outro
esquema
SELECT * FROM COLSnão retorna nada do meu esquema. Eu só tenho privilégios selecionados nas tabelas. A seleção não seria suficiente para permitir a visualização via COLS?
David Oneill
select * from schema1.colsme dá um table or view does not existerro. Isso teria a ver com a forma como os privilégios são configurados?
David Oneill
Sim, seria. Parece que a resposta de Tony Andrew é provavelmente melhor para sua situação. Eu tinha esquecido da visão "all_tab_columns".
JosephStyons
10

PARA pesquisar um nome de coluna, use a consulta abaixo se você souber o nome da coluna com precisão:

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

PARA pesquisar um nome de coluna, se você não souber a coluna exata, use a seguir:

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

Aqui está um que salvamos em findcol.sql para que possamos executá-lo facilmente de dentro do 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
fonte