通过 QT C++ 连接到 SQL server 2005

Posted

技术标签:

【中文标题】通过 QT C++ 连接到 SQL server 2005【英文标题】:Connecting to SQL server 2005 through QT C++ 【发布时间】:2012-09-30 10:05:28 【问题描述】:

我有一台 windows server 2003 的服务器,它在我的本地网络上的 IP 是 192.168.1.220 此服务器已安装 SOL server 2005 express edition。此 SQL 服务器有一个名为 amir 的数据库。

我想从同一网络上的 Linux 客户端连接到它。 SQL server 服务在我的服务器上使用端口 1617,我使用此端口使用 java 连接到服务器。

哇,我想使用 QT C++,但我的代码不起作用。

这是我的代码:

#include <QtCore/QCoreApplication>
#include <iostream>
#include <QSqldatabase>
#include <QSqldriver>
int main(int argc, char *argv[])

   QCoreApplication a(argc, argv);
   QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
   bool test=db.isValid();//true
   test=db.isDriverAvailable("QODBC");//true
   db.setHostName("192.168.1.220\\SQLEXPRESS");
   db.setDatabaseName("DRIVER=SQL Server;SERVER=192.168.1.220\\SQLEXPRESS:1617;DATABASE=amir");
   db.setUserName("sa");
   db.setPassword("amir");
   db.setPort(1617);
   test=db.isValid();//true
   if(!db.open())
   
      cout<<endl<<"not connected"<<endl;
      QString error=db.lastError().text();
      cout<<error.toLocal8Bit().data();
      return false;
   
   else
      cout<<endl<<"connected"<<endl;
      return true;
 

每次我尝试它“未连接”并且错误是

[unixODBC][Driver Manager]未找到数据源名称,未指定默认驱动程序 QODBC3:无法连接

使用这些参数我可以使用 java 连接

那么这里有什么问题吗?以及是否有另一种使用 qt c++ 连接到 SQL 服务器的快速方法,而不是 ODBC 驱动程序。

【问题讨论】:

您必须使用 QODBC 插件配置您的 Qt(您需要添加选项 -qt-sql-odbc 或 -plugin-sql-odbc) 你的意思是我需要在我的 linux 上安装 qt-sql-odbc 并首先配置它以连接到我服务器上的 sql server 吗?就像我在 Windows XP 上的 ODBC 管理一样>? 这个插件安装在我的 linux 上,我如何配置 QODBC?以及如何更改我的代码 【参考方案1】:

您需要在服务器上设置数据源名称才能通过 ODBC 连接。这是我用来设置 DSN 的一些代码:

QString SQLServerProvider::buildDSN(QString server, QString database, QString username, QString password)

#ifdef Q_WS_MACX
    QString dsn = QString("DRIVER=/usr/local/lib/libtdsodbc.so;SERVER=%1;TDS_VERSION=8pClient;DATABASE=%2;PORT=1433;UID=%3;PWD=%4;").arg(server).arg(database).arg(username).arg(password);
#endif

#ifdef Q_WS_X11
    QString dsn = QString("DRIVER=FreeTDS;SERVER=%1;TDS_VERSION=8.0;PORT=1433;DATABASE=%2;UID=%3;PWD=%4;").arg(server).arg(database).arg(username).arg(password);
#endif

#ifdef Q_WS_WIN
    QString dsn = QString("DRIVER=SQL SERVER;SERVER=%1;DATABASE=%2;UID=%3;PWD=%4;").arg(server).arg(database).arg(username).arg(password);
#endif
    return dsn;

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", databaseName);
db.setDatabaseName(buildDSN(server, database, username, password));

这是我在最初的帖子中忘记放入的一些代码:

    #ifdef Q_WS_X11
    QString dir = QDir::homePath();
    QDir d;
    QString libdir = d.absolutePath();

    QFile odbcinst(dir + "/.odbcinst.ini");
    if(!odbcinst.exists())
    
        odbcinst.open(QIODevice::WriteOnly | QIODevice::Text);
        QTextStream out(&odbcinst);
        out << "[FreeTDS]\n";
        out << "Description = v0.91 with protocol v8.0\n";
        out << "Driver = " + libdir + "/libtdsodbc.so\n";
        out << "Setup = " + libdir + "/libtdsodbc.so\n";
        out << "FileUsage = 1";
        odbcinst.close();
    
    else
    
        QList<QString> lines;

        odbcinst.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream readfile(&odbcinst);

        int i = 0, lnbr = 0;
        bool found = false;
        while(!readfile.atEnd())
        
            QString line = readfile.readLine();
            if(line.contains("[FreeTDS]"))
            
                lnbr = i;
                found = true;
            
            lines.append(line);
            i++;
        
        odbcinst.close();

        // append to end
        if(!found)
        
            // append to the end
            odbcinst.open(QIODevice::Append | QIODevice::Text);
            QTextStream file(&odbcinst);

            file << "\n[FreeTDS]\n";
            file << "Description = v0.91 with protocol v8.0\n";
            file << "Driver = " + libdir + "/libtdsodbc.so\n";
            file << "Setup = " + libdir + "/libtdsodbc.so\n";
            file << "FileUsage = 1";
            odbcinst.close();
        
        else // update existing entry
        
            qDebug() << "Found an entry for FreeTDS. Updating driver to " + libdir + "/libtdsodbc.so.";
            qDebug() << lines[lnbr+2];
            qDebug() << lines[lnbr+3];

            lines.replace(lnbr + 2, "Driver = " + libdir + "/libtdsodbc.so");
            lines.replace(lnbr + 3, "Setup = " + libdir + "/libtdsodbc.so");

            QString text;
            for(int j = 0; j < lines.count(); j++)
            
                text.append(lines[j] + "\n");
            

            odbcinst.open(QIODevice::WriteOnly | QIODevice::Text);
            QTextStream updatefile(&odbcinst);
            updatefile << text;
            odbcinst.close();
        

    
#endif

如果 .odbcinst.ini 文件不存在,此代码会在您的主目录中创建该文件,并为 FreeTDS 添加一个条目。如果确实存在,它将附加到文件的末尾。如果文件中已经存在 FreeTDS 条目,它将更新现有文件。如果您还没有设置 FreeTDS,这里有一个指南:http://pzuk.wordpress.com/2012/02/03/how-to-make-freetds-unixodbc-and-qt-working-together/

请注意,我发布的用于配置 FreeTDS 的代码仅在您希望将 FreeTDS 与您的应用程序捆绑在一起并且从您启动的位置正确设置库路径时才需要。它以标准用户而非 root 用户身份运行,因此一切都在本地用户帐户中完成。

【讨论】:

以上是关于通过 QT C++ 连接到 SQL server 2005的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Qt 库连接到标准 C++ 项目?

将 qml 信号连接到 Qt

Qt C++ 将带有非空签名的信号连接到 lambda

如何在不将其连接到终端的情况下运行“屏幕”,以便可以在 C++ (qt) 应用程序中捕获输出?

服务器重新启动后重新连接到 QDBus 服务器 (Qt C++)

如何从 C++ 端连接到 QML 项目的 onClick 事件