Comment valider à moindre coût l’existence d’une colonne dans une table d’un autre schéma avec Oracle?

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

Question

L’environnement est Oracle 9 & amp; 10. Je n'ai pas accès au niveau DBA.

Le problème est de vérifier qu’une colonne spécifique existe dans une table spécifique, dans un autre schéma.

Il y a deux cas à traiter.

  1. Un autre schéma dans la même instance
  2. Un schéma dans une instance différente, à l'aide d'un lien_base

Étant donné mon schéma FRED et un autre schéma BARNEY, j'ai essayé quelque chose comme ceci

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

Qui a généré [1]: (erreur): ORA-00942: la table ou la vue n'existe pas

Après avoir vegging sur ce moment, j'ai réalisé que USER_TAB_COLS, n'est pas vraiment une table. C'est une vue. Je sélectionne depuis toujours dans les tables, mais pas dans une vue.

J'ai essayé la même chose avec mon db_link et j'ai été surpris de voir les données revenir. Un lien_bdd contient un nom_schéma / un mot de passe incorporé; il me semble donc raisonnable que cela fonctionne, car il se connecte effectivement à l'autre schéma, ce qui devrait rendre les vues accessibles.

Ayant googlé autour de moi et ayant épuisé mes yeux sur la montagne de doc Oracle, Je cherche quelqu'un pour me diriger dans la bonne direction, ou au moins signaler ce qui me manque.

Quelles techniques sont disponibles pour obtenir des métadonnées liées à la table utilisateur à partir d'un schéma dans la même instance afin de valider l'existence d'une colonne spécifique?

Merci d'avance.

Mal.

+1 pour de bonnes réponses. Merci.

Était-ce utile?

La solution

Comme pour les autres réponses, j'utilise normalement ALL_TAB_COLUMNS pour une requête comme celle-ci. Mais cela ne montrera que les colonnes des tables sur lesquelles vous avez SELECT. Et il est choisi sur cette colonne - dans le cas improbable où ils auraient implémenté des privilèges de niveau colonne pour cette table, vous pourrez peut-être voir la table, mais pas la colonne spécifique qui vous intéresse. Pour la plupart d'entre nous, c'est extrêmement rare.

DBA_TAB_COLUMNS affichera toutes les colonnes, mais vous devrez sélectionner sur celui-ci attribué à votre schéma par votre administrateur de base de données. (En fait, vous aurez besoin d'une subvention sur ALL_TAB_COLUMNS pour l'utiliser, mais c'est courant dans la plupart des magasins). Le package intégré DBMS_METADATA PL / SQL peut également être utilisé, avec des limitations similaires, mais je pense que vous le trouverez plus compliqué.

Bien sûr, vous pouvez également simplement essayer de sélectionner un enregistrement dans barney.some_table.some_column@my_dblink (ou tout élément de ce qui vous intéresse). Et puis gérer l'exception. Moche, je ne le recommanderais pas dans la plupart des situations.

Autres conseils

Vous pouvez utiliser la requête suivante:

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

(User_Tables et User_Tab_Cols sont juste des vues sur all_tables et all_tab_coumns avec un where owner = <Current User> attaché à celui-ci)

Si vous êtes autorisé à voir la table some_table de Barney (c'est-à-dire que vous avez obtenu au moins les privilèges SELECT sur celui-ci), vous saurez si la colonne est là. Si vous n'avez aucun droit sur la table, vous ne pourrez pas obtenir de méta-information dessus.

Vous utiliseriez all_tab_columns pour cela.

Mais attention, vous ne verrez que ce que vous êtes autorisé à voir.

Même instance, schéma différent:

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

Le nombre (*) présente l'avantage de toujours renvoyer une seule ligne avec une valeur égale à 1 ou à 0, de sorte que vous n'avez pas à traiter les NO_DATA_FOUND erreurs dans PL / SQL.

Sur un lien de base de données, même schéma que celui auquel vous vous connectez en tant que:

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

Sur un lien de base de données, un schéma différent de celui que vous connectez en tant que:

Select Count(*)
From   all_tab_cols@MY_DB_LINK
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top