简述
最近一段时间在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 。
完结!