[20150430]同义词使用问题.txt

[20150430]同义词使用问题.txt

SCOTT@test> @ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.3.0     Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

SCOTT@test> desc tt
ERROR:
ORA-04043: object tt does not exist

SCOTT@test> create synonym syn_public_tt1 for tt;
Synonym created.

SCOTT@test> create synonym syn_public_tt2 for syn_public_tt1;
Synonym created.

--居然可以建议同义词.

SCOTT@test> select * from syn_public_tt1;
select * from syn_public_tt1
              *
ERROR at line 1:
ORA-00980: synonym translation is no longer valid

SCOTT@test> host oerr ora 980
00980, 00000, "synonym translation is no longer valid"
// *Cause: A synonym did not translate to a legal target object. This
//         could happen for one of the following reasons:
//         1. The target schema does not exist.
//         2. The target object does not exist.
//         3. The synonym specifies an incorrect database link.
//         4. The synonym is not versioned but specifies a versioned
//            target object.
// *Action: Change the synonym definition so that the synonym points at
//          a legal target object.


SCOTT@test> create table tt as select * from dept ;
Table created.

SCOTT@test> select * from syn_public_tt1;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS1
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SCOTT@test> select * from syn_public_tt2;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS1
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

--这个问题非常讨厌,如果不小心把表删除了,而对应的同一词依旧存在.
SCOTT@test> drop table tt purge;
Table dropped.

SCOTT@test> select *  from dba_synonyms where owner='SCOTT';
OWNER  SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME     DB_LINK
------ ------------------------------ ------------------------------ -------------- --------------------
SCOTT  SYN_PUBLIC_TT1                 SCOTT                          TT
SCOTT  PRODUCTS                       SH                             PRODUCTS
SCOTT  SYN_PUBLIC_TT2                 SCOTT                          SYN_PUBLIC_TT1

--也没有办法标识是否有效.而且麻烦的是同义词可以定义同义词的同义词,这样定位脚本要写的有点复杂,要进行一些递归.

SCOTT@test> column table_name format a20
SCOTT@test> select *  from dba_synonyms where owner='SCOTT' and (table_owner,table_name) not in (select owner,table_name from dba_tables);
OWNER  SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME           DB_LINK
------ ------------------------------ ------------------------------ -------------------- --------------------
SCOTT  SYN_PUBLIC_TT1                 SCOTT                          TT
SCOTT  SYN_PUBLIC_TT2                 SCOTT                          SYN_PUBLIC_TT1

--视乎这样是对的,如果我建立表tt呢?
SCOTT@test> create table tt as select * from dept ;
Table created.

SCOTT@test> select *  from dba_synonyms where owner='SCOTT' and (table_owner,table_name) not in (select owner,table_name from dba_tables);
OWNER  SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME           DB_LINK
------ ------------------------------ ------------------------------ -------------------- --------------------
SCOTT  SYN_PUBLIC_TT2                 SCOTT                          SYN_PUBLIC_TT1

--很明显这个脚本存在问题.

SELECT *
  FROM dba_synonyms
WHERE     owner = 'SCOTT'
       AND (table_owner, table_name) NOT IN (SELECT owner, table_name
                                               FROM dba_tables)
       AND (table_owner, table_name) NOT IN (SELECT owner, synonym_name
                                               FROM dba_synonyms);

SCOTT@test> create synonym syn_public_tt3 for syn_public_tt2;
Synonym created.

SCOTT@test> drop  synonym syn_public_tt1 ;
Synonym dropped.


SELECT *
  FROM dba_synonyms
WHERE     owner = 'SCOTT'
       AND (table_owner, table_name) NOT IN (SELECT owner, table_name FROM dba_tables)
       AND (table_owner, table_name) NOT IN (SELECT owner, synonym_name FROM dba_synonyms);

OWNER  SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME           DB_LINK
------ ------------------------------ ------------------------------ -------------------- --------------------
SCOTT  SYN_PUBLIC_TT2                 SCOTT                          SYN_PUBLIC_TT1

--^_^,又漏掉了SYN_PUBLIC_TT3,好在这种级联定义应该不会太多.
--写sql语句不是我的强项.估计要使用connect by之类的东西.

--这个问题,我最近在整理一个数据库,里面无效的同义词太多.这才有上面的测试.还好开发一般不会选择定义同义词的同义词.删除这些
--无效的同义词还是很容易的.

上一篇:python实现微信小程序支付


下一篇:微信支付,支付宝支付回调的问题