ORA-12504错误表明Navicat未向监听器提供SERVICE_NAME或SID,根本原因是连接类型与参数传递不匹配:若选“Oracle (TNS)”模式,手动填写的服务名无效,必须依赖tnsnames.ora中明确定义的SERVICE_NAME或SID;改用“Oracle (Basic)”模式并正确填写HOST、PORT及SERVICE_NAME(优先)或SID即可直接解决。
ora-12504 错误说明 navicat 没有收到服务标识信息(即没填 sid 或 service_name),监听器无法判断你要连哪个实例。这不是配置文件问题,而是连接参数本身缺失关键字段——直接补上就能解决。
为什么填了服务名还报ORA-12504?
Navicat 连接 Oracle 时,默认使用 TNS 连接模式,但如果你选的是“Oracle (TNS)”类型,它会忽略手动填写的 Service Name 或 SID 栏位,转而依赖本地 tnsnames.ora 中的定义。一旦该文件里对应条目缺 SERVICE_NAME 或 SID 字段,或者你根本没配 TNS 条目,就会退回到 ORA-12504。
- 常见错觉:在“服务名”输入框里打了
ORCL,但 Navicat 实际没把它当有效值传给底层驱动 - 根本原因:连接类型和参数传递方式不匹配——你填的字段只在“Oracle (Basic)”模式下生效
- Mac 用户额外注意:
tnsnames.ora路径常被忽略,系统默认找不到,导致强制 fallback 到无参连接
改用 Basic 模式 + 手动指定 SID/SERVICE_NAME
绕过 TNS 解析,让 Navicat 直接构造连接串。这是最可控、最不易受环境变量干扰的方式。
- 新建连接时,数据库类型选
Oracle (Basic),不是Oracle (TNS) -
Host填数据库服务器地址(如localhost或 IP) -
Port填监听端口(通常是1521) -
SID或Service Name二选一填准:优先用SERVICE_NAME(查库命令:SELECT value FROM v$parameter WHERE name='service_names';);若不确定,再试SID(查库命令:SELECT instance_name FROM v$instance;) - 用户名/密码照常填
检查 tnasnames.ora 是否真被读取(仅限 TNS 模式)
如果你坚持用 TNS 模式,必须确认 Navicat 正确加载了你的 tnsnames.ora 文件,否则它根本不会去解析里面的内容。
- Windows 下典型路径:
%ORACLE_HOME%\network\admin\tnsnames.ora;若没设ORACLE_HOME,Navicat 可能读%USERPROFILE%\AppData\Roaming\PremiumSoft\Navicat\profiles\tnsnames.ora - macOS 下:
$ORACLE_HOME/network/admin/tnsnames.ora,或 Navicat 自带的 profile 路径(可通过 Navicat → Preferences → Connection → Oracle → TNS Admin 查看) - 文件中对应条目必须包含完整
CONNECT_DATA块,且明确写出SERVICE_NAME或SID,例如:(ORCL =<br> (DESCRIPTION =<br> (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))<br> (CONNECT_DATA =<br> (SERVER = DEDICATED)<br> (SERVICE_NAME = orcl)<br> )<br> )<br>)
容易被忽略的细节
很多人改完参数立刻重试,却忘了监听器本身是否已注册该服务——ORA-12504 是客户端侧缺失参数,但紧随其后的 ORA-12514 往往才是服务端问题。务必先确保 SID 或 SERVICE_NAME 的值和数据库实际运行的一致,大小写敏感,不能靠猜。











