ORA-00980 同义词翻译在 PLSQL 中不再有效
ORA-00980 synonym translation no longer valid in PLSQL
我在远程 Oracle 数据库上有一个同义词,我可以在 SQL 中通过数据库 link 访问它,例如,
insert into my_table select * from my_synonym@my_database_link;
如果我把上面的语句放到一个PLSQL块中,它不会编译,给出错误信息"ORA-00980: synonym translation is no longer valid"。标准解释是同义词指向的 table 已被删除等,但事实并非如此,因为该语句适用于 SQL.
如果某些东西在 SQL 中有效但在 PL/SQL 中无效,那么在大多数情况下这是权限问题。
当您进入 PL/SQL 块时,用户通过 角色 获得的任何特权都不会激活。所以很可能底层 table 的 SELECT
特权是通过角色授予的,因此在 PL/SQL 块中不是 "active"。
解决这个问题的通常方法是直接将权限授予用户,而不是通过角色。
检查 "my_synonym" 的远程数据库授权对于您在连接字符串中使用的用户必须几乎 "select",还要检查此同义词指向的对象(也许有人删除了 table).
感谢所有试图提供帮助的人。结果证明这是一个 Oracle 限制:
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:
- Create a database link dblink2 on DB1 pointing to DB3
SQL> create database link dblink2 connect to u3 identified by u3 using
'EMT102U6';
- 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.
当 table/view/procedure 的所有者与 SYNONYM 中提到的所有者不匹配时,我发现了这个问题。
示例:如果 table TABLE_BRACH 的所有者是所有者 A,并且在同义词中提到 table 所有者是其他人(不是所有者 A)。
解决方法:
1. 去掉同义词
2. 用正确的所有者创建同名的。
CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;
解决方法是改用 Oracle 视图。
CREATE VIEW v_my_synomym as (select * from my_synonym@my_database_link);
然后在您的包或过程中引用视图,即:
insert into my_table select * from v_my_synonym;
我在远程 Oracle 数据库上有一个同义词,我可以在 SQL 中通过数据库 link 访问它,例如,
insert into my_table select * from my_synonym@my_database_link;
如果我把上面的语句放到一个PLSQL块中,它不会编译,给出错误信息"ORA-00980: synonym translation is no longer valid"。标准解释是同义词指向的 table 已被删除等,但事实并非如此,因为该语句适用于 SQL.
如果某些东西在 SQL 中有效但在 PL/SQL 中无效,那么在大多数情况下这是权限问题。
当您进入 PL/SQL 块时,用户通过 角色 获得的任何特权都不会激活。所以很可能底层 table 的 SELECT
特权是通过角色授予的,因此在 PL/SQL 块中不是 "active"。
解决这个问题的通常方法是直接将权限授予用户,而不是通过角色。
检查 "my_synonym" 的远程数据库授权对于您在连接字符串中使用的用户必须几乎 "select",还要检查此同义词指向的对象(也许有人删除了 table).
感谢所有试图提供帮助的人。结果证明这是一个 Oracle 限制:
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:
- Create a database link dblink2 on DB1 pointing to DB3
SQL> create database link dblink2 connect to u3 identified by u3 using 'EMT102U6';
- 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.
当 table/view/procedure 的所有者与 SYNONYM 中提到的所有者不匹配时,我发现了这个问题。
示例:如果 table TABLE_BRACH 的所有者是所有者 A,并且在同义词中提到 table 所有者是其他人(不是所有者 A)。
解决方法: 1. 去掉同义词 2. 用正确的所有者创建同名的。
CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;
解决方法是改用 Oracle 视图。
CREATE VIEW v_my_synomym as (select * from my_synonym@my_database_link);
然后在您的包或过程中引用视图,即:
insert into my_table select * from v_my_synonym;