本人Qt版本为5.14.2,编译器分别使用MingGW7.3.0 64位和MSVC2017 64位尝试,均可以正常编译,以下步骤为个人记录,如有错误敬请指出!谢谢
详细文件点击下载(下载链接)
1.打开 C:\Qt\Qt5.14.2\5.14.2\Src\qtbase\src\plugins\sqldrivers\oci\oci.pro,更改pro文件,以下分别为两种不同编译器的更改方法,特别注意oracle sdk的路径设置
//这里是MinGW配置
//这里是MinGW配置
//这里是MinGW配置
TARGET = qsqloci
HEADERS += $$PWD/qsql_oci_p.h
SOURCES += $$PWD/qsql_oci.cpp $$PWD/main.cpp
#QMAKE_USE += oci
darwin:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
OTHER_FILES += oci.json
PLUGIN_CLASS_NAME = QOCIDriverPlugin
include(../qsqldriverbase.pri)
//路径根据oracle sdk包解压路径选择
INCLUDEPATH += C:\Qt\Oracle_11\instantclient_11_2\sdk\include
LIBS += -LC:\Qt\Oracle_11\instantclient_11_2\sdk\lib\msvc -loci
//这里是MSVC配置
//这里是MSVC配置
//这里是MSVC配置
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)
//路径根据oracle sdk包解压路径选择
INCLUDEPATH += C:\Qt\Oracle_11\instantclient_11_2\sdk\include
LIBPATH += C:\Qt\Oracle_11\instantclient_11_2\sdk\lib\msvc
更改完成后,编译运行,如果顺利的话会在C盘根目录下生成Qt可用的dll驱动文件,图中为MinGW编译出的,MSVC类似
将上图中的qsqlpci.dll,放到Qt的安装目录的指定编译器目录下,图中是mingw编译器,正常来说应该不用放libqsqloci.a文件。
2.错误解决(参考链接)
error: use of undeclared identifier 'OCIBindByPos2'
这是因为在Qt5.14里面调用的是OCIBindByPos2()函数,这个函数的第九个参数的数据类型是ub4*,但是根据oracle官方的说法:在这里找到的思路:是新的OCIBindByPos2()函数和以前的OCIBindByPos()函数有一定的区别,为了能在最新的Qt5.14上能成功编译Oracle驱动,我们需要对oci项目下的qsql_oci.cpp的1559行代码附近进行修改如下:
// binding the column
// r = OCIBindByPos2( //xzm1228
r = OCIBindByPos(
d->sql, &bindColumn.bindh, d->err, i + 1,
bindColumn.data,
bindColumn.maxLen,
bindColumn.bindAs,
bindColumn.indicators,
// bindColumn.lengths,//xzm1228
reinterpret_cast<ub2 *>(bindColumn.lengths),
0,
arrayBind ? bindColumn.maxarr_len : 0,
arrayBind ? &bindColumn.curelep : 0,
OCI_DEFAULT);
新建工程
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
OracleConnectTest.cpp
HEADERS += \
OracleConnectTest.h
FORMS += \
OracleConnectTest.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
#include "OracleConnectTest.h"
#include "ui_OracleConnectTest.h"
#include
#include
OracleConnectTest::OracleConnectTest(QWidget *parent)
: QWidget(parent)
, ui(new Ui::OracleConnectTest)
{
ui->setupUi(this);
}
OracleConnectTest::~OracleConnectTest()
{
delete ui;
}
//UI的按钮点击槽函数
void OracleConnectTest::on_pushButton_clicked()
{
qDebug()<<QSqlDatabase::drivers();
QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");
db.setHostName("192.168.101.xxx");//注意不要输错了,我这个错误导致检查了一个小时。。。。。
db.setPort(1521);
db.setDatabaseName("orcl");
db.setUserName("xxxxx");//自己的用户名
db.setPassword("xxxxxx");//对应的用户密码
qDebug()<<"Connecting to oracle....";
if(!db.open())
{
qDebug()<<db.lastError().text();
}
else
{
qDebug()<<"Connect success!";
}
}
注意!点击运行后会遇到如下报错,这是因为没有将oci的dll文件放到软件执行目录下
QSqlDatabase: QOCI driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL3 QOCI QOCI8 QODBC QODBC3 QPSQL QPSQL7
“Driver not loaded Driver not loaded”
打开oracle的解压目录,复制图中dll文件到编译的软件执行目录下
然后再次运行,出现以下输出表示运行成功!
如有错误,敬请指出~,本文主要写了MinGW的编译过程,MSVC本人试过一样的。