代码改变世界

ORA-02083: 数据库名含有非法字符 '-'

2015-11-12 17:00  TRACEING  阅读(1798)  评论(0编辑  收藏  举报

如果数据库的GLOBAL_NAME中包含'-',就可能导致通过数据库链创建的物化视图、视图和同义词出现这个错误。
 
 
重现一下这个错误:
SQL> CONN yangtk/yangtk@192.25.1.103/ora11g_p.ytk_thinkpad
已连接。
SQL> CREATE DATABASE LINK TEST101
  2  USING '192.25.1.101/TEST101';
数据库链接已创建。
SQL> SELECT * FROM DUAL@TEST101;
D
-
X
SQL> CREATE SYNONYM MY_DUAL FOR DUAL@TEST101;
同义词已创建。
SQL> SELECT * FROM MY_DUAL;
SELECT * FROM MY_DUAL
              *
第 1 行出现错误:
ORA-02083: 数据库名含有非法字符 '-'
可以看到,直接访问DUAL@TEST101是没有问题的,但是通过同义词等这种创建到数据库中的对象进行访问,就会出现ORA-2083错误。
这是由于GLOBAL_NAME中包含了'-',从而导致数据库链和创建的对象都包含了'-'字符,使得最终访问对象时报错。
SQL> SELECT * FROM GLOBAL_NAME;
GLOBAL_NAME
-----------------------------------------------------------------------------------------
ORA11G.YTK-THINKPAD
SQL> SELECT DB_LINK FROM USER_DB_LINKS;
DB_LINK
------------------------------
TEST101.YTK-THINKPAD
SQL> SELECT * FROM USER_SYNONYMS;
SYNONYM_NAME    TABLE_OWNER     TABLE_NAME                     DB_LINK
--------------- --------------- ------------------------------ --------------------------
MY_DUAL                         DUAL                           TEST101.YTK-THINKPAD
解决这个错误的根本办法是修改GLOBAL_NAME,当然如果数据库的GLOBAL_NAMES参数为FALSE,可以在创建数据库链的时候人为添加一个后缀,避免数据库链中包含'-':
SQL> SHOW PARAMETER GLOBAL_NAMES
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------
global_names                         boolean     FALSE
SQL> CREATE DATABASE LINK TEST101.YTK
  2  USING '192.25.1.101/TEST101';
数据库链接已创建。
SQL> CREATE OR REPLACE SYNONYM MY_DUAL
  2  FOR DUAL@TEST101.YTK;
同义词已创建。
SQL> SELECT * FROM MY_DUAL;
D
-
X
查询METALINK文档,发现Doc ID:  Note:331169.1对这个问题进行比较详细的描述,不过Oracle给出的方法也是更新GLOBAL_NAME:
SQL> DROP DATABASE LINK TEST101;
数据库链接已删除。
SQL> ALTER DATABASE RENAME GLOBAL_NAME TO ORA11G.YTK_THINKPAD;
数据库已更改。
SQL> CREATE DATABASE LINK TEST101
  2  USING '192.25.1.101/TEST101';
数据库链接已创建。
SQL> CREATE OR REPLACE SYNONYM MY_DUAL
  2  FOR DUAL@TEST101;
同义词已创建。
SQL> SELECT * FROM MY_DUAL;
D
-
X
SQL> SELECT * FROM GLOBAL_NAME;
GLOBAL_NAME
------------------------------------------------------------------------------------------
ORA11G.YTK_THINKPAD
SQL> SELECT DB_LINK FROM USER_DB_LINKS;
DB_LINK
------------------------------
TEST101.YTK
TEST101.YTK_THINKPAD
SQL> SELECT * FROM USER_SYNONYMS;
SYNONYM_NAME    TABLE_OWNER     TABLE_NAME                     DB_LINK
--------------- --------------- ------------------------------ ---------------------------
MY_DUAL                         DUAL                           TEST101.YTK_THINKPAD