0x00 问题场景

1. 环境配置

角色名称版本位数备注
数据库Oracle Database11g Release 2,11.2.0.1.032 bit
数据库操作系统Windows 7 Professional6.1.7601, Service Pack 132-bit\
客户端操作系统Windows 7 Professional6.1.7601, Service Pack 164 bit\
数据库客户端Navicat Premium12.0.1164 bit\

2. 问题说明

Oracle数据安装完后死活连接不上,各种莫名其妙的报错。遇到的错误码如下:

navicat 11的报错

Cannot load OCI DLL, 193:C:\Program Files\PremiumSoft\Nacicat Premium\instantclient_11_2\oci.dll
Instant Client package is required for Basic and TNS connection.
For more information:http://wiki.navicat.com/wiki/index.php/Instant_client_required
ORA-28547:connection to server failed, probable Oracle Net admin error

navicat 12的报错

Oracle library is not loaded.
ORA-28547:connection to server failed, probable Oracle Net admin error

新建了一个数据库test_db,配置了新的listener

ORA-12514: TNS:listener does not currently know of service requested in connect

查看服务状态

服务实例的状态全是’UNKNOWN’,蛋疼。

Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\test>lsnrctl status

LSNRCTL for 32-bit Windows: Version 11.2.0.1.0 - Production on 25-11月-2019 16:2
6:22

Copyright (c) 1991, 2010, Oracle.  All rights reserved.

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))
LISTENER 的 STATUS
------------------------
别名                      LISTENER
版本                      TNSLSNR for 32-bit Windows: Version 11.2.0.1.0 - Produ
ction
启动日期                  25-11月-2019 10:27:03
正常运行时间              0 天 5 小时 59 分 18 秒
跟踪级别                  off
安全性                    ON: Local OS Authentication
SNMP                      OFF
监听程序参数文件          C:\app\test\product\11.2.0\dbhome_1\network\admin\list
ener.ora
监听程序日志文件          c:\app\test\diag\tnslsnr\WIN-xxxxxxxx898\listener\aler
t\log.xml
监听端点概要...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.182.146)(PORT=1521)))
服务摘要..
服务 "CLRExtProc" 包含 1 个实例。
  实例 "CLRExtProc", 状态 UNKNOWN, 包含此服务的 1 个处理程序...
服务 "orcl" 包含 1 个实例。
  实例 "orcl", 状态 UNKNOWN, 包含此服务的 1 个处理程序...
服务 "test_db" 包含 1 个实例。
  实例 "test_db", 状态 UNKNOWN, 包含此服务的 1 个处理程序...
命令执行成功

C:\Users\test>

因为尝试了各种方法,报的错也是百花齐放,就是没有解决问题。

0x01 问题分析

遇到的第一个问题就是

ORA-28547:connection to server failed, probable Oracle Net admin error

这个问题说的就是navicat的连接器错误,无法连接到服务端。这里引入一个连接器概念Oracle Instant Client

Oracle Instant Client是什么

Oracle Instant Client enables applications to connect to a local or remote Oracle Database for development and production deployment. The Instant Client libraries provide the necessary network connectivity, as well as basic and high end data features, to make full use of Oracle Database. It underlies the Oracle APIs of popular languages and environments including Node.js, Python and PHP, as well as providing access for OCI, OCCI, JDBC, ODBC and ProC applications. Tools included in Instant Client, such as SQLPlus and Oracle Data Pump, provide quick and convenient data access.

这里解释下前两句:

Oracle Instant Client使应用程序可以连接到本地或远程Oracle数据库,以进行开发和生产部署。Instant Client库提供必要的网络连接以及基本和高端数据功能,以充分利用Oracle数据库

正常连接Oracle数据库可以是用Oracle配套的SQL Plus工具连接,或者Oracle的客户端,大约700M左右,很重。
在这里插入图片描述
但是为了客户端轻量级连接,*Oracle Instant Client**提供了一个动态库oci.dll。这个库文件只有几百K,只要用了它,腰不酸腿不疼,一口气上五楼,不费劲儿(暴露年龄了。。)。自己写个程序,调用几个函数即可以远程操作Oracle数据库。Navicat默认也是使用了Oracle的这个库,但默认版本为10.2的。

问题来了,我数据库是11.2,但是连接库是10.2的版本,明显版本太低导致不匹配。所以需要使用11.2版本的oci.dll

Oracle Instant Client是一个大包,下面有很多分类适用不同场景。具体分类如下:

Instant Client Package描述关联
Basic运行OCI,OCCI和JDBC-OCI应用程序需要的所有文件OCI OCCI JDBC-OCI
Basic Light只包含英语错误信息, 只支持unicode,ascii,西欧字符集。OCI OCCI JDBC-OCI
SDK提供开发OCI和OCCI程序所需的头文件和makfile示例3
SQL*Plus提供SQL*Plus命令行工具用于执行SQL和PL/SQL语句和脚本SQL*Plus
Tools提供Data Pump, SQL*Loader and Workload Replay ClientData Pump SQL*Loader WRC
ODBC提供ODBC相关的库ODBC
Precompilers提供ProC and ProCOBOL预编译相关的库Pro*C and Pro*COBOL
JDBC-OCI Supplement支持国际化相关库JDBC-OCI

网上广为流传的一种说法是,oci.dll需要使用32 bit的版本,有两个流派阐述了为什么要是32 bit的。

第一种说法是: oracle 数据库是32bit的,不管navicat是多少位,oci.dll需要跟服务器端的保持一致。
第二种说法是:navicat只有32bit的版本,所以oci.dll必须跟navicat保持一致。

于是下载了Instant Client Downloads for Microsoft Windows 32-bit

然而还是报错。

第二中说法似乎比较靠谱,但是我navicat就是64 bit的。Oracle Instant Clien有tBasic版本和Basic Light版本。两个都包含oci.dll,第一直觉是下载一个Basic Light,文件比较小,更轻量。

于是在Instant Client Downloads for Microsoft Windows (x64) 64-bit中下载了instantclient-basiclite-windows.x64-11.2.0.4.0.zip

然而出现新的错误

Cannot load OCI DLL, 193:C:\Program Files\PremiumSoft\Nacicat Premium\instantclient_11_2\oci.dll
Instant Client package is required for Basic and TNS connection.
For more information:http://wiki.navicat.com/wiki/index.php/Instant_client_required

百思不得其解,衍生出了琢磨服务器端的监听器,有发现了很多问题。这里就不在描述了。

这里直接说下最终答案吧,就是oci.dll要符合3个条件:

  1. 数据库版本相同,这里是Version 11.2.0.4.0
  2. 与客户端程序的位数相同,这里navicat是64 bit的所以选择64 bit
  3. 使用Basic版本,不能使用Basic Light

哦,第一个流派衍生出的一种方法不得不说,就是直接从服务器上拷贝oci.dll给navicat用。奇怪的是这个oci.dll跟官网上的32bit的package中的大小不同,开始感觉可能是一种解决方案。后来只能说,道理狗屁不通,方法只知其表。navicat的32 bit应该可以用,但是64 bit是没用的。

0x02 解决方案

使用64 bit的navicat下载64 bit的Instant Client Package -Version 11.2.0.4.0 - Basic的文件。

下载地址如下:
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html#license-lightbox

需要oracle账号登录下载

下载好后解压到navicat的安装目录下:
C:\Program Files\PremiumSoft\Navicat Premium 12
在这里插入图片描述
打开navicat,【工具】- 【选项】-【环境】

将解压出来的oci.dll文件的绝对路径填入到OCI library(oci.dll)的表单中。
在这里插入图片描述
确定,关闭navicat重启后生效。
在这里插入图片描述

0x03 参考文献

https://www.oracle.com/database/technologies/instant-client.html
https://www.oracle.com/database/technologies/112010-win32soft.html
https://www.oracle.com/database/technologies/instant-client/microsoft-windows-32-downloads.html

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐