ORA-00980 同义词翻译在 PLSQL 中不再有效
Posted
技术标签:
【中文标题】ORA-00980 同义词翻译在 PLSQL 中不再有效【英文标题】:ORA-00980 synonym translation no longer valid in PLSQL 【发布时间】:2015-08-03 14:08:00 【问题描述】:我在远程 Oracle 数据库上有一个同义词,我可以通过数据库链接在 SQL 中访问它,例如,
insert into my_table select * from my_synonym@my_database_link;
如果我将上述语句放入 PLSQL 块中,它将无法编译,并给出错误消息“ORA-00980:同义词翻译不再有效”。标准解释是同义词指向的表已被删除等,但事实并非如此,因为该语句在 SQL 中有效。
【问题讨论】:
问汤姆有一个关于这个主题的条目,其中的场景与你的相似,asktom.oracle.com/pls/apex/… 以下答案的补充(来自 Burleson Consulting):dba-oracle.com/… 【参考方案1】:如果某些东西在 SQL 中有效,但在 PL/SQL 中无效,那么在大多数情况下,这是权限问题。
当您输入 PL/SQL 块时,用户通过 角色 获得的任何特权均无效。所以很可能基础表上的SELECT
权限是通过角色授予的,因此在 PL/SQL 块中不是“活动的”。
解决此问题的常用方法是直接将权限授予用户,而不是通过角色。
【讨论】:
感谢您回答我的问题,但在这种特殊情况下不涉及授权:通过数据库链接 my_database_link 访问 my_synonym。 @DVeloper: ...存储在 DBLink 中的用户需要授权才能访问基础表。【参考方案2】:感谢所有试图提供帮助的人。这原来是一个 Oracle 限制:
https://support.oracle.com/rs?type=doc&id=453754.1
适用于:
PL/SQL - 版本 9.2.0.8 及更高版本 本文档中的信息 适用于任何平台。 已于 2015 年 4 月 1 日检查相关性
症状
PL/SQL 块失败并出现错误:ORA-00980: synonym translation is no 从远程数据库中选择数据时,有效期更长。这 下面的代码演示了这个问题:
在 DB3 上(创建表)
连接 u3/u3 DROP TABLE 选项卡;创建表选项卡(c1 编号);插入 进入标签值(1);提交;
在 DB2 上(在 DB3 上创建表的同义词)
连接 u2/u2 删除数据库链接 dblink2;创建数据库链接 dblink2 连接到由 u3 使用“EMT102U6”识别的 u3;选择 * FROM global_name@dblink2;删除同义词 syn2;创建同义词 syn2 FOR tab@dblink2;从 syn2 中选择 *;
在 DB1 上(为 DB2 上的同义词创建同义词)
连接 u1/u1 删除数据库链接 dblink1;创建数据库链接 dblink1 连接到由 u2 使用“EMT102W6”标识的 u2;选择 * FROM global_name@dblink1;删除同义词 syn1;创建同义词 syn1 对于 syn2@dblink1;从 syn1 中选择 c1;
这在 SQL 中有效,但在从 PL/SQL 调用时失败
声明数字 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 QUERING FROM A PL/SQL 中报告 9I -> 8I-> 7.3.4 中的过程,获取 ORA-980。此错误已关闭 出于以下原因,作为“不是 BUG”
PL/SQL 不能指示中间数据库(DB2)跟随数据库 在编译阶段链接。因此,为了这个 PL/SQL 块编译和运行,数据库链接 dblink1 和 dblink2 应该在前端数据库 - DB1 上定义。在运行时 数据库链接 dblink2 将按预期在 DB2 中查找。
解决方案
要实施该解决方案,请执行以下步骤:
在 DB1 上创建指向 DB3 的数据库链接 dblink2
SQL> 创建数据库链接 dblink2 连接到由 u3 识别的 u3 使用 'EMT102U6';
在 DB1 上创建和编译 PL/SQL 块。
创建数据库链接 dblink2 连接到由 u3 识别的 u3 使用 'EMT102U6';
SELECT * FROM global_name@dblink2;声明数字 NUMBER;开始 从 syn1 中选择 c1 到 num;结尾; /PL/SQL 程序成功 完全的。
提示:另一种选择是在 PL/SQL 块中使用动态 SQL 作为 解决问题。使用动态 SQL 时,无法解析数据库链接 在编译时但在运行时。
【讨论】:
我认为引用 Oracle 文档很好/很好,但您不应该逐字复制其内容。提供你自己的例子。 :) 这个答案的好补充(来自 Burleson Consulting):dba-oracle.com/…【参考方案3】:解决方法是改用 Oracle 视图。
CREATE VIEW v_my_synomym as (select * from my_synonym@my_database_link);
然后引用您的包或过程中的视图,即:
insert into my_table select * from v_my_synonym;
【讨论】:
【参考方案4】:为您在连接字符串中使用的用户检查远程数据库授权“my_synonym”必须几乎是“选择”,还要检查该同义词指向的对象(可能有人删除了表)。
【讨论】:
【参考方案5】:当表/视图/过程的所有者与 SYNONYM 中提到的所有者不匹配时,我发现了这个问题。
示例:如果表 TABLE_BRACH 的所有者是 ownerA,并且在同义词中提到的表所有者是其他东西(不是 ownerA)。
解决方案: 1.删除同义词 2. 用正确的所有者创建具有相同名称的名称。
CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;
【讨论】:
以上是关于ORA-00980 同义词翻译在 PLSQL 中不再有效的主要内容,如果未能解决你的问题,请参考以下文章