Qt连接Oracle并读写中文

戏言zare [ 铁皮渔船建造者 ] 2022-09-29 13:49:22

一、编译oci驱动

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时的编译器和放文件的一致)

二、连接Oracle

在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步骤,第二参数绑定数据库

三、关于Qt对US7ASCII字符集数据的读取和写入

当服务器字符集为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函数

四、进阶-Qt编译的连接Oracle的程序如何在没有任何环境的电脑上运行并且成功连接数据库

其实,我们在开发的电脑上也可以不必装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库,就可以连接上数据库了。

...全文
18 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
相关推荐
发帖
程序员 · 1号螺丝厂

371

社区成员

程序员聚集地,梦想奋斗工厂!
前端后端 个人社区 浙江省·杭州市
社区管理员
  • 削尖的螺丝刀
  • Minecraft__Him
  • 馆主阿牛
加入社区
帖子事件
创建了帖子
2022-09-29 13:49
社区公告
暂无公告