web-dev-qa-db-ja.com

PLSQLではORA-00980シノニム変換は無効になりました

SQLでデータベースリンクを介してアクセスできるリモートOracleデータベースにシノニムがあります。たとえば、

insert into my_table select * from my_synonym@my_database_link;

上記のステートメントをPLSQLブロックに入れると、コンパイルされず、エラーメッセージ「ORA-00980:シノニムの変換が無効になりました」が表示されます。標準的な説明は、シノニムが指すテーブルが削除されたなどですが、SQLでステートメントが機能するため、これは当てはまりません。

9
D Veloper

手伝ってくれた皆さん、ありがとうございました。これはOracleの制限であることが判明しました。

https://support.Oracle.com/rs?type=doc&id=453754.1

に適用されます:

PL/SQL-バージョン9.2.0.8以降このドキュメントの情報は、すべてのプラットフォームに適用されます。 2015年4月1日に関連性がチェックされました

症状

PL/SQLブロックが次のエラーで失敗する:ORA-00980:リモートデータベースからデータを選択すると、シノニム変換が無効になります。次のコードは、この問題を示しています。

DB3で(テーブルを作成)

CONNECT u3/u3 DROP TABLEタブ。 CREATE TABLE tab(c1 number);タブの値に挿入(1);コミット;

DB2の場合(DB3のテーブルの同義語を作成)

CONNECT u2/u2 DROP DATABASE LINK dblink2; 'EMT102U6'を使用してu3によって識別されるu3に接続するデータベースリンクdblink2の接続を作成します。 SELECT * FROM global_name @ dblink2; DROP SYNONYM syn2; CREATE SYNONYM syn2 FOR tab @ dblink2; SELECT * FROM syn2;

DB1で(DB2のシノニムにシノニムを作成)

CONNECT u1/u1 DROP DATABASE LINK dblink1; 'EMT102W6'を使用してu2によって識別されるu2に接続するデータベースリンクdblink1の接続を作成します。 SELECT * FROM global_name @ dblink1; DROP SYNONYM syn1; syn2 @ dblink1のSYNONYM syn1を作成します。 syn1からc1を選択します。

これはSQLでは機能しますが、PL/SQLから呼び出されると失敗します

DECLARE num NUMBER; BEGIN SELECT c1 INTO num FROM syn1;終わり; /

4行目のエラー:ORA-06550:4行目、3列目:PL/SQL:ORA-00980:同義語の変換は無効ですORA-06550:4行目、3列目:PL/SQL:SQLステートメントは無視されました

原因

この問題は、バグ2829591の9I-> 8I-> 7.3.4、GETTING ORA-980でのPL/SQLプロシージャからのクエリで報告されています。このバグは、次の理由により「NOT A BUG」としてクローズされました

PL/SQLは、コンパイルフェーズ中にデータベースリンクをたどるように中間データベース(DB2)に指示できません。したがって、このPL/SQLブロックをコンパイルして実行するには、データベースリンクdblink1とdblink2の両方をフロントエンドデータベース-DB1で定義する必要があります。実行時にデータベースリンク中に、dblink2が期待どおりにDB2で検索されます。

解決

ソリューションを実装するには、次の手順を実行してください。

  1. DB3を指すDB1にデータベースリンクdblink2を作成します。

SQL>データベースリンクを作成dblink2 'EMT102U6'を使用して、u3によって識別されるu3に接続します。

  1. DB1でPL/SQLブロックを作成してコンパイルします。

'EMT102U6'を使用してu3によって識別されるu3に接続するデータベースリンクdblink2の接続を作成します。

SELECT * FROM global_name @ dblink2; DECLARE num NUMBER;ベギン
SELECT c1 INTO num FROM syn1;終わり;/PL/SQLプロシージャが正常に完了しました。

ヒント:別のオプションは、PL/SQLブロックで動的SQLを使用することです。動的SQLを使用する場合、データベースリンクはコンパイル時ではなく実行時に解決されます。

2
D Veloper

何かがSQLでは機能するがPL/SQLでは機能しない場合、ほとんどの場合、これは特権の問題です。

PL/SQLブロックに入ると、ユーザーがroleを介して受け取った特権はアクティブになりません。したがって、おそらく、基になるテーブルに対するSELECT特権はロールを通じて付与されたため、PL/SQLブロックでは「アクティブ」ではありません。

これに対する通常の解決策は、ロールではなく、ユーザーに直接権限を付与することです。

回避策は、代わりにOracleビューを使用することです。

CREATE VIEW v_my_synomym as (select * from my_synonym@my_database_link);

次に、パッケージまたはプロシージャでビューを参照します。

insert into my_table select * from v_my_synonym;
0
Abdul Majid

「my_synonym」のリモートデータベース許可をチェックインすると、接続文字列で使用するユーザーのほとんどが「選択」である必要があります。この同義語が指すオブジェクトもチェックしてください(おそらく誰かがテーブルを削除した)。

0
NavyPier

テーブル/ビュー/プロシージャの所有者がSYNONYMに記載されている所有者と一致しない場合、この問題が見つかりました。

例:テーブルTABLE_BRACHの所有者がownerAで、シノニムで言及されているテーブル所有者が別の場合(ownerAではない)。

解決策:1. SYNONYMを削除します。2.正しい所有者で同じ名前で作成します。

CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;
0
Md. Kamruzzaman