对Qt5.4连接Oracle数据的一点看法

        刚学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();

     ……

……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值