368
社区成员




qt开源版默认不自带oci驱动,但是有工程文件,需要自己编译。
工程在C:\Qt\Qt5.14.1\5.14.1\Src\qtbase\src\plugins\sqldrivers\oci目录中。
打开后先对pro文件进行修改
TARGET = qsqloci
HEADERS += $$PWD/qsql_oci_p.h
SOURCES += $$PWD/qsql_oci.cpp $$PWD/main.cpp
#QMAKE_USE += oci 这行注释掉
QMAKE_LFLAGS += D:\app\Administrator\product\11.2.0\dbhome_1\BIN\oci.dll #添加dll,h,lib的路径
INCLUDEPATH += D:\app\Administrator\product\11.2.0\dbhome_1\OCI\include
LIBPATH += D:\app\Administrator\product\11.2.0\dbhome_1\OCI\lib\MSVC
darwin:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
OTHER_FILES += oci.json
PLUGIN_CLASS_NAME = QOCIDriverPlugin
include(../qsqldriverbase.pri)
编译时会报错: OCIBindByPos2’ was not declared in this scop
改成如下:
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);
编译成功,在C:\plugins\sqldrivers目录下生成的libqsqloci.a,qsqloci.dll,qsqloci.dll.debug三个文件,将其拷贝到相应的编译器目录下
C:\Qt\Qt5.14.1\5.14.1\mingw73_64\plugins\sqldrivers (注意编译oci时的编译器和放文件的一致)
在pro文件中添加:
QT += sql
h文件:
#include <QtSql/QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlDriver>
#include <QSqlQueryModel>
private:
QSqlDatabase MSCON;
QSqlQuery MSSQL;
void ConnectDatabase();
cpp文件:
bool MainWindow::ConnectDataBase()
{
MSCON = QSqlDatabase::addDatabase("QOCI"); //加载驱动
MSCON.setHostName("192.168.100.94");
MSCON.setPort(1521);
MSCON.setDatabaseName("DSJ03501"); //实例名
MSCON.setUserName("qgtg");
MSCON.setPassword("qgtg");
if(MSCON.open())
{
addMsg("连接数据库成功");
return true;
}
else
{
addMsg("连接数据库失败");
return false;
}
}
MSSQL = QSqlQuery(MSCON);
MSSQL.exec(select * from xxx); //query也可以取结果值,但是不推荐
QSqlQueryModel *queryModel = new QSqlQueryModel();
queryModel->setQuery(MSSQL);
int counts = queryModel->rowCount(); //用querymodel来获取结果条数,model获取的记录为query查询的全记录
QSqlRecord rec = queryModel->record(j-1); //用QSqlRecord来获取结果值,一次只能获取一行记录
QString str1=rec.value(0).toString(); //获取结果,value的参数可以是索引(从0开始),也可以是字段名(QString)
QSqlQueryModel Mod;
Mod.setQuery("select * from xxx",MSCON); //model也可以直接设置sql语句,这样就少了query步骤,第二参数绑定数据库
当服务器字符集为US7ASCII时,会发现无论是读取中文还是写入中文都是?
这是由于Qt默认的字符编码是utf8,而US7ASCII存的是单字符型,他里面存着的中文实质上是十六进制ASCII码。
我们用plsql所查询看到的中文是经过转化的。
所以我们要读取中文,先要把数据库中的中文字符转换为ASCII码传进程序,再在程序内部将ASCII码转化为中文显示。
1.读取中文
先在sql语句中把要查询的字段转化为ASCII码,这里用到UTL_RAW.cast_to_raw函数例如:
select UTL_RAW.cast_to_raw('测试') from dual --得到结果 B2E2CAD4 这是“测试”的十六进制ASCII码形式
所以在中文字段前加UTL_RAW.cast_to_raw
然后在程序内部做转换,把ascii转为字符。
QString res=QString::fromLocal8Bit(rec.value(0).toByteArray())
2.写入中文
同理,只需将顺序反一下,首先在程序内部将要写入的中文转化为十六进制ASCII码。
QString str="测试";
QByteArray buf=str.toLocal8Bit();
str=buf.toHex();
再在sql语句中将ASCII码转回中文,ASCII转中文的函数为UTL_RAW.cast_to_varchar2,例:
select UTL_RAW.cast_to_varchar2('B2E2CAD4') from dual --得到结果是 “测试”
在参数前加UTL_RAW.cast_to_varchar2函数
其实,我们在开发的电脑上也可以不必装Oracle客户端,只需下载官方basic包和sdk包即可。
basic包里包含了oci.dll
sdk包里包含了oci.lib文件和oci.h文件
所有有这两个包足够我们编译oci驱动了,oci驱动的编译见第一点。
驱动成功编译,连接数据库的程序也写好了,运行时却还是显示QOCI not loaded
很容易想到是没有加载到oci.dll
这里我们不推荐添加环境变量的方式引入oci
我们保持环境变量的清洁,这样可以更清楚的了解连接Oracle都需要哪些库文件。
与之相关的库文件如下:oci.dll,oraociei11.dll这两个文件都是在basic包里的,其中oraociei11.dll足足有125m
可以想象我们不装客户端却可以连上Oracle基本靠他了。
还有qsqloci.dll这个是我们自己编译的oci驱动,一般在相应编译器目录的plugins\sqldrivers下,我们把这两层目录
新建在运行程序相同的目录,把qsqloci.dll放在里面,并在程序中指定该路径。
在main.cpp里做修改:
QApplication a(argc, argv);
QApplication::setLibraryPaths(QStringList(QApplication::applicationDirPath()+"/plugins/"));//添加了这句
MainWindow w;
w.show();
return a.exec();
再在运行程序目录下引进其他qt库,就可以连接上数据库了。