您的位置:首页 > 数据库 > Oracle

对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();

……

……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐