Come si può validare a buon mercato l'esistenza di una colonna in una tabella in un altro schema con Oracle?

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

Domanda

L'ambiente è Oracle 9 & amp; 10. Non ho accesso al livello DBA.

Il problema è verificare l'esistenza di una colonna specifica in una tabella specifica, in un altro schema.

Ci sono due casi da affrontare.

  1. Un altro schema nella stessa istanza
  2. Uno schema in un'istanza diversa, usando un db_link

Dato il mio schema FRED e un altro schema BARNEY, ho provato qualcosa del genere

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

Che ha prodotto [1]: (Errore): ORA-00942: la tabella o la vista non esiste

Dopo averlo cercato per un po ', mi sono reso conto che USER_TAB_COLS, in realtà non è un tavolo. È una vista. Ho sempre selezionato dalle tabelle, ma non da una vista.

Ho provato la stessa cosa con il mio db_link e sono rimasto sorpreso nel vedere i dati tornare. Un link_db ha un nome / password schema incorporato, quindi mi sembra ragionevole che abbia funzionato, poiché accede effettivamente all'altro schema, il che dovrebbe rendere le visualizzazioni raggiungibili.

Avendo cercato su Google e sfinito i miei occhi sulla montagna di Oracle doc, Sto cercando qualcuno che mi indichi nella direzione corretta, o almeno sottolinei cosa mi sto perdendo.

Quali tecniche sono disponibili per ottenere metadati correlati alla tabella utente da uno schema nella stessa istanza al fine di convalidare l'esistenza di una colonna specifica?

Grazie in anticipo.

Il male.

+1 per buone risposte. Grazie.

È stato utile?

Soluzione

Come per le altre risposte, normalmente utilizzo ALL_TAB_COLUMNS per una query come questa. Ma questo mostrerà solo le colonne nelle tabelle in cui hai SELEZIONA. Ed è selezionato su quella colonna: nel caso improbabile che abbiano implementato i privilegi a livello di colonna per quella tabella, potresti essere in grado di vedere la tabella, ma non vedere la colonna specifica di interesse. Per la maggior parte di noi, è estremamente raro.

DBA_TAB_COLUMNS mostrerà tutte le colonne, ma dovrai selezionarne una concessa al tuo schema dal tuo DBA. (In realtà, avrai bisogno di una sovvenzione su ALL_TAB_COLUMNS per usarlo, ma è comune nella maggior parte dei negozi). Il pacchetto integrato DBMS_METADATA PL / SQL può anche essere utilizzato, con limitazioni simili, ma penso che lo troverai più complicato.

Ovviamente, puoi anche provare a selezionare un record da barney.some_table.some_column@my_dblink (o qualsiasi altra cosa ti interessi). E quindi gestire l'eccezione. Brutto, non lo consiglierei nella maggior parte delle situazioni.

Altri suggerimenti

È possibile utilizzare la seguente query:

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

(User_Tables e User_Tab_Cols sono solo visualizzazioni su all_tables e all_tab_coumns con un where owner = <Current User> allegato)

Se ti è permesso di vedere some_table di Barney (cioè se ti sono stati concessi almeno i privilegi SELECT su di esso), allora saprai se la colonna è lì. Se non hai diritti sul tavolo, non sarai in grado di ottenere meta informazioni su di esso.

Per questo useresti all_tab_columns.

Ma attenzione che vedrai solo ciò che ti è permesso vedere.

Stessa istanza, schema diverso:

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

Il conteggio (*) ha il vantaggio di restituire sempre una singola riga con un valore di 1 o 0, quindi non è necessario gestire NO_DATA_FOUND errori in PL / SQL.

Attraverso un DB Link, stesso schema di quello a cui ti connetti:

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

Attraverso un DB Link, schema diverso da quello a cui ti connetti come:

Select Count(*)
From   all_tab_cols@MY_DB_LINK
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top