Qt使用Oracle数据库踩坑教程

avatar
作者
筋斗云
阅读量:8

简述

最近一段时间在Qt中使用Oracle数据库积累了一些踩坑过程,以及qt使用Oracle数据库的一些操作。

目录

1. Oracle数据库安装 Oracle数据库安装教程点击跳转。 2. Oracle数据库安装注意事项 数据库安装的跳转连接安装教程采用的是Oracle11g数据库,如果是服务器级别的建议采用更高版本的Oracle比如19c。安装过程中的全局数据库名会作为Qt连接Oracle的配置项,需谨记,(无需关心大小写问题)。 3. Qt配置Oracle数据库 Qt配置Oracle数据库点击跳转。此教程使用Qt编译器,编译qt的oci源码,生成dll库。我个人使用的是vs2015编译的oci源码,数据库为19c版本,pro为以下格式,仔细检查每个路径文件是否存在

TARGET = qsqloci
HEADERS += $$PWD/qsql_oci_p.h
SOURCES += $$PWD/qsql_oci.cpp $$PWD/main.cpp
#根据Oracle客户端安装路径 指定oci.dll
QMAKE_LFLAGS +=D:/WINDOWS.X64_193000_db_home/oci/lib/msvc/oci.lib
#根据Oracle客户端D安装路径 指定头文件目录
INCLUDEPATH += D:/WINDOWS.X64_193000_db_home/oci/include
#根据安装的Oracle客户端指定libPath
LIBPATH += D:/WINDOWS.X64_193000_db_home/oci/lib/MSVC
darwin:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
OTHER_FILES += oci.json
PLUGIN_CLASS_NAME = QOCIDriverPlugin
include(../qsqldriverbase.pri)

个人生成dll目录为C:\Qt\Qt5.9.3\5.9.3\Src\qtbase\src\plugins\sqldrivers\plugins\sqldrivers

qsqloci.dll和qsqlocid.dll将dll库拷贝到编译目录下即可。 4. Qt操作Oracle数据库 Qt连接Oracle数据库

	QSqlDatabase db = QSqlDatabase::addDatabase("QOCI", connectName);
	db.setHostName("localhost");
    db.setDatabaseName("ORCL");//安装时全局数据库名
    db.setUserName("system");
    db.setPassword("xiaoxin521");
    db.setPort(1521);

Qt查找Oracle表是否存在

1.QSqlDatabase的tables可以返回所有表,然后使用contains可以判断是否存在,这里强烈不建议使用此方式,很耗时,Oracle自带表很多。

2.通过一下sql语句可查询Oracle表,**注意:如果Oracle当前使用的库名中表非常多,此方式也会比较耗时,亲测!,可考虑第三种方式**
	bool ret = false;
    QString qSqlString =  QString("select count(*) from user_tables where upper(table_name) = upper('%1')").arg(talbename);
    QSqlQuery query(qSqlString, database);
    ret  = query.exec();
    if (ret) {
        while (query.next()) {
            ret = query.value(0).toBool();
        }
    }
    return ret;

3.第三种方式是采用表中表名,创建一个存储表名的表,用来判断该表是否存在,此方式时间优化很高,代码量需增加。

Qt创建Oracle表,创建自增列,不支持double类型,需要用其他类型代替。我个人使用的float足够了,不够需要用Oracle的number类型具体没用过。

①.创建表正常操作即可,这里主要是想介绍一下创建自增列。

②.首先创建表,id主键,创建成功后需要创建表序列看一下代码,序列sql语句参数可根据Oracle需求修改。

	QString qSqlString = "create table "+talbename+" ("
                                                   "id int PRIMARY KEY,"
                                                   "time timestamp)";
    QSqlQuery query(qSqlString, database);
    bool ret = query.exec();
    if(!ret)
    {
        //
    }
    else {
        QString sequence = "create sequence " + talbename +"_seq "
                                                           "increment by 1 "
                                                           "start with 1 "
                                                           "maxvalue 1000000 "
                                                           "minvalue 1 "
                                                           "nocache "
                                                           "nocycle";
        QSqlQuery querySequence(sequence, database);
        ret = querySequence.exec();
        if(!ret)
        {
            //
        }
    }
    return ret;

使用自增列

①当插入数据的时候,values第一个值为id,插入方式如下图。

QString qSqlString="insert into "+talbename+ QString(" values(%1,?)").arg(talbename + "_seq.nextval");

Qt使用Oracle存储时间类型

①创建表中存在time字段方便与根据时间来查询数据,在Oracle中使用timestamp类型,如③中实例,插入数据直接addBindValue一个QDateTime类型即可。

②根据时间查询数据,下面只贴sql语句,time为字段,%1为表名%2为需要查询的开始时间%3位结束时间,该sql语句是Oracle的标准语句,改为Qt方式使用。

		QDateTime stopTime= tempData.time.addDays(1);
        QString qSqlString = QString("select * from %1 WHERE time between to_date('%2','yyyy/MM/dd') and to_date('%3','yyyy/MM/dd')")
                .arg(tableName)
                .arg(tempData.time.toString("yyyy-MM-dd"))
                .arg(stopTime.toString("yyyy-MM-dd"));

Qt批量插入数据到Oracle

下面贴一个批量插入数据的实例,这里要说明一下,当创建表使用的float类型时候批量插入数据时不支持float类型,需要转为double否则会报错ORA-00932。

	QString qSqlString = "create table test (id float)";
	
	QVariantList varList;
    for (double i = 0.1001 ; i < 100000000.0; i+=100.1001) {
        varList<< 1.12;
    }
    String qSqlString= "insert into test(id) values(:id)";
    
    QSqlQuery query(getSqlConnect("xiaoxin"));
    query.prepare(qSqlString);
    query.bindValue(":id", varList);
    qDebug() <<  query.execBatch() << varList.size();

获取Oracle最后一条数据

如果使用,自增列,那么使用以下方式获取最后的数据然后再进行批量插入。

	QString qSqlString = "SELECT * FROM (SELECT * FROM test ORDER BY id DESC) WHERE ROWNUM = 1";
    QSqlQuery query(getSqlConnect("xiaoxin"));
    query.prepare(qSqlString);
    qDebug() << query.exec() ;
    qDebug() << query.next() ;
    qDebug() << query.value("id").toInt();

关于对Oracle数据库插入大量数据

①如果对Oracle插入大数据量时发现很慢可看以下建议

②无需频繁获取Oracle进程,使用几个即可。

③数据非常建议打包后(批量处理),使用一个QSqlDatabase对象来批量数据数据。 5.关于Qt使用Oracle报错 Oracle表名不能超过30个字符。ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的SID等错误解决方法,此问题如果没有修改过Oracle的配置文件,解决方法需要->重启软件->重启Qt->重启电脑即可解决问题。ORA-12518:监听程序无法分发客户机连接,可能是代码中获取Oracle进程过多,百度修改进程数量或者修改代码。ORA-12560: TNS: 协议适配器错误的解决方法,此问题最为头疼的一个问题,记得看过官方解释说该问题未得到解决,解决方法为如果是低版本此问题百度无法解决,那么升级为19c基本上是可以解决的,或者重装系统以及重装数据库。ORA-01652:无法通过1024(在表空间SYSTEM中):该问题是oracle的表空间DBF存储文件达到了限制,查看该博客增加基础知识点击,Oracle的DB_BLOCK_SIZE大小根据操作系统来决定,我个人使用Oracle19安装后是8k,正常情况下只支持32G数据,解决方案如下。

1.创建bigfile ORCL为表空间名 datafile为存储的文件路径 size为初始大小
create bigfile tablespace ORCL datafile 'D:\app\oradata\SYSTEM\ORCL01.DBF'  size 500M  autoextend on;
2.创建一个用户ORCL,结尾ORCL是表空间名
create user ORCL identified by Admin123 default tablespace ORCL;
3.给用户授权
grant connect , resource,dba to ORCL;
4.查询该用户的表空间使用名称
SELECT default_tablespace from dba_users where username = 'ORCL';
5.如果不是ORCL改一下,然后commit提交一下。
alter user ORCL  default tablespace ORCL;

操作以上步骤后,需要使用该用户即可。

6.查询工具介绍 使用PLSQL Developer 13查询Oracle数据特别方便链接如下,包含中文教程,破解。跳转提取码:oucb 。

完结!

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!