¿Busca tablas con nombres de columna específicos en una base de datos Oracle?

95

Tenemos una gran base de datos Oracle con muchas tablas. ¿Hay alguna forma de que pueda consultar o buscar para encontrar si hay tablas con ciertos nombres de columna?

Es decir, muéstrame todas las tablas que tienen las columnas: id, fname, lname, address

Detalle que olvidé agregar: necesito poder buscar en diferentes esquemas. El que debo usar para conectar no posee las tablas en las que necesito buscar.

David Oneill
fuente

Respuestas:

200

Para buscar todas las tablas con una columna en particular:

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

Para buscar tablas que tengan alguna o todas las 4 columnas:

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

Para buscar tablas que tengan las 4 columnas (sin falta ninguna):

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
fuente
2
Probablemente debería usar DBA_TAB_COLUMNS en lugar de ALL_TAB_COLUMNS para realizar esta búsqueda, en caso de que el usuario que está iniciando sesión no tenga acceso a algunas tablas.
Jeffrey Kemp
Es cierto, pero solo si el usuario con el que está conectado tiene el privilegio SELECT ANY TABLE.
Tony Andrews
2
Agregue column_name+ likesi no está seguro del nombre exacto:select owner, table_name, column_name from all_tab_columns where column_name like 'someField%';
Mike R
10

Los datos que desea están en la tabla de metadatos "cols":

SELECT * FROM COLS WHERE COLUMN_NAME = 'id'

Este le dará una lista de tablas que tienen todas las columnas que desea:

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 hacer esto en un esquema diferente, simplemente especifique el esquema delante de la tabla, como en

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

Si desea combinar las búsquedas de muchos esquemas en un resultado de salida, puede hacer esto:

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
fuente
¿Cómo utilizo esto para ver un esquema diferente? (Olvidé mencionar ese requisito en mi pregunta original)
David Oneill
Simplemente anteponga el nombre del esquema al frente de cada nombre de tabla ... es decir, myschema.c1. Obviamente, debe tener privilegios seleccionados en el otro esquema
wadesworld
SELECT * FROM COLSno devuelve nada de mi esquema. Solo tengo privilegios selectos en las mesas. ¿Seleccionar no sería suficiente para permitirme verlo a través de COLS?
David Oneill
select * from schema1.colsme da un table or view does not existerror. ¿Tendría eso que ver con cómo se configuran los privilegios?
David Oneill
Sí lo haría. Parece que la respuesta de Tony Andrew probablemente sea mejor para su situación. Me había olvidado de la vista "all_tab_columns".
JosephStyons
10

PARA buscar el nombre de una columna, utilice la siguiente consulta si conoce el nombre de la columna con precisión:

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

PARA buscar el nombre de una columna si no conoce la columna exacta, utilice a continuación:

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

Aquí hay uno que hemos guardado en findcol.sql para que podamos ejecutarlo fácilmente desde 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
fuente