在win10下通过Qt5.12编译Oracle数据库驱动时,打开X:\Qt\Qt5.12.0\5.12.0\Src\qtbase\src\plugins\sqldrivers\oci下的工程文件,在oci.pro文件中更改如下所示:
TARGET = qsqloci
HEADERS += $$PWD/qsql_oci_p.h
SOURCES += $$PWD/qsql_oci.cpp $$PWD/main.cpp
#QMAKE_USE += oci
QMAKE_LFLAGS += oci.lib
darwin:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
OTHER_FILES += oci.json
PLUGIN_CLASS_NAME = QOCIDriverPlugin
include(../qsqldriverbase.pri)
INCLUDEPATH += E:\OCI\include
LIBPATH += E:\OCI\lib\MSVC
需要把Oracle安装包下的OCI目录里面的include和lib的目录添加进来,如果你的电脑没有安装Oracle,那就去已经安装Oracle的电脑上对应的目录拷贝一份即可,然后按照上述代码进行配置即可;
在编译后很可能遇到下述bug:error: use of undeclared identifier 'OCIBindByPos2'
error: use of undeclared identifier 'OCIBindByPos2'
这是因为在Qt5.12里面调用的是OCIBindByPos2()函数,这个函数的第九个参数的数据类型是ub4*,但是根据oracle官方的说法:在这里找到的思路:是新的OCIBindByPos2()函数和以前的OCIBindByPos()函数有一定的区别,为了能在最新的Qt5.12上能成功编译Oracle驱动,我们需要对oci项目下的qsql_oci.cpp的1559行代码附近进行修改如下:
// binding the column
r = OCIBindByPos(
d->sql, &bindColumn.bindh, d->err, i + 1,
bindColumn.data,
bindColumn.maxLen,
bindColumn.bindAs,
bindColumn.indicators,
reinterpret_cast<ub2*>(bindColumn.lengths),
0,
arrayBind ? bindColumn.maxarr_len : 0,
arrayBind ? &bindColumn.curelep : 0,
OCI_DEFAULT);
这么做是将OCIBindByPos2()函数替换成OCIBindByPos()但是OCIBindByPos()函数的第九个参数是ub2*,但是实际上
bindColumn.length实际上是ub4*,因此需要一个强制转换,转换完毕之后,qmake,然后重新生成项目即可,这样就完全解决这个问题了。
重新生成之后就可以在X:\plugins\sqldrivers目录下找到所需要的qsqloci.dll和qsqlocid.dll,这就生成了我们所需要的驱动。然后将驱动放在E:\Qt\Qt5.12.0\5.12.0\msvc2017_64\plugins\sqldrivers目录下,你用那个编译器,就放在那个目录下。比如我用的是msvc2017_64.
将驱动文件放好之后,新建一个工程,测试一下oracle数据库连接:
//连接oracle数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");
db.setPort(1521);
db.setHostName("name");
db.setDatabaseName("ORCL");
db.setUserName("uname");
db.setPassword("pwd");
if (!db.open()) {
qDebug()<< db.lastError().text();
}else{
qDebug()<< u8"链接远程数据库成功";
}
到了这一步,可能会出现两种报错如下:
empty inner name and ver.
Dynamic-----------------screen need SpecialCtrl mon 1
QSqlDatabase: QOCI driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QOCI QOCI8 QODBC QODBC3 QPSQL QPSQL7
"Driver not loaded Driver not loaded"
第二个报错:
inner:
empty inner name and ver.
Dynamic-----------------screen need SpecialCtrl mon 1
QOCIDriver: unable to create environment
" Unable to logon"
出现这两种报错,是因为没有相对于的Oracle库,需要在已经安装Oracle客户端的电脑拷贝两个库文件:oci.dll和oraociei11.dll,将这两个库放到你工程生成的exe目录下,然后重新运行Qt项目。即可成功连接数据库。