14

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.

D Veloper
  • 171
  • 1
  • 1
  • 6
  • Ask Tom has an entry on this topic with scenarios similar to yours here, https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:7095288486502 – Patrick Bacon Aug 03 '15 at 17:33
  • Good addition to the answers below (from Burleson Consulting) : http://www.dba-oracle.com/sf_ora_00980_synonym_translation_is_no_longer_valid.htm – Benj May 22 '18 at 13:45

5 Answers5

3

If something works in SQL but not in PL/SQL then in most cases this is a problem with privileges.

Any privilege that a user received through a role is not active when you enter a PL/SQL block. So most probably the SELECT privilege on the underlying table was granted through a role and thus is not "active" in the PL/SQL block.

The usual cure for this is to grant the privileges directly to the user, not through a role.

  • Thank you for answering my question, but in this particular case no grants are involved: my_synonym is accessed via the database link my_database_link. – D Veloper Aug 03 '15 at 14:59
  • 1
    @DVeloper: ... and the user that is stored in the DBLink needs grants to access the underlying table. –  Aug 03 '15 at 15:02
3

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.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
D Veloper
  • 171
  • 1
  • 1
  • 6
  • I think it is good/fine to cite the Oracle documentation, yet you should not copy its contents verbatim. Provide your own example. :) – Patrick Bacon Aug 06 '15 at 13:51
  • Good addition to this answer (from Burleson Consulting) : http://www.dba-oracle.com/sf_ora_00980_synonym_translation_is_no_longer_valid.htm – Benj May 22 '18 at 13:47
1

Workaround solution is to use an Oracle view instead.

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

Then reference the view in your package or procedure i.e.:

insert into my_table select * from v_my_synonym;
barbsan
  • 3,418
  • 11
  • 21
  • 28
0

Check in remote database grants for "my_synonym" must be almost "select" for the user you use in connect string, check also the object which this synonym points at (maybe someone deleted the table).

NavyPier
  • 45
  • 5
0

I found this issue when owner of the table/view/procedure are not match with owner mentioned in SYNONYM.

Example : If owner of table TABLE_BRACH is ownerA and in Synonym mentioned table owner is something else (Not ownerA).

Solution: 1. Drop the SYNONYM 2. Create that with same name with correct owner.

CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;
Md. Kamruzzaman
  • 1,895
  • 16
  • 26