1. ホーム
  2. oracle

[解決済み] ORA-00980 PLSQL で同義語の翻訳が有効でなくなった。

2022-02-12 09:28:23

質問

リモートOracleデータベースにシノニムを持っていて、データベースリンクを介してSQLでアクセスすることができます。

insert into my_table select * from my_synonym@my_database_link;

上記のステートメントをPLSQLブロックに入れると、エラーメッセージ "ORA-00980: synonym translation is no longer valid" を出して、コンパイルできません。標準的な説明は、同義語が指すテーブルが削除されたなどですが、このステートメントは SQL で動作するため、このようなことは起こりません。

解決方法は?

ご協力いただいた皆様、ありがとうございました。これは、Oracleの制限であることが判明しました。

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

に適用されます。

PL/SQL - バージョン 9.2.0.8 以降 この文書に記載されている情報 は、どのプラットフォームにも適用されます。 関連性チェック日:01-Apr-2015

症状

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

DB3の場合(テーブルを作成する)

CONNECT u3/u3 DROP TABLE tab; CREATE TABLE tab(c1 number); INSERT INTO tab VALUES (1); COMMIT;

DB2上(DB3上のテーブルのシノニム作成)

CONNECT u2/u2 DROP DATABASE LINK dblink2; CREATE DATABASE LINK dblink2 CONNECT TO u3 IDENTIFIED BY u3 USING 'EMT102U6'; 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; CREATE DATABASE LINK dblink1 CONNECT TO u2 IDENTIFIED BY u2 USING 'EMT102W6'; SELECT *. FROM global_name@dblink1; DROP SYNONYM syn1; CREATE SYNONYM syn1 FOR syn2@dblink1; SELECT c1 from syn1;

これはSQLでは動作しますが、PL/SQLから呼び出すと失敗します。

DECLARE num NUMBER; BEGIN SELECT c1 INTO num FROM syn1; END; /

4 行目で ERROR が発生しました。 ORA-06550: 4行目、3列目: PL/SQLです。ORA-00980: 同義語変換は、もはや有効ではありません ORA-06550: 4行目、3列目。 PL/SQLです。SQLステートメントが無視されました。

原因

この問題はBug 2829591 PL/SQL 9I -> 8I-> 7.3.4 の PROCEDURE で、ORA-980 を取得しました。 このバグは 以下の理由により、「NOT A BUG」としています。

PL/SQLはミドルデータベース(DB2)に対して、データベースの追従を指示することができません。 リンクは、コンパイルフェーズで使用されます。したがって、このPL/SQLを使用するには ブロックがコンパイルされ実行されるには、データベースリンクdblink1とdblink2の両方が必要です。 はフロントエンド・データベースであるDB1上で定義される必要があります。 実行時に データベースリンク dblink2 は、予想通り DB2 で検索されます。

解決方法

解決策を実行するには、以下の手順を実行してください。

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

SQL> create database link dblink2 connect to u3 identified by u3 using. 'EMT102U6'です。

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

CREATE DATABASE LINK dblink2 CONNECT TO u3 IDENTIFIED BY u3 USING 'EMT102U6' です。

SELECT * FROM global_name@dblink2; DECLARE num NUMBER; BEGIN
SELECT c1 INTO num FROM syn1; END; / PL/SQLプロシージャが正常に実行されました。 が完了しました。

ヒント: 別の方法として、PL/SQLブロックの中でダイアンティックSQLを使用することもできます。 を回避することができます。動的SQLを使用する場合、データベースリンクは解決されません。 はコンパイル時ではなく、実行時に行われます。