原文见:
http://hi.baidu.com/xchinux/item/5dd91dd578684938e3108f9b1.
安装Oracle ODBC Driver(依赖于Oracle Instant Client,又依赖于VC2005运行库(即可发布包))
到下面网址下载最新的Oracle ODBC Driver和Instant Client
http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html上面列出了各个操作系统平台下的下载链接,要记住,Qt程序是32位的,就下载32位的,Qt程序是64位的就下载64位的。
我这里使用的是32位windows的:
http://www.oracle.com/technetwork/topics/winsoft-085727.htmlVersion 11.2.0.3.0 Instant Client Package - Basic:All files required to run OCI, OCCI, and JDBC-OCI applications
instantclient-basic-nt-11.2.0.3.0.zip(51,149,941 bytes)
*Instant Client Package - ODBC:Additional libraries for enabling ODBC applications
instantclient-odbc-nt-11.2.0.3.0.zip(740,177 bytes)
将上面两个包下载后,解压到某个要安装的目录下,比如为D:\oracle_odbc,则现在这个目录下有ODBC_IC_Readme_Win.html这个
文件,来看安装说明.
执行D:\oracle_odbc\odbc_install.exe,即可安装Oracle ODBC Driver,这时打开odbcad32.exe,应该能在驱动里看到Oracle in instantclient_11_2的驱动名字了。
2. 写tnsnames.ora,并且设置环境变量TNS_ADMIN指定到其所在目录
其实这个tnsnames.ora我还不会写,我就直接将oracle安装目录下的network\admin\tnsnames.ora拷贝过来了,其实里面关键的就是HOST和SERVICE_NAME,一开始的XE字样,和SERVICE_NAME保持一致即可,如果有多个Oracle实例的话,就要区别开来了。具体的tnsnames.ora的写法,得专门去看一下。这里,我将tnsnames.ora就放到D:\oracle_odbc目录下,然后设置环境变量TNS_ADMIN为D:\oracle_odbc,这样就行了。
- XE =
- (DESCRIPTION =
- (ADDRESS = (PROTOCOL = TCP)(HOST = BJP-X200)(PORT = 1521))
- (CONNECT_DATA =
- (SERVER = DEDICATED)
- (SERVICE_NAME = XE)
- )
- )
-
- EXTPROC_CONNECTION_DATA =
- (DESCRIPTION =
- (ADDRESS_LIST =
- (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
- )
- (CONNECT_DATA =
- (SID = PLSExtProc)
- (PRESENTATION = RO)
- )
- )
-
- ORACLR_CONNECTION_DATA =
- (DESCRIPTION =
- (ADDRESS_LIST =
- (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
- )
- (CONNECT_DATA =
- (SID = CLRExtProc)
- (PRESENTATION = RO)
- )
- )
3. 设置NLS_LANG环境变量
在服务器端执行一下下面的语句,将其值设置给NLS_LANG环境变量即可(在我的环境上,它的值是"SIMPLIFIED CHINESE_CHINA.AL32UTF8")
- select userenv('language') from dual
4. 在odbcad32.exe管理器中,建立
数据源(实际上也可以通过odbcconf.exe来动态设置用户数据源,或自己写个文件数据源,注意,如果是32位的,则在win64上,要使用C:\windows\syswow64\odbcad32.exe来配置ODBC数据源)如果不使用数据源(包括文件数据源),则可以使用DSN字符串(自己建个文件数据源,然后打开那个.dsn文件,照抄下来),如下所示:
- QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
- QString strDSN = "DRIVER={Oracle in instantclient_11_2};UID=TEST;DBQ=XE;SERVER=XE;PWD=123456";
- db.setDatabaseName(strDSN);
上面的代码中,TEST是用户名,XE是TNS Service Name. DBQ值填写TNS Service Name, SERVER与DBQ相同即可.
OK,经过上面四步,Qt程序连接
显示汉字可以正常了,写汉字也没
问题(汉字的问题,又涉及到Qt中的汉字问题了)。
5. 解决ora-01861文字与格式字符串不匹配的问题 一开始报这个
错误的时候,我还以为是中文字符串问题,最后一查才知道是Oracle Date类型的问题,即写
SQL的时候,Date类型字段,不要用
QString来代替,而是将其转换为QDate或QDateTime类型,或者是使用PLSQL函数to_date()、to_char()转换,这样就OK了。
6. 关于设置环境变量TNS_ADMIN和NLS_LANG的问题
这两个环境变量可以通过在.bat中设定,然后再.bat中启动.exe来实现,如果不想要这个.bat(要显示一下dos窗口,很不好看),则可以在代码中进行设定,比如在main()函数中Oracle连接前,加入类似下面的代码:
- QDir dir(QCoreApplication::applicationDirPath());
- dir.cdUp();
- dir.cd("etc");
- QString strEtcDir = dir.absolutePath();
- QSettings config(strEtcDir + "/config.ini", QSettings::IniFormat);
- QString strNLS_LANG = config.value("Oracle/NLS_LANG").toString();
- QString strTNS_ADMIN = QDir::toNativeSeparators(strEtcDir);
-
- ::SetEnvironmentVariable(L"NLS_LANG",
- strNLS_LANG.toStdWString().c_str());
- ::SetEnvironmentVariable(L"TNS_ADMIN",
- strTNS_ADMIN.toStdWString().c_str());
上面的代码中,假设我将NLS_LANG的值设定放在../etc/config.ini配置文件中的Oracle/NLS_LANG配置下,而tnsnames.ora文件,则放在../etc目录下,这样就可以通过::SetEnvironmentVariable()函数来分别设定两个NLS_LANG和TNS_ADMIN两个环境变量,这样在这段代码之后再使用QSqlDatabase以ODBC方式连接Oracle就可以了。