Oracleを使用して、別のスキーマのテーブルの列の存在をどのように安価に検証しますか?
-
22-07-2019 - |
質問
環境はOracle 9 <!> ampです。 10. DBAレベルのアクセス権がありません。
問題は、特定の列が別のスキーマの特定のテーブルに存在することを確認することです。
対処すべきケースは2つあります。
- 同じインスタンス内の別のスキーマ
- db_linkを使用した、異なるインスタンスのスキーマ
スキーマFREDと別のスキーマBARNEYを指定して、次のようなものを試しました
SELECT 1
FROM BARNEY.USER_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE'
AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
生成された [1]:(エラー):ORA-00942:テーブルまたはビューが存在しません
これについてしばらく考えた後、USER_TAB_COLSは実際にはテーブルではないことに気付きました。ビューです。私はずっとテーブルから選択していますが、ビューからは選択していません。
db_linkで同じことを試してみましたが、データが戻ってくるのを見て驚きました。 db_linkにはschema_name / passwordが埋め込まれているので、他のスキーマに効果的にログインし、ビューに到達できるようになったため、機能したことは理にかなっているようです。
オラクルの山の山でグーグル検索をして、眼球をすり減らせて、 正しい方向に向けてくれる人を探しているか、少なくとも足りないものを指摘してください。
特定の列が存在することを検証するために、同じインスタンス内のスキーマからユーザーテーブル関連のメタデータを取得するために利用できるテクニックは何ですか?
事前に感謝します。
悪。
良い答えを得るには+1。 ありがとう。
解決
他の返信と同様に、通常、このようなクエリにはALL_TAB_COLUMNSを使用します。ただし、SELECTがあるテーブルの列のみが表示されます。そして、その列で選択されます-そのテーブルに列レベルの特権を実装したというまれなイベントでは、テーブルは表示できますが、目的の特定の列は表示されません。私たちのほとんどにとって、それは非常にまれです。
DBA_TAB_COLUMNSにはすべての列が表示されますが、DBAによってスキーマに付与された列を選択する必要があります。 (実際には、ALL_TAB_COLUMNSで使用するには許可が必要ですが、それはほとんどのショップで一般的です)。 DBMS_METADATA PL / SQLビルトインパッケージも使用できますが、同様の制限がありますが、より複雑になると思います。
もちろん、barney.some_table.some_column @ my_dblink(または興味のあるもの)からレコードを選択することもできます。そして、例外を処理します。 glyい、私はほとんどの状況でそれをお勧めしません。
他のヒント
次のクエリを使用できます。
SELECT 1
FROM ALL_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE'
AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
AND OWNER = 'BARNEY';
(User_TablesおよびUser_Tab_Colsは、all_tablesおよびall_tab_coumnsの単なるビューであり、where owner = <Current User>
が付加されています)
Barneyのsome_tableの表示が許可されている場合(つまり、少なくともSELECT権限が付与されている場合)、列が存在するかどうかがわかります。テーブルに対する権限がない場合、メタ情報を取得できません。
そのためにはall_tab_columnsを使用します。
ただし、表示が許可されているもののみが表示されることに注意してください。
同じインスタンス、異なるスキーマ:
Select Count(*)
From all_tab_cols
Where owner = 'BARNEY' and
table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';
count(*)には、常に1または0の値を持つ単一の行が返されるという利点があるため、PL / SQLでNO_DATA_FOUND
エラーを処理する必要はありません。
DBリンクを介して、接続先と同じスキーマ:
Select Count(*)
From user_tab_cols@MY_DB_LINK
Where table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';
DBリンク全体で、接続するスキーマとは異なるスキーマ:
Select Count(*)
From all_tab_cols@MY_DB_LINK
Where owner = 'BARNEY' and
table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';