Ora-01775 looping chain of synonyms

今天用户运行查询语句的时候遇到了Ora-01775错误,查看了一下帮助得到如下解释:

ORA-01775 looping chain of synonyms
Cause: Through a series of CREATE synonym statements, a synonym was defined that referred to itself. For example, the following definitions are circular:
CREATE SYNONYM s1 for s2
CREATE SYNONYM s2 for s3
CREATE SYNONYM s3 for s1
Action: Change one synonym definition so that it applies to a base table or view and retry the operation.

本来打算用oerr查询这个错误信息的,不知道为什么没有相关的帮助信息显示。
很明显同义词的创建构成了一个环链,所以当用户通过同义词查询的时候oracle就不知查询那个了。这个Oracle 给出的帮助
信息很详细,还给出了一个例子。
做一个测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
SQL> CREATE synonym s1 FOR s2;
同义词已创建。
SQL> CREATE synonym s2 FOR s3;
同义词已创建。
SQL> CREATE synonym s3 FOR s4;
同义词已创建。
SQL>  CREATE synonym s4 FOR s1;
同义词已创建。
SQL> SELECT * FROM s1;
SELECT * FROM s1
              *1 行出现错误:
ORA-01775: 同义词的循环链
SQL> SELECT * FROM s2;
SELECT * FROM s2
              *1 行出现错误:
ORA-01775: 同义词的循环链
 
 
SQL> SELECT * FROM s2;
SELECT * FROM s2
              *1 行出现错误:
ORA-01775: 同义词的循环链
 
 
SQL> SELECT * FROM s4;
SELECT * FROM s4
              *1 行出现错误:
ORA-01775: 同义词的循环链

这个时候不管你查询那个同义词都会返回01775错误。
不知道你有没有没有发现,这个在创建第一个同义词s1的时候我么并没有s2这个synonym或者object 存在,也就是说
ORACLE 在创建同义词的时候是不会检查object是否存在的,只有当你用到这个synonym引用其他object的时候才会检查。
在 Oracle Database SQL Reference 10g Release 2 (10.2)中找到了这样一句话:
The schema object need not currently exist and you need not have privileges to access the object.
不知道为什么Oracle 会这样做,如果Oracle在创建同义词的时候做一下检查,我想这个01775错误就不会存在了。

在网上找到了一段有趣的代码,记录在这里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SET serveroutput ON format wrap
prompt
declare
    connect_by_loop exception;
    pragma exception_init(connect_by_loop,-1436);
    hold_prev_synonym_name    user_synonyms.synonym_name%type;
begin
    dbms_output.put_line('Synonym Hierarchy');
    dbms_output.put_line('----------------------------------------');
    FOR x IN (SELECT lpad(' ',level * 3) || synonym_name a
            ,synonym_name b
            FROM user_synonyms
         connect BY prior synonym_name = table_name
           start WITH synonym_name = 'S3') loop
        hold_prev_synonym_name := x.b;
        dbms_output.put_line(x.a);
    end loop;
    exception
        when connect_by_loop then
            dbms_output.put_line(
                 'Error: connect-by loop following "'
                ||hold_prev_synonym_name||'"');
end;
/
 
Synonym Hierarchy
----------------------------------------
   S3
      S2
         S1
            S4
               S3
                  S2
                     S1
Error: connect-BY loop following "S1"
PL/SQL procedure successfully completed.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*