ora-12154 是客户端本地 tns 名解析失败,仅因未找到服务名对应配置;需确认 tnsnames.ora 路径(用 tnsping 查看)、tns_admin 环境变量设置、文件语法正确性、sqlnet.ora 中 names.directory_path 启用 tnsnames,或改用 easy connect 格式验证。

ORA-12154 是纯客户端本地解析失败,和数据库是否运行、网络是否通、密码是否正确完全无关。它只说明:cx_Oracle(或 sqlplus)根本没找到你写的那个服务名(比如 ORCL)对应哪台机器、哪个端口、哪个服务。
确认当前实际加载的 tnsnames.ora 路径
别猜目录,让 Oracle 自己告诉你它在读哪个文件:
- 运行
tnsping ORCL(把ORCL换成你实际用的服务名),第一行输出类似Used parameter files: /opt/oracle/instantclient_19_2/network/admin/sqlnet.ora—— 这个路径里的admin/子目录下必须有tnsnames.ora - 如果这行是空的,说明 Oracle 根本没找到任何
tnsnames.ora,此时检查TNS_ADMIN环境变量是否设置,且指向的是「目录」而非文件路径 - Linux/macOS 下用
echo $TNS_ADMIN;Windows 下用echo %TNS_ADMIN%;若为空,就手动设,例如:export TNS_ADMIN=/path/to/your/tnsdir - 注意:多个 Oracle 客户端共存时(如 11g 和 19c Instant Client),
TNS_ADMIN指向错误目录是最常见原因
验证 tnsnames.ora 文件语法与内容
这个文件不是 JSON,但对格式极其敏感。哪怕一个空格、一个括号错位,都会导致整个条目失效:
- 确保服务名定义是顶格写的,后面紧接
=,不要有空格:ORCL =✅,ORCL =❌(等号前有空格) - 最外层必须是
(DESCRIPTION = ...),不能漏括号,也不能多一层嵌套 - 所有
=前后不能有空格,HOST、PORT、SERVICE_NAME关键字大小写不敏感,但值区分(Linux 下orcl和ORCL可能不等价) - 避免 BOM 头(UTF-8 with BOM)、中文全角符号、行尾多余空格或空行
- 最小可用示例(复制即用):
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = db-server)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCL)
)
)
检查 sqlnet.ora 是否禁用了 tnsnames 解析
即使 tnsnames.ora 存在且语法正确,sqlnet.ora 也可能把它“关掉”:
- 打开
sqlnet.ora(路径和tnsnames.ora同级),查找NAMES.DIRECTORY_PATH行 - 如果它是
NAMES.DIRECTORY_PATH= (TNSNAMES),没问题;但如果被注释掉、写成(LDAP)或空值,就会跳过tnsnames.ora - 安全起见,可显式设为:
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT),这样既支持别名也支持host:port/service_name格式 - 改完
sqlnet.ora后,终端/应用需重启才生效(环境变量或配置不会热加载)
绕过 tnsnames.ora 的临时验证法
如果以上都调不通,用 Easy Connect 格式直连,快速判断是不是纯配置问题:
- 在代码或 sqlplus 中改用:
user/pass@db-server:1521/ORCL(注意是斜杠/,不是冒号:) - 如果这个能连上,100% 确认是
tnsnames.ora加载或内容问题,不是网络或数据库本身故障 - 注意:JDBC URL 中同样可用该格式,如
jdbc:oracle:thin:@db-server:1521/ORCL - 此方式不依赖任何本地配置文件,适合调试和 CI/CD 环境
真正容易卡住的地方,往往不是文件不存在,而是 TNS_ADMIN 指向了空目录、tnsnames.ora 里多了一个看不见的 BOM、或者 sqlnet.ora 里那行 NAMES.DIRECTORY_PATH 被悄悄注释掉了——这些细节不打印错误,但会让整个解析链路静默失败。











