Search code examples
oracleplsqlsynonym

ORA-00980 synonym translation no longer valid in PLSQL


I've got a synonym on a remote Oracle database that I can access in SQL over a database link, eg,

insert into my_table select * from my_synonym@my_database_link;

If I put the above statement into a PLSQL block, it won't compile, giving the error message "ORA-00980: synonym translation is no longer valid". The standard explanation is the table that the synonym points to has been dropped, etc, but this is not the case because the statement works in SQL.


Solution

  • Thank you to everyone who tried to help. This turned out to be an Oracle limitation:

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

    APPLIES TO:

    PL/SQL - Version 9.2.0.8 and later Information in this document applies to any platform. Checked for relevance on 01-Apr-2015

    SYMPTOMS

    A PL/SQL block fails with error: ORA-00980: synonym translation is no longer valid, when selecting data from a remote database. The following code demonstrates this issue:

    On DB3 (create the table)

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

    On DB2 (create a synonym to the table on 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;

    On DB1 (create a synonym to the synonym on 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;

    This works in SQL but fails when called from PL/SQL

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

    ERROR at line 4: ORA-06550: line 4, column 3: PL/SQL: ORA-00980: synonym translation is no longer valid ORA-06550: line 4, column 3: PL/SQL: SQL Statement ignored

    CAUSE

    This issue was reported in Bug 2829591 QUERING FROM A PL/SQL PROCEDURE IN 9I -> 8I-> 7.3.4, GETTING ORA-980. This bug was closed as 'NOT A BUG' for the following reasons

    PL/SQL cannot instruct middle database (DB2) to follow the database link during the compilation phase. Therefore in order for this PL/SQL block to compile and run, both database links dblink1 and dblink2 should be defined on the front end database - DB1. During runtime database link dblink2 will be looked up in DB2 as expected.

    SOLUTION

    To implement the solution, please execute the following steps:

    1. Create a database link dblink2 on DB1 pointing to DB3

    SQL> create database link dblink2 connect to u3 identified by u3 using 'EMT102U6';

    1. Create and compile the PL/SQL block on DB1.

    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 procedure successfully completed.

    TIP: Another option is to use dyanmic SQL in the PL/SQL block as a work around. When using dynamic SQL the database link is not resolved at compile time but at runtime.