Win7 Qt5.4.1+VS2013编译Oracle驱动,连接Oracle数据库

来源:互联网 发布:豆瓣淘宝卖家讨论区 编辑:程序博客网 时间:2024/04/30 07:23
Qt开发环境描述,​Qt版本是qt-opensource-windows-x86-msvc2013-5.4.1,安装时已选择安装源码,安装目录是D:\Tools\Qt5.4.1。
Oracle客户端描述,登录Oracle官网http://www.oracle.com/technetwork/topics/winsoft-085727.html,下载sdk  Windows版,
instantclient-sdk-nt-12.1.0.2.0.zip 和 运行环境 instantclient-basic-nt-12.1.0.2.0.zip。
instantclient-sdk-nt-12.1.0.2.0.zip解压后,就得到Oracle客户端的开发包,我的解压目录是D:\oracle\sdk



进入目录D:\Tools\Qt5.4.1\5.4\Src\qtbase\src\plugins\sqldrivers\oci,使用VS2013打开oci.pro,
并设置头文件的包含目录是D:\oracle\sdk\include,附加库目录需要包含D:\oracle\sdk\lib\msvc,链接库的附加依赖项加入oci.lib。
注意,如果不包含oci.lib会报告一堆“无法解析外部符号 OCIXXXX”的错误信息。
按下快捷键F7开始构建,最终报错“无法解析的外部符号”。这是因为Qt头文件包含出错导致,具体原因不明(可能包含了Qt源码的头文件导致混乱)。



打开项目属性,看到附加包含目录的内容



修改后如下图所示,其中5.4.1是我安装的Qt的版本号,可根据情况自行修改,如果目录不对会报告“无法打开包含文件”的错误。



设置好后,按下F7,就会编译成功,我们目前编译的是Debug版本


到目录D:\Tools\Qt5.4.1\5.4\Src\qtbase\plugins\sqldrivers中找到刚刚生成的qsqlocid.dll,拷贝到D:\Tools\Qt5.4.1\5.4\msvc2013\plugins\sqldrivers中。如果需要发布应用程序,那么在应用程序所在的目录中新建文件夹sqldrivers,把qsqlocid.dll拷贝进行就可以了。



建立Qt控制台程序测试一下(例子摘自网上)

#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QCoreApplication>
#include <QLibrary>

/**连接Oracle数据库
*数据库名:abc
*表名:my_oracle
*用户名:system
*密码:123
*端口号:(默认)1521
*/
void connectOracle(QString sIp, int iPort, QString sDbNm, QString sUserNm, QString sPwd)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");
db.setHostName(sIp);
db.setPort(iPort);
db.setDatabaseName(sDbNm);
db.setUserName(sUserNm);
db.setPassword(sPwd);
if (db.open())
{
qDebug() << "success\n";
}
else
{
qDebug() << "error_Oracle:\n" << db.lastError().text();
return;
}

//查询语句  
QSqlQuery query("select IPCID,IPCName,IPCRtspAddrMain from IPCInfo");
while (query.next())
{
QString id = query.value(0).toString();
QString name = query.value(1).toString();
qDebug() << id << " --- " << name;
}
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QStringList lists = QSqlDatabase::drivers();

for (int i = 0; i < lists.size(); ++i)
{
qDebug() << lists.at(i);
}

connectOracle("192.168.0.1", 1521, "dbname", "user", "pwd");

return a.exec();
}
编译运行后,连接Oracle数据库成功,并查询出数据。这儿我编译的是32位的驱动,连接的是64位的Oracle 11g。


不要高兴地太早,这事还没有完。

把程序发布后,运行,报告"QOCI driver not loaded"



怎么回事呢?百度后知道了答案,见这位网友的博客连接http://blog.csdn.net/luozhuang/article/details/38400239

还记得刚开始下载的文件instantclient-basic-nt-12.1.0.2.0.zip吗?这个就是oracle的运行环境,加压到D:\oracle_run目录中
然后在代码开始的位置加入以下代码
QLibrary *hello_lib = NULL;
hello_lib = new QLibrary("D:\\oracle_run\\oci.dll");
//加载动态库  
hello_lib->load();
if (!hello_lib->isLoaded())
{
qDebug() << "load Oracle failed!\n";
return;
}
再次编译运行,终于连接上Oracle数据库并且查询到数据了。这只是在Win7下可以正常运行,如果把程序发布到Xp运行,会报告一个错误
“无法定位程序输入点WSAPoll于动态链接库WS2-32.DLL上”,原因就是xp下面的ws_32.dll不包含WSAPoll这个API。那么把win7下面的ws3_32.dll
拷贝到xp中可以吗?当然不可以。我猜Oracle最新的运行环境使用了新技术,可能不能运行在XP中了,但它原先的运行环境肯定能运行在XP中,那就
将运行环境降级,一个一个地试一试。
找到oracle 11g最早的客户端instantclient-basic-win32-11.1.0.6.0.zip,测试了一下,很不错,测试程序能运行在xp、win7(32/64位)、win10中,成功连接数据库,获取数据。如果你嫌运行时太大,可以把不必要的文件都删除掉,其实也省不了多大的空间,因为最大的文件oraociei11.dll(100M)不能去掉。

最终测试代码如下

#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QCoreApplication>
#include <QLibrary>

/**连接Oracle数据库
*数据库名:abc
*表名:my_oracle
*用户名:system
*密码:123
*端口号:(默认)1521
*/
void connectOracle(QString sIp, int iPort, QString sDbNm, QString sUserNm, QString sPwd)
{
QLibrary *hello_lib = NULL;
hello_lib = new QLibrary(qApp->applicationDirPath() + "/oracle/oci.dll");
//加载动态库  
hello_lib->load();
if (!hello_lib->isLoaded())
{
qDebug() << "load Oracle failed!\n";
return;
}

QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");
db.setHostName(sIp);
db.setPort(iPort);
db.setDatabaseName(sDbNm);
db.setUserName(sUserNm);
db.setPassword(sPwd);
if (db.open())
{
qDebug() << "success\n";
}
else
{
qDebug() << "error_Oracle:\n" << db.lastError().text();
return;
}

//查询语句  
QSqlQuery query("select IPCID,IPCName,IPCRtspAddrMain from IPCInfo");
while (query.next())
{
QString id = query.value(0).toString();
QString name = query.value(1).toString();
qDebug() << id << " --- " << name;
}
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QStringList lists = QSqlDatabase::drivers();

for (int i = 0; i < lists.size(); ++i)
{
qDebug() << lists.at(i);
}

connectOracle("192.168.0.7", 1521, "orcl", "icms", "icms");

return a.exec();
}




0 0
原创粉丝点击