¿Cómo se valida de forma económica la existencia de una columna en una tabla en otro esquema con Oracle?

StackOverflow https://stackoverflow.com/questions/1646953

Pregunta

El entorno es Oracle 9 & amp; 10. No tengo acceso a nivel DBA.

El problema es verificar que existe una columna específica en una tabla específica, en otro esquema.

Hay dos casos para tratar.

  1. Otro esquema en la misma instancia
  2. Un esquema en una instancia diferente, usando un db_link

Dado mi esquema FRED y otro esquema BARNEY, intenté algo como esto

SELECT 1
FROM BARNEY.USER_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE' 
  AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'

Que produjo [1]: (Error): ORA-00942: la tabla o vista no existe

Después de vegging por un tiempo, me di cuenta de que USER_TAB_COLS, no es realmente una tabla. Es una vista. He estado seleccionando desde tablas todo el tiempo, pero no desde una vista.

Intenté lo mismo con mi db_link, y me sorprendió ver que los datos regresaban. Un db_link tiene un nombre / contraseña de esquema incorporado, por lo que me parece razonable que funcionó, ya que efectivamente se conecta al otro esquema, lo que debería hacer que las vistas sean accesibles.

Habiendo buscado en Google y agotado mis ojos en la montaña de Oracle doc, Estoy buscando a alguien que me señale en la dirección correcta, o al menos señale lo que me falta.

¿Qué técnicas están disponibles para obtener metadatos relacionados con la tabla de usuario de un esquema en la misma instancia para validar que existe una columna específica?

Gracias de antemano.

Mal.

+1 para buenas respuestas. Gracias.

¿Fue útil?

Solución

Al igual que con las otras respuestas, normalmente uso ALL_TAB_COLUMNS para una consulta como esta. Pero eso solo mostrará columnas en las tablas donde tiene SELECT. Y se selecciona en esa columna: en el improbable caso de que hayan implementado privilegios a nivel de columna para esa tabla, es posible que pueda ver la tabla, pero no ver la columna específica de interés. Para la mayoría de nosotros, eso es extremadamente raro.

DBA_TAB_COLUMNS mostrará todas las columnas, pero tendrá que seleccionar en su esquema otorgado por su DBA. (En realidad, necesitará una subvención en ALL_TAB_COLUMNS para usarlo, pero eso es común en la mayoría de las tiendas). El paquete incorporado DBMS_METADATA PL / SQL también se puede utilizar, con limitaciones similares, pero creo que lo encontrará más complicado.

Por supuesto, también puede intentar seleccionar un registro de barney.some_table.some_column@my_dblink (o cualquier parte de eso que le interese). Y luego maneja la excepción. Feo, no lo recomendaría en la mayoría de las situaciones.

Otros consejos

Puede usar la siguiente consulta:

SELECT 1
FROM ALL_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE' 
  AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
  AND OWNER = 'BARNEY';

(User_Tables y User_Tab_Cols son solo vistas en all_tables y all_tab_coumns con un where owner = <Current User> adjunto)

Si se le permite ver la tabla_algo de Barney (es decir, se le OTORGÓ al menos privilegios SELECT), entonces sabrá si la columna está allí. Si no tiene derechos sobre la tabla, no podrá obtener metainformación sobre ella.

Usaría all_tab_columns para eso.

Pero tenga cuidado de que solo verá lo que puede ver.

Misma instancia, esquema diferente:

Select Count(*)
From   all_tab_cols
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';

El recuento (*) tiene la ventaja de devolver siempre una sola fila con un valor de 1 o 0, por lo que no tiene que lidiar con NO_DATA_FOUND errores en PL / SQL.

A través de un enlace de base de datos, el mismo esquema que el que conecta:

Select Count(*)
From   user_tab_cols@MY_DB_LINK
Where  table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';

A través de un enlace de base de datos, esquema diferente al que se conecta como:

Select Count(*)
From   all_tab_cols@MY_DB_LINK
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top