• 7724阅读
  • 1回复

Qt使用Oracle ODBC Driver连接 [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2013-06-28
关键词: ODBCOracle
原文见:http://hi.baidu.com/xchinux/item/5dd91dd578684938e3108f9b


1. 安装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.html


Version 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,这样就行了。
  1. XE =
  2.   (DESCRIPTION =
  3.       (ADDRESS = (PROTOCOL = TCP)(HOST = BJP-X200)(PORT = 1521))
  4.       (CONNECT_DATA =
  5.           (SERVER = DEDICATED)
  6.         (SERVICE_NAME = XE)
  7.      )
  8.   )
  9.                 
  10. EXTPROC_CONNECTION_DATA =
  11.   (DESCRIPTION =
  12.       (ADDRESS_LIST =
  13.           (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
  14.     )
  15.     (CONNECT_DATA =
  16.         (SID = PLSExtProc)
  17.          (PRESENTATION = RO)
  18.     )
  19.   )
  20.                 
  21. ORACLR_CONNECTION_DATA =
  22.   (DESCRIPTION =
  23.     (ADDRESS_LIST =
  24.       (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
  25.     )
  26.     (CONNECT_DATA =
  27.       (SID = CLRExtProc)
  28.       (PRESENTATION = RO)
  29.     )
  30.   )


3. 设置NLS_LANG环境变量
在服务器端执行一下下面的语句,将其值设置给NLS_LANG环境变量即可(在我的环境上,它的值是"SIMPLIFIED CHINESE_CHINA.AL32UTF8")
  1. select userenv('language') from dual


4. 在odbcad32.exe管理器中,建立数据源(实际上也可以通过odbcconf.exe来动态设置用户数据源,或自己写个文件数据源,注意,如果是32位的,则在win64上,要使用C:\windows\syswow64\odbcad32.exe来配置ODBC数据源)如果不使用数据源(包括文件数据源),则可以使用DSN字符串(自己建个文件数据源,然后打开那个.dsn文件,照抄下来),如下所示:

  1. QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
  2. QString strDSN = "DRIVER={Oracle in instantclient_11_2};UID=TEST;DBQ=XE;SERVER=XE;PWD=123456";
  3. 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连接前,加入类似下面的代码:
  1. QDir dir(QCoreApplication::applicationDirPath());
  2. dir.cdUp();
  3. dir.cd("etc");
  4. QString strEtcDir = dir.absolutePath();
  5. QSettings config(strEtcDir + "/config.ini", QSettings::IniFormat);
  6. QString strNLS_LANG = config.value("Oracle/NLS_LANG").toString();
  7. QString strTNS_ADMIN = QDir::toNativeSeparators(strEtcDir);
  8.   
  9. ::SetEnvironmentVariable(L"NLS_LANG",
  10.         strNLS_LANG.toStdWString().c_str());
  11. ::SetEnvironmentVariable(L"TNS_ADMIN",
  12.         strTNS_ADMIN.toStdWString().c_str());

上面的代码中,假设我将NLS_LANG的值设定放在../etc/config.ini配置文件中的Oracle/NLS_LANG配置下,而tnsnames.ora文件,则放在../etc目录下,这样就可以通过::SetEnvironmentVariable()函数来分别设定两个NLS_LANG和TNS_ADMIN两个环境变量,这样在这段代码之后再使用QSqlDatabase以ODBC方式连接Oracle就可以了。


二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线912890618@qq

只看该作者 1楼 发表于: 2014-10-24
正需要。
快速回复
限100 字节
 
上一个 下一个