删除 Dblink 报错 ORA-02024: database link not found 的解决方法

 

朋友说删除DBLINK 报错: ORA-02024: database link not found

 

Metalink上搜到了2篇与这个错误有关的文章:

       Cannot drop a database link after changing the global_name ORA-02024 [ID 382994.1]

       http://blog.youkuaiyun.com/tianlesoftware/archive/2011/01/23/6160082.aspx

 

       ORA-02024: Database Link Not Found [ID 1058949.1]

       http://blog.youkuaiyun.com/tianlesoftware/archive/2011/01/23/6160080.aspx

 

两篇文章分别讲到了2种情况。

 

.  DBLINK所有者不一致造成

我们来演示一下这种情况。

 

--创建dblink

SQL> conn system/admin;

已连接。

SQL>  create database link dave connect to system identified by admin using '

  2   (DESCRIPTION =

  3   (ADDRESS_LIST =

  4   (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.6.100)(PORT = 1521))

  5   )

  6   (CONNECT_DATA =

  7   (SERVICE_NAME = newccs)

  8   )

  9   )

 10   ';

 

数据库链接已创建。

 

DBLINK 创建这块可以参考官网说明:

CREATE DATABASE LINK

http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_5005.htm#SQLRF01205

 

--查看验证dblink

SQL> select name from v$database@dave;

 

NAME

---------

NEWCCS

 

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

会话已更改。

 

SQL> select * from all_db_links;

OWNER      DB_LINK    USERNAME   HOST       CREATED

---------- ---------- ---------- ---------- -------------------

SYSTEM     DAVE       SYSTEM                2011-01-23 21:17:31

 

--我们用错误的所有者来删除看看

SQL> drop public database link dave;

drop public database link dave

                          *

1 行出现错误:

ORA-02024: 未找到数据库链接

 

--用正确的用户来删除

SQL> drop database link dave;

数据库链接已删除。

 

 

. Global_name 造成

 

先看官网的一段说明:

       If the value of the GLOBAL_NAMES initialization parameter is TRUE, then the database link must have the same name as the database to which it connects. If the value of GLOBAL_NAMES is FALSE, and if you have changed the global name of the database, then you can specify the global name.

       The maximum number of database links that can be open in one session or one instance of an Oracle RAC configuration depends on the value of the OPEN_LINKS and OPEN_LINKS_PER_INSTANCE initialization parameters.

             

       Global_names 是一个布尔值,global_names的作用是创建db link时是否强制使用远程数据库的global_name,如果global_names=true,db link name必须要求是remote databaseglobal_name,否则创建之后db link 不能连同,缺省值是false global_name False时,如果我们修改了global_name,那么在dblink中也要相应的指定global_name. 并且当我们修改了global_name后,之前存在的我们dblink也无法删除。

       Global_name 是由db_name.db_domain构成。

 

有关这几个参数的说明,参考:

       DBID,SID,DB_NAME,DB_DOMAIN,INSTANCE_NAME,DB_UNIQUE_NAME,SERVICE_NAMES 及监听参数的说明

http://blog.youkuaiyun.com/tianlesoftware/archive/2010/12/20/6086066.aspx

 

CREATE DATABASE LINK

http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_5005.htm#SQLRF01205

 

open_links_per_instance open_links 参数说明

http://www.cndba.cn/cndba/dave/article/1431


 

下面来看示例:

SQL> show parameter global_names

NAME             TYPE        VALUE

------------------------------------ ----------- -------

global_names        boolean     FALSE

 

SQL> select * from global_name;

GLOBAL_NAME

------------------------------

NEWCCS

 

SQL> create database link dave connect to system identified by admin using 'newccs';

数据库链接已创建。

 

SQL> select * from dba_db_links;

OWNER      DB_LINK    USERNAME   HOST       CREATED

---------- ---------- ---------- ---------- -------------------

SYSTEM     DAVE       SYSTEM     newccs     2011-01-23 21:45:41

 

SQL>  select name from v$database@dave;

NAME

---------

NEWCCS

 

       这里要注意一点,我这里创建的dblink 使用的是监听名:newccs. dba_db_links表中的host显示的是这个监听的名字。 在第一个示例中,我创建dblink 是使用命令来写的,那种情况下host 为空。

 

       在上面提到,当global_namesFalse的情况下,如果我们修改了global_name,之前创建的dblink 在删除的时候也会包ORA-02024的错误。 甚至我们把global_name 改变成原来的值,也无法删除。 因为这种改变没有生效。 除非我们更新props$ 表。

 

 

 

先来验证global_name 修改后生效问题。

 

SQL> select * from global_name;

GLOBAL_NAME

----------------------------------------------------------------------------

NEWCCS

 

SQL> alter database rename global_name to newccs.tianlesoftware.com;

数据库已更改。

 

SQL> select * from global_name;

GLOBAL_NAME

----------------------------------------------------------------------------

NEWCCS.TIANLESOFTWARE.COM

 

SQL> alter database rename global_name to newccs;

数据库已更改。

 

SQL> select * from global_name;

GLOBAL_NAME

----------------------------------------------------------------------------

NEWCCS.TIANLESOFTWARE.COM

--这里并没有生效。

 

SQL> drop database link dave;

drop database link dave

                   *

1 行出现错误:

ORA-02024: 未找到数据库链接

 

 

       从上面的操作,验证了如果仅通过alter 命令,是无法让global_name 还原成原来的值的。并且当global_name 发生改变后,已经存在的dblink也无法删除。

 

       解决这个问题的方法,就是用sys用户来修改props$表:

       SQL> update props$ set value$ = '<globalname without domain>' where name ='GLOBAL_DB_NAME';

 

 

示例:

SQL> conn / as sysdba;

已连接。

SQL> update props$ set value$ = 'NEWCCS' where name ='GLOBAL_DB_NAME';

 

已更新 1 行。

SQL> commit;

提交完成。

 

然后切换到dblink 的用户,删除dblink

SQL> conn system/admin;

已连接。

SQL> drop database link dave;

数据库链接已删除。

 

如果还报这种错误,可以刷新三次shared pool 在执行drop命令:

alter system flush SHARED_POOL;

alter system flush SHARED_POOL;

alter system flush SHARED_POOL;

 

如果刷新shared pool后还无法drop,那么就需要重启DB,在删除了。

 

 

 

 

 

 

------------------------------------------------------------------------------

QQ:492913789

Email:ahdba@qq.com

Blog: http://www.cndba.cn/dave 


网上资源: http://tianlesoftware.download.youkuaiyun.com

相关视频:http://blog.youkuaiyun.com/tianlesoftware/archive/2009/11/27/4886500.aspx

DBA1 群:62697716(); DBA2 群:62697977()

DBA3 群:62697850   DBA 超级群:63306533;    

聊天 群:40132017

--加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请

<think> 我们正在解决创建DBLink时遇到的ORA-00933错误。根据Oracle官方文档和常见案例,该错误在创建DBLink时通常由以下原因引起: 1. 语法错误:创建DBLinkSQL语句书写不正确。 2. 使用了错误的连接字符串格式。 3. 在DBLink名称中使用了特殊字符或关键字。 以下是创建DBLink的标准语法: ```sql CREATE [PUBLIC] DATABASE LINK dblink_name CONNECT TO target_user IDENTIFIED BY target_password USING 'connect_string'; ``` 常见错误点及解决方案: 1. **连接字符串格式错误**: 连接字符串必须用单引号括起来,且整个语句以分号结束(在SQL*Plus中需要分号,但在某些客户端可能不需要)。例如: ```sql -- 错误示例:连接字符串缺少引号 CREATE DATABASE LINK mylink CONNECT TO scott IDENTIFIED BY tiger USING orcl; -- 正确示例: CREATE DATABASE LINK mylink CONNECT TO scott IDENTIFIED BY tiger USING 'orcl'; ``` 2. **DBLink名称包含特殊字符或关键字**: DBLink名称如果包含特殊字符(如连字符、空格)或Oracle关键字,必须使用双引号括起来,但通常建议避免使用特殊字符。例如: ```sql -- 错误示例:名称中包含连字符(-)会报错 CREATE DATABASE LINK my-link ... -- 引发ORA-00933 -- 正确示例:用双引号包裹 CREATE DATABASE LINK "my-link" ... -- 或者避免使用特殊字符 CREATE DATABASE LINK my_link ... ``` 3. **缺少必要的关键字或空格**: 检查关键字之间是否有空格,特别是`CONNECT TO`和`IDENTIFIED BY`后面必须跟一个空格。例如: ```sql -- 错误示例:缺少空格 CREATE DATABASE LINK mylink CONNECTTO scott ... -- 正确示例: CREATE DATABASE LINK mylink CONNECT TO scott ... ``` 4. **分号位置问题**: 在SQL*Plus或SQL Developer等工具中,语句末尾需要分号。但是,如果是在PL/SQL块中(如动态SQL)则不需要分号。例如: ```sql --SQL*Plus中正确 CREATE DATABASE LINK ... USING 'orcl'; -- 在动态SQL中(如EXECUTE IMMEDIATE)则去掉分号 EXECUTE IMMEDIATE 'CREATE DATABASE LINK ... USING ''orcl'' '; ``` 5. **使用了不兼容的选项**: Oracle 12c开始,如果使用多租户架构(CDB/PDB),创建DBLink时需要注意连接字符串指向的是PDB而不是CDB。例如,如果目标数据库是PDB,连接字符串应指向PDB的服务名。 6. **注释符号错误**: 在创建DBLink的语句中,避免使用行内注释(--),因为可能导致后续语句被截断。如果必须写注释,请使用/* */格式。 7. **保留关键字冲突**: 如果用户名、密码或连接字符串中使用了Oracle保留关键字(如CONNECT、SELECT等),需要用双引号括起来。但这种情况较少见,通常出现在密码中。例如: ```sql -- 密码是保留字(如"connect") CREATE DATABASE LINK mylink CONNECT TO scott IDENTIFIED BY "connect" USING 'orcl'; ``` **调试步骤**: 1. 将创建DBLinkSQL语句拆分成最简形式: ```sql -- 先使用最简单的语句测试 CREATE DATABASE LINK testlink CONNECT TO scott IDENTIFIED BY tiger USING 'orcl'; ``` 如果成功,再逐步添加复杂元素(如PUBLIC关键字、特殊名称等)。 2. 验证连接字符串: 确保连接字符串是有效的TNS别名,或使用完整的TNS描述符(推荐使用TNS别名,并在tnsnames.ora中配置)。 3. 检查Oracle版本: 某些旧版本中,DBLink创建语法可能有差异。例如,在Oracle 11g中,如果使用SID而不是服务名,连接字符串格式不同。 4. 使用动态SQL调试: 如果在PL/SQL中动态创建,使用DBMS_OUTPUT打印完整SQL语句,然后单独执行以验证语法。 5. 查看官方文档: 参考Oracle官方文档中对应版本的语法:[CREATE DATABASE LINK](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/CREATE-DATABASE-LINK.html) **示例修复**: 假设原始错误语句为: ```sql CREATE PUBLIC DATABASE LINK remote-db CONNECT TOremote_user IDENTIFIED BY pass123 USING 'remote_db:1521/orcl'; ``` 错误分析: - DBLink名称`remote-db`包含连字符(需要双引号) - `CONNECT TO`后缺少空格(应改为`CONNECT TO remote_user`) 修复后语句: ```sql CREATE PUBLIC DATABASE LINK "remote-db" CONNECT TO remote_user IDENTIFIED BY pass123 USING 'remote_db'; ``` **注意事项**: -Oracle 12c及以上版本,创建公共DBLink需要`CREATE PUBLIC DATABASE LINK`权限。 - 如果目标数据库是PDB,连接字符串应使用PDB的服务名,而不是CDB的服务名。 通过以上步骤,绝大多数ORA-00933错误在创建DBLink时都可解决。 </think> ### ORA-00933错误在创建DBLink时的解决方案 创建数据库链接(DBLink)时遇到ORA-00933错误,通常由语法不规范或特殊字符问题导致。以下是系统性解决方案: --- ### 一、核心修复步骤 1. **检查连接字符串格式** **错误示例**(缺少引号): ```sql CREATE DATABASE LINK remote_db CONNECT TO user IDENTIFIED BY password USING remote_host:1521/orcl; -- 缺少引号 ``` **正确写法**(需单引号包裹): ```sql CREATE DATABASE LINK remote_db CONNECT TO user IDENTIFIED BY password USING 'remote_host:1521/orcl'; -- 引用[1] ``` 2. **验证DBLink名称规范** 名称包含连字符(`-`)或数字开头时需用双引号: ```sql -- 错误(名称含连字符) CREATE DATABASE LINK remote-db ... -- 正确 CREATE DATABASE LINK "remote-db" ... -- 引用[3] ``` 3. **排查多余字符** 移除语句末尾分号(在SQL*Plus中无需分号): ```sql -- 错误 CREATE DATABASE LINK ... ; -- 正确 CREATE DATABASE LINK ... ``` 4. **检查关键字完整性** 确认`CONNECT TO`和`IDENTIFIED BY`子句无中断: ```sql -- 错误(缺少空格) CREATE DATABASE LINK ... CONNECTTO user ... -- 正确 CREATE DATABASE LINK ... CONNECT TO user ... ``` --- ### 二、进阶排查方案 | 错误场景 | 错误示例 | 修复方案 | |-------------------------|----------------------------------|----------------------------------------| | **TNS别名未配置** | `USING 'nonexistent_alias'` | 在`tnsnames.ora`添加有效别名 | | **多租户架构配置错误** | `USING 'CDB_service'`(应连PDB) | 改为PDB服务名:`USING 'pdb_service'` | | **保留关键字冲突** | 名称使用`USER`, `LINK`等关键字 | 用双引号包裹:`"USER_LINK"` | | **注释符号错误** | `-- 注释后无空格... USING '...'` | 删除行内注释或换用`/* */` | --- ### 三、分步调试流程 1. **简化语句测试** 用最小化配置验证基础语法: ```sql CREATE DATABASE LINK testlink CONNECT TO scott IDENTIFIED BY tiger USING 'ORCL'; -- 仅保留必需参数 ``` 2. **检查网络配置** 验证`tnsnames.ora`中的服务名配置: ```ini ORCL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = remote_host)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl)) ) ``` 3. **权限验证** 执行用户需具备权限: ```sql GRANT CREATE DATABASE LINK TO current_user; ``` --- ### 四、特殊场景解决方案 1. **Oracle RAC环境** 使用SCAN地址替代单节点地址: ```sql USING 'scan_name:1521/orcl_pdb' -- 引用[2] ``` 2. **密码含特殊字符** 用双引号包裹密码: ```sql IDENTIFIED BY "p@ss#word!" -- 特殊字符处理 ``` 3. **动态创建DBLink** 在PL/SQL中需去掉分号: ```sql EXECUTE IMMEDIATE ' CREATE DATABASE LINK dyn_link CONNECT TO user IDENTIFIED BY pwd USING ''remote_service'' -- 注意双层单引号 '; ``` > **修复案例**: > 用户因DBLink名称`prod-db1`含连字符报错,**添加双引号**后成功创建: > `CREATE DATABASE LINK "prod-db1" ...` [^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值