如何调试ORA-01775: 递归的同义词链?

59

我熟悉ORA-01775错误背后的问题,但是否有调试技巧,或者我只能通过“创建或替换”的方式解决它?

是否有一种查询模式或其他方法,可以查找公共同义词的当前定义是什么?

更棒的是有一个图形化工具,但目前为止,任何东西都会很有帮助。

18个回答

85

事实证明,问题并不是一连串的同义词循环,而是同义词指向不存在的视图。

在这种情况下,Oracle 显然会报错为循环链。


1
好的,肯定发生了其他事情。如果我创建一个视图,为它创建一个同义词,然后删除该视图,当我尝试查询同义词时,会出现以下错误:ORA-00980:同义词翻译无效。 - Dave Costa
2
视图所引用的表都是具有公共同义词的表。这可能与此有关。 - Josh Kodroff
我正在尝试插入到新创建的表中,但是我得到了相同的错误,不知道为什么 :( - Mladen Oršolić
2
我觉得这个答案非常有用...对我来说,当我重新将一个过程添加到一个包中时,我引用了一个不存在的类型。在重新添加该类型后,错误消失了。 - DaaaahWhoosh
2
一个缺失的对象可以因为缺失而引发一系列问题。 - Andrew Brennan
显示剩余2条评论

33
如果您正在使用TOAD,请转到“查看”>“TOAD选项”>“Oracle”>“常规”,并从“解释计划”部分中删除“TOAD_PLAN_TABLE”,然后放置“PLAN_TABLE”。

1
谢谢。这是我在Toad for Oracle中遇到的问题。 - joezen777
1
甚至更好的是,使用 sys.plan_table$ - William Robertson

23

数据字典表DBA_SYNONYMS包含数据库中所有同义词的信息。因此,您可以运行查询

SELECT table_owner, table_name, db_link
  FROM dba_synonyms 
 WHERE owner        = 'PUBLIC'
   AND synonym_name = <<synonym name>>

查看公共同义词当前指向的对象。


5
AND synonym_name LIKE '%同义词名称%' -- 更加有帮助一些。 - Dave Jarvis
1
如果您没有访问dba_synonyms的权限,可以尝试在all_synonyms上执行相同的查询。 - software.wikipedia

20

这个错误代码的不太直观的解决方案似乎是同义词所指向的对象存在问题。

以下是我用于查找指向错误对象的同义词的SQL。

SELECT S.OWNER as SYN_OWNER, S.SYNONYM_NAME as SYN_NAME,
    S.TABLE_OWNER as OBJ_OWNER, S.TABLE_NAME as OBJ_NAME,
    CASE WHEN O.OWNER is null THEN 'MISSING' ELSE O.STATUS END as OBJ_STATUS
FROM DBA_SYNONYMS S
    LEFT JOIN DBA_OBJECTS O ON S.TABLE_OWNER = O.OWNER AND S.TABLE_NAME = O.OBJECT_NAME
WHERE O.OWNER is null
    OR O.STATUS != 'VALID';

2
最佳答案。找出问题所在的方法。 - Kshitiz Sharma
1
@Jarrod Chesney,针对这个查询结果应该怎么处理? - Daniel Belém Duarte
@Daniel Belém Duarte 重新创建缺失的对象,然后重新编译。这对我很有效。非常棒的代码。 - hslakhan
这解决了我的问题;有趣的是,在Oracle SQL Developer中查看同义词时,它似乎并不无效,但确实使用了错误的所有者创建了该同义词。 - Rich Bianco

6

尝试使用以下选择来查找问题同义词,它列出了所有指向不存在对象(表、视图、序列、包、过程、函数)的同义词。

SELECT *
FROM dba_synonyms
WHERE table_owner = 'USER'
    AND (
        NOT EXISTS (
            SELECT *
            FROM dba_tables
            WHERE dba_synonyms.table_name = dba_tables.TABLE_NAME
            )
        AND NOT EXISTS (
            SELECT *
            FROM dba_views
            WHERE dba_synonyms.table_name = dba_views.VIEW_NAME
            )
        AND NOT EXISTS (
            SELECT *
            FROM dba_sequences
            WHERE dba_synonyms.table_name = dba_sequences.sequence_NAME
            )
        AND NOT EXISTS (
            SELECT *
            FROM dba_dependencies
            WHERE type IN (
                    'PACKAGE'
                    ,'PROCEDURE'
                    ,'FUNCTION'
                    )
                AND dba_synonyms.table_name = dba_dependencies.NAME
            )
        )

这仅适用于特定的模式和特定类型的对象。如果它引用了dba_objects,它会更好地工作。 - Andrew Brennan
我建议更改最后的条件为:AND NOT EXISTS ( SELECT * FROM all_objects WHERE object_type NOT IN ( 'SYNONYM' ) AND dba_synonyms.table_name = all_objects.OBJECT_NAME ) - mxdsp

3
今天我遇到了这个错误,经过调试,我发现我使用同义词引用的实际表确实丢失了。所以我建议-首先检查表是否存在!! :-))

1
在我的情况下,“缺失”的表只是被不同的数据库用户所拥有。各种变化都可能发生! - Jeff

2
虽然Jarrod的回答是个好主意,可以捕捉到更广泛的相关问题,但我在Oracle论坛上发现了这个查询,它更直接地解决了(最初提出的)问题。
select owner, synonym_name, connect_by_iscycle CYCLE
from dba_synonyms
where connect_by_iscycle > 0
connect by nocycle prior table_name = synonym_name
and prior table_owner = owner
union
select 'PUBLIC', synonym_name, 1
from dba_synonyms
where owner = 'PUBLIC'
and table_name = synonym_name
and (table_name, table_owner) not in (select object_name, owner from dba_objects
where object_type != 'SYNONYM')

https://community.oracle.com/message/4176300#4176300

您不必深入研究其他类型的无效对象,只需处理那些实际上处于无限循环中的对象。

2
一个开发者无意中写了一份代码,生成并运行了以下SQL语句:CREATE OR REPLACE PUBLIC SYNONYM "DUAL" FOR "DUAL"; 这导致select * from dba_synonyms where table_name = 'DUAL'; 返回了PUBLIC DUAL SOME_USER DUAL而不是PUBLIC DUAL SYS DUAL。我们通过运行以下修复了这个问题(感谢如何重新创建公共同义词“DUAL”?)。
ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=FALSE SCOPE=MEMORY;
CREATE OR REPLACE PUBLIC SYNONYM DUAL FOR SYS.DUAL;
ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=true SCOPE=MEMORY;

2

步骤1)查看与名称相对应的对象:

select * from all_objects where object_name = upper('&object_name');

可能存在同义词,但不存在表格吗?


步骤2)如果那不是问题的原因,就调查同义词:

select * from all_synonyms where synonym_name = upper('&synonym_name');

可能是缺少了底层表或视图与该同义词相关。

没有创建表格,我创建了公共同义词,因为这个表格需要从另一个模式中访问,我执行了授权,但是它没有起作用。我尝试了"select * from so_and_so_table;",但是查询返回了"ORA-01775循环同义词链"的错误。在创建表格之后,这个问题得到了解决。 - Tim

1
今天我们遇到了这个错误。 这是我们如何调试和修复它的。
  1. Package went to invalid state due to this error ORA-01775.

  2. With the error line number , We went thru the package body code and found the code which was trying to insert data into a table.

  3. We ran below queries to check if the above table and synonym exists.

    SELECT * FROM DBA_TABLES WHERE TABLE_NAME = '&TABLE_NAME';  -- No rows returned
    
    SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME = '&SYNONYM_NAME'; -- 1 row returned
    
  4. With this we concluded that the table needs to be re- created. As the synonym was pointing to a table that did not exist.

  5. DBA team re-created the table and this fixed the issue.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接