远程数据库用户必须有create session权限,dblink连接实际使用远程账号,无此权限会导致ora-01017等错误;需授权create session及表级权限;dblink权限分私有/公有两种;global_names=true时dblink名须匹配远程global_name;密码含特殊字符或大小写须用英文双引号包裹。
远程数据库用户必须有 create session 权限
本地数据库通过 dblink 连接远程库时,实际是用远程库的账号(connect to username identified by password 中指定的)去建立会话。如果该账号在远程库中没有 create session 权限,创建 dblink 本身可能成功,但后续任何 @dblink_name 查询都会报错:ora-01017: invalid username/password; logon denied 或更隐蔽的 ora-02063: preceding line from xxx。
检查方式(在远程数据库中执行):
SELECT * FROM user_sys_privs WHERE privilege = 'CREATE SESSION';
授权命令(需远程库管理员执行):
GRANT CREATE SESSION TO remote_user;- 如需访问具体表,还得额外授权:
GRANT SELECT ON schema.table_name TO remote_user; - 若要执行 DML,还需
INSERT/UPDATE/DELETE权限;调用远程存储过程则需EXECUTE权限
本地用户创建 DBLink 需匹配权限类型
本地用户(比如 ALANLEE)能否创建 DBLink、以及创建后谁可用,取决于授予的权限类型,不是“有权限就能随便用”。
常见错误现象:DBLink 创建成功,但其他用户查 EMP@my_link 报 ORA-00942: table or view does not exist——其实不是表不存在,而是该用户根本没权限使用这个 DBLink。
权限与行为对应关系:
-
CREATE DATABASE LINK→ 只有创建者能用,其他用户即使知道名字也无法访问 -
CREATE PUBLIC DATABASE LINK→ 所有用户可用,但前提是创建者有该权限(普通用户默认没有) -
UNLIMITED TABLESPACE不能替代 DBLink 权限,网上说“实测可用”是误判:它可能绕过某些对象创建限制,但不赋予网络连接能力
检查本地用户权限(在本地库执行):
SELECT privilege FROM user_sys_privs WHERE privilege LIKE '%DATABASE LINK%';
GLOBAL_NAMES=TRUE 时 DBLink 名称必须匹配远程 global_name
这是 Oracle 默认开启(或常被设为 TRUE)的一个参数,容易被忽略却直接导致连接失败。
现象:DBLink 创建不报错,但首次查询就报 ORA-02085: database link xxx connects to yyy,后面跟两个明显不同的库名。
原因:Oracle 强制要求 DBLink 名称必须等于远程数据库的 global_name(可通过 SELECT * FROM global_name; 在远程库查)。
解决方式(二选一):
- 改 DBLink 名称:比如远程库
global_name是HSCSSERVER.WORLD,那 DBLink 名就得叫HSCSSERVER.WORLD,不能简写为HSAJ216 - 临时关闭校验(不推荐生产):在本地库执行
ALTER SYSTEM SET global_names=FALSE SCOPE=BOTH;,需 DBA 权限且重启生效
密码含特殊字符或大小写时必须加双引号
Oracle 对密码大小写和特殊字符敏感,但 DBLink 语法里不加引号会自动转成大写并截断特殊符号。
例如远程密码是 hundsun@2024!,写成 IDENTIFIED BY hundsun@2024! 会被解析为 HUNDSUN@2024!(部分版本甚至报错),而远程库实际密码可能是区分大小写的。
正确写法:
CREATE PUBLIC DATABASE LINK HSAJ216 CONNECT TO hs_user IDENTIFIED BY "hundsun@2024!" USING '...';
注意点:
- 双引号必须是英文直角引号,中文引号会直接报错
- 密码中含空格、连字符、下划线、@、! 等都建议加引号
- 一旦用了双引号,后续所有对该 DBLink 的操作都无需再加引号,只在创建时约束密码字面量
真正卡住人的往往不是语法写错,而是远程库权限漏授、GLOBAL_NAMES 暗中拦截、或者密码被悄悄转义——这些点不逐个验证,光重试 CREATE 没用。











