Reputation: 47
I have a server of windows server 2003 and its IP on my local network is 192.168.1.220 This server has SOL server 2005 express edition installed. This SQL server has a database called amir.
I want to connect to it from a Linux client on the same network. SQL server service using port 1617 on my server and I used this port to connect to the server using java.
Wow i want to use QT C++ but my code doesn't work.
This is my code:
#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;
}
Every time i try this it out "not connected" and the error is
[unixODBC][Driver Manager]Data source name not found, and no default driver specified QODBC3: Unable to connect
Using these parameters I can connect using java
So what is the wrong here? and if there is another fasting way to connect to the SQL server using qt c++ than ODBC driver.
Upvotes: 1
Views: 4350
Reputation: 9789
You need to setup a data source name on your server to connect through ODBC. Here is some code that I use to setup a 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));
Here is some code that I forgot to put in the initial post:
#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
This code creates the .odbcinst.ini file in your home directory if it doesn't exist and adds an entry for FreeTDS. If it does exist, it will append to the end of the file. If an entry for FreeTDS exists in the file already, it will update the existing file. Here's a guide for setting up FreeTDS if you haven't already: http://pzuk.wordpress.com/2012/02/03/how-to-make-freetds-unixodbc-and-qt-working-together/
Note, that the code for configuring FreeTDS that I posted is only required if you want to bundle FreeTDS with your application and have the libary path setup correctly from where you launch. It runs as a standard user and not as root so everything is done in the local user account.
Upvotes: 1