tnsnames.ora必须放在$oracle_home/network/admin(linux/macos)或%oracle_home%\network\admin(windows)下,或由tns_admin环境变量指定的绝对路径;设tns_admin后将完全忽略oracle_home路径,且sqlnet.ora须同目录、names.directory_path必须含tnsnames。

tnsnames.ora 文件必须放在正确路径下
Oracle 客户端不会自动扫描任意位置的 tnsnames.ora,它只认默认路径或环境变量指定的位置。不放对地方,tnsping 和 sqlplus 都会报 ORA-12154。
- Linux / macOS:默认读取
$ORACLE_HOME/network/admin/tnsnames.ora;若$ORACLE_HOME未设置,多数客户端直接失败 - Windows:默认是
%ORACLE_HOME%\network\admin\tnsnames.ora,注意反斜杠在配置文件里无需转义,但脚本中若用双引号包裹路径需小心 - 若设置了
TNS_ADMIN环境变量,Oracle 会**只读这个路径**,完全忽略$ORACLE_HOME下的文件——这是多人共用一台机器时最常踩的坑 - 验证实际加载的是哪个文件,看
tnsping输出里的Used TNSNAMES adapter to resolve the alias和Used parameter files行
远程连接条目必须用 SERVICE_NAME,不是 SID
现代 Oracle 实例(10g 起默认)使用动态注册,监听器注册的是 SERVICE_NAME,不是旧式 SID。写错就必然 ORA-12514:监听器“不认识你点的菜”。
- 确认数据库真实服务名:在数据库服务器上执行
lsnrctl services,找类似Service "ORCL" has 1 instance(s)这一行里的名字 -
tnsnames.ora条目中必须用SERVICE_NAME=xxx;SID=xxx只适用于静态注册且明确禁用动态注册的极少数场景 - 常见错误写法:
(CONNECT_DATA = (SID = ORCL))→ 改成(CONNECT_DATA = (SERVICE_NAME = ORCL)) - 如果数据库启用了 PDB,服务名通常是 PDB 名(如
PDB1),不是 CDB 名;连 CDB 需显式指定SERVICE_NAME=CDB$ROOT
HOST 和 PORT 必须可路由、可访问、未被拦截
tnsping 显示 OK 仅表示监听器进程收到了探测包并回了拒绝包,不代表端口真能建 TCP 连接。很多“tnsping 通但 sqlplus 不通”的问题出在这层。
- 先用
telnet hostname 1521或nc -zv hostname 1521测试端口是否开放;失败说明网络不通、防火墙拦了、或监听器根本没监听该 IP - 检查监听器是否绑定了正确的网卡:
lsnrctl status输出中的ADDRESS行,HOST值不能是127.0.0.1或localhost(除非客户端也在服务器本机) - Linux 上检查
iptables/firewalld是否放行 1521;Windows 上确认防火墙规则允许tnslsnr.exe入站 - 云环境(如阿里云、AWS)额外检查安全组策略,必须显式放行目标端口
别忽略 sqlnet.ora 的 NAMES.DIRECTORY_PATH 设置
即使 tnsnames.ora 写对了、路径也对了,sqlnet.ora 里一句错配就能让整个解析失效。
- 关键配置项是
NAMES.DIRECTORY_PATH,必须包含TNSNAMES,例如:NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT) - 如果写成
NAMES.DIRECTORY_PATH= (EZCONNECT),Oracle 就完全不查tnsnames.ora,直接跳过——此时tnsping也会失败(但错误信息可能误导人) -
sqlnet.ora同样受TNS_ADMIN控制;它和tnsnames.ora必须在同一目录,或都由TNS_ADMIN指向同一位置 - 该文件若存在语法错误(如多了一个逗号、括号不匹配),Oracle 会静默忽略整份配置,退回到默认行为,非常难排查
tnsping + lsnrctl services + telnet 三步交叉验证。最容易被忽略的是:监听器注册的服务名和 tnsnames.ora 里写的不一致,且没人去 lsnrctl services 看一眼。











