对Qt5.4连接Oracle数据的一点看法
2015-05-02 23:24
381 查看
刚学Qt,对它的信号、槽机制打动;一直想写个记账程序,手头上有个现成的Oracle数据,就用它做后台吧。
其实,一直懂Qt连接Oracle数据,上网看了下,公共版不带Oracle驱动,要自己编译;好吧,就来看下怎么编译吧:(跟着大部分人编译的历程,是能编译成功的。)我在Win7下编译。编译需要的头文件[.h]、静态库文件[.lib] ,其实不一定要安装Oracle数据库或客气端,只要去Oracle官网上下载 "instantclient-sdk-nt*.zip" 文件就可以了,里面就有编译所需的文件了。编译中要注意一点:需要在 oci.pro 这个工程文件里加上 "INCLUDEPATH +=
< "oci.h目录"> 、 LIBS += -L < "oci.lib文件夹"> ,做好这些,想怎么编译就怎么编译。
说完编译,就说下重要的连接。连接,这是个困扰我好两周的问题:因为不知道连接,只能参看帮助里的例子,发现连接只有"mysql"的连接;再看网上连接,一个样子;这里我就在想用这种模式,非得知道Oracle数据的主机IP、端口、数据库名称才能连接,那这样用Oracle连接名那种安全、方便的连接方式不是就无用武之地了吗?! 我想这种方式不好,不方便,不安全,得找办法取代这模式。我最初从驱动文件入手,想用改打开数据边参数入手,结果提示 “ORA-12162: TNS: 指定的服务名不正确”、“ORA-12336:
不能连接到数据库 (链接名称 )” 这样不行;我动过封闭OCI,就像封闭OCCI一样,可是,对OCI不工作流程不熟,在网上看了好多封装过程,还是没明白,甚至看官方的OCI说明书,对与我种一句英文句子,10个单词,我只知道1个的我,这个工作量太;后来想参看封装OCCI,可是没找到装的源码做参考,最终放弃了;不行,还是得从Qt入手,针对连接数据库功能下手,虽然不明白怎么连接,但问题就出在那个连接的地方;上代码:(代码片段不能用,直接写了)
bool QOCIDriver::open(const QString & db,
const QString & user,
const QString & password,
const QString & hostname,
int port,
const QString &opts)
{
Q_D(QOCIDriver);
int r;
if (isOpen())
close();
qParseOpts(opts, d);
// Connect without tnsnames.ora if a hostname is given
QString connectionString = db;
if (!hostname.isEmpty())
connectionString =
QString::fromLatin1("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
"(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
r = OCIHandleAlloc(d->env, reinterpret_cast<void **>(&d->srvhp), OCI_HTYPE_SERVER, 0, 0);
if (r == OCI_SUCCESS)
r = OCIServerAttach(d->srvhp, d->err, reinterpret_cast<const OraText *>(connectionString.utf16()),
connectionString.length() * sizeof(QChar), OCI_DEFAULT);
一直以为是参数太多,不方便,看上面的代码发现,还真是每个参数都必须的;一直改那些参数的地方;无果。最后发现
QString connectionString = db;
if (!hostname.isEmpty())
connectionString =
QString::fromLatin1("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
"(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
关键点: if (!hostname.isEmpty()),看明白吧,“hostname” 是可以不要的,只要 “hostname” 参数不传入,就不需要写IP、端口……。
上面的代码是一样的功能,取得“QString connectionString”,这下明白了,连接时不传入参数 “hostname” ;
这下可以一个一个参数试了,一共也就五个参数,去掉 "tnsnames.ora" 封装好的三个参数, 也就只要三个参数(username, Password, "tnsnames.ora -> <Connname> " )。
这下问题解决了。上代码:
QSqlDatabase db = QSqlDatabase::addDatabase("QOCI8");
//db.setHostName("IP");
db.setUserName("user");
db.setPassword("aa");
//db.setPort(1521);
db.setDatabaseName("test");
if(!db.open())
{
QMessageBox::information(NULL, "ErrorInfo", db.lastError().text(), QMessageBox::Ok);
qDebug() << db.lastError().text();
return;
}
QMessageBox::information(NULL, "Conn", "Connect Success! ", QMessageBox::Ok);
qDebug() << db.lastError().text();
……
……
其实,一直懂Qt连接Oracle数据,上网看了下,公共版不带Oracle驱动,要自己编译;好吧,就来看下怎么编译吧:(跟着大部分人编译的历程,是能编译成功的。)我在Win7下编译。编译需要的头文件[.h]、静态库文件[.lib] ,其实不一定要安装Oracle数据库或客气端,只要去Oracle官网上下载 "instantclient-sdk-nt*.zip" 文件就可以了,里面就有编译所需的文件了。编译中要注意一点:需要在 oci.pro 这个工程文件里加上 "INCLUDEPATH +=
< "oci.h目录"> 、 LIBS += -L < "oci.lib文件夹"> ,做好这些,想怎么编译就怎么编译。
说完编译,就说下重要的连接。连接,这是个困扰我好两周的问题:因为不知道连接,只能参看帮助里的例子,发现连接只有"mysql"的连接;再看网上连接,一个样子;这里我就在想用这种模式,非得知道Oracle数据的主机IP、端口、数据库名称才能连接,那这样用Oracle连接名那种安全、方便的连接方式不是就无用武之地了吗?! 我想这种方式不好,不方便,不安全,得找办法取代这模式。我最初从驱动文件入手,想用改打开数据边参数入手,结果提示 “ORA-12162: TNS: 指定的服务名不正确”、“ORA-12336:
不能连接到数据库 (链接名称 )” 这样不行;我动过封闭OCI,就像封闭OCCI一样,可是,对OCI不工作流程不熟,在网上看了好多封装过程,还是没明白,甚至看官方的OCI说明书,对与我种一句英文句子,10个单词,我只知道1个的我,这个工作量太;后来想参看封装OCCI,可是没找到装的源码做参考,最终放弃了;不行,还是得从Qt入手,针对连接数据库功能下手,虽然不明白怎么连接,但问题就出在那个连接的地方;上代码:(代码片段不能用,直接写了)
bool QOCIDriver::open(const QString & db,
const QString & user,
const QString & password,
const QString & hostname,
int port,
const QString &opts)
{
Q_D(QOCIDriver);
int r;
if (isOpen())
close();
qParseOpts(opts, d);
// Connect without tnsnames.ora if a hostname is given
QString connectionString = db;
if (!hostname.isEmpty())
connectionString =
QString::fromLatin1("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
"(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
r = OCIHandleAlloc(d->env, reinterpret_cast<void **>(&d->srvhp), OCI_HTYPE_SERVER, 0, 0);
if (r == OCI_SUCCESS)
r = OCIServerAttach(d->srvhp, d->err, reinterpret_cast<const OraText *>(connectionString.utf16()),
connectionString.length() * sizeof(QChar), OCI_DEFAULT);
一直以为是参数太多,不方便,看上面的代码发现,还真是每个参数都必须的;一直改那些参数的地方;无果。最后发现
QString connectionString = db;
if (!hostname.isEmpty())
connectionString =
QString::fromLatin1("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
"(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
关键点: if (!hostname.isEmpty()),看明白吧,“hostname” 是可以不要的,只要 “hostname” 参数不传入,就不需要写IP、端口……。
上面的代码是一样的功能,取得“QString connectionString”,这下明白了,连接时不传入参数 “hostname” ;
这下可以一个一个参数试了,一共也就五个参数,去掉 "tnsnames.ora" 封装好的三个参数, 也就只要三个参数(username, Password, "tnsnames.ora -> <Connname> " )。
这下问题解决了。上代码:
QSqlDatabase db = QSqlDatabase::addDatabase("QOCI8");
//db.setHostName("IP");
db.setUserName("user");
db.setPassword("aa");
//db.setPort(1521);
db.setDatabaseName("test");
if(!db.open())
{
QMessageBox::information(NULL, "ErrorInfo", db.lastError().text(), QMessageBox::Ok);
qDebug() << db.lastError().text();
return;
}
QMessageBox::information(NULL, "Conn", "Connect Success! ", QMessageBox::Ok);
qDebug() << db.lastError().text();
……
……
相关文章推荐
- Java与Oracle数据连接方法
- ★★彻底搞懂Oracle的左外连接和右外连接(以数据说话)
- Oracle ORA-3137[12333] 关闭的连接 java.sql.SQLRecoverableException: 无法从套接字读取更多的数据 _optim_peek_user_binds
- ssh连接Linux导出oracle数据
- 转载:用oralce连接.net客户端出现问题:“数据连接不成功,请检查该数据库是否已启动尝试加载oracle客户端时引发BadImageFormatException.如果在安装32位Oracle客户端组件的情况下以64位模式运行,”的解
- 关于通过聚集索引以及堆来对比数据表组织结构-SQLServer最优实践 的一点看法
- PLSQLDeveloper连接远程Oracle数据…
- ORACLE UPDATE 语句语法与性能分析的一点看法
- ORACLE多行数据转为一行以,连接
- 通过数据链接(Database Link),从Oracle 9i 连接 SQL Server 2000(实例)
- 经验:搞代码就行了,别乱动数据库(【测试数据要尽量写好一点,只改不删,后期不要轻易删表记录】。关联复杂。oracle报错难以解决)==教训经历如下:
- oracle常见为题汇总,以及一个简单数据连接操作工厂
- 对数据库数据冗余的一点看法
- java连接oracle,完全正确却没有数据
- 用C#通过DatabaseLink连接远程Oracle数据表的错误,及其变通方法
- NET连接不上Oracle数据时的问题。
- Oracle not in子连接查询不到值的问题(not in 不能查询null数据)
- arcgis连接oracle,并向oracle中导入shp数据
- Oracle基础知识(二十三) - 在Oracle的连接视图上进行数据更新操作
- Grails 项目配置数据连接的配置文件的编写 Grails连接Oracle grails连接Mysql 的配置文件