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.
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.
Related
I develop Qt application in C++ under manjaro linux. The goal is to connect with a qC (Nucleo-L476RG Board) and receive data from accelerometer. App can find device on /dev/ttyACM0, but when i try to connect it fails with error "QSerialPort::DeviceNotFoundError". Checking errorString() gives "No such file or directory", but it still can find it in /dev.
I'm in the right group to read the file:
[1]: https://i.stack.imgur.com/CG1yZ.png
I use Qt v.6.2.4, but have build the code with Qt v.5.15.3. I tried to run another person's app that does the same and works under ubuntu, but it didn't work.
Here is my code with the searching and connecting methods. Method addToLogs() just prints logs in textEdit.
void MainWindow::addToLogs(QString message)
{
QString currDateTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
ui->textEditLogs->append(currDateTime + "\t" + message);
}
void MainWindow::on_pushButtonSearch_clicked()
{
ui->comboBoxDevices->clear();
this->addToLogs("Szukam urządzeń...");
QList<QSerialPortInfo> devices;
devices = QSerialPortInfo::availablePorts();
if(devices.count() > 0)
{
for(int i=0; i<devices.count(); i++)
{
this->addToLogs(devices.at(i).portName());// + " " + devices.at(i).description());
//ui->comboBoxDevices->addItem(devices.at(i).systemLocation());//portName());
ui->comboBoxDevices->addItem(devices.at(i).portName());
}
}
}
void MainWindow::on_pushButtonConnect_clicked()
{
if(ui->comboBoxDevices->count() == 0)
{
this->addToLogs("Nie wykryto żadnych urządzeń!");
return;
}
if(this->device->isOpen())
{
this->addToLogs("Port jest już otwarty!");
return;
}
QString portName = ui->comboBoxDevices->currentText();
//this->device->setPortName(portName);
this->device->setPortName("/dev/ttyACM0");
qDebug() << this->device->portName();
if(device->open(QSerialPort::ReadWrite))
{
this->device->setBaudRate(QSerialPort::Baud9600);
this->device->setParity(QSerialPort::NoParity);
this->device->setDataBits(QSerialPort::Data8);
this->device->setStopBits(QSerialPort::OneStop);
this->device->setFlowControl(QSerialPort::NoFlowControl);
this->addToLogs("Połączono z urządzeniem " + portName);
}
else
{
this->addToLogs("Otwarcie portu szeregowego się nie powiodło!");
this->addToLogs(device->errorString());
qDebug() << this->device->error();
}
}
I will be thankful for help, cause i've benn sitting on it for last 2 or 3 weeks and nothing works.
I have a problem with a QSqlQuery when I execute a source command on my database.
This code works :
QString myRequest = "CREATE DATABASE MY_DATABASE;";
lQueryResult.Exec(myRequest);
if(!lQueryResult.GetMexec())
{
qDebug() << "Error in the request";
return false;
}
else
{
qDebug() << "The request is OK";
}
This code doesn't works, I have a syntax error :
You have an error in
your SQL syntax; check the manual that corresponds to your MariaDB
server version for the right syntax to use near 'source
./folder/myFile.sql' at line 1 QMYSQL: Unable to execute query
This is the code :
myRequest = "source myFile.sql";
lQueryResult.Exec(myRequest);
if(!lQueryResult.GetMexec())
{
qDebug() << "Error";
qDebug() << lQueryResult.LastError();
return false;
}
else
{
qDebug() << "OK";
}
I can successfully do my source with this command :
QString lCommand("mysql -uUsername -pPassword Data_Base -e \"source " + variablePath + variableFile + ".sql\"");
system(lCommandeProvisoire.toStdString().c_str());
I have no error. But, if I execute this code juste after, I have the error
No database selected QMYSQL: Unable to execute query
:
TheRequest = "SELECT * FROM MyTable;";
QueryResult.Exec(TheRequest);
if(!QueryResult.GetMexec())
{
qDebug() << QueryResult.LastError();
return false;
}
else
{
qDebug() << "OK";
}
But, If I execute a select * from MyTable in shell, it works.
Also, if I execute this in a shell logged in mysql, it works :
source myFile.sql
SOURCE is MySQL client command which means it is executed by MySQL shell, not by MySQL server, so you can't execute it via QSqlQuery. You can work around this by reading whole file and then sending it's contents to server.
I want to package my Qt application with an existing Sqlite db. I have the standard Qt database code:
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName("database.sqlite");
bool connected = m_db.open();
if (!connected) {
qDebug() << "Error: connection with database failed";
} else {
qDebug() << "Database: connection success";
QSqlQuery q(m_db);
q.prepare("SELECT * FROM people");
if (q.exec()) {
qDebug() << "Yay!";
} else {
qWarning() << "Bad exec: " << q.lastError();
qWarning() << q.executedQuery();
}
}
However, the result is:
Error: connection with database failed
I know this is because it's not finding the correct database, and is instead creating a new one. If I provide the absolute path on my development machine to m_db.setDatabaseName(), it works. But my database file is in my .qrc and will not be available in that location when I deploy... so how can I get a reliable path for this database?
in the setDatabaseName-call use the right syntax for resource files:
m_db.setDatabaseName(":database.sqlite"); // <-- note the : before the name
... presuming the database file is located in the root of your resource file system.
Greetings, Thomas
I'm trying to access a USB dongle (which has SIM card in it) using QSerialPort.
The dongle is successful identified but when trying to open it I get permission error. The description of the error message from Qt documentation states that this could be that the device is being accessed by another service or the user has no permission. I attempted to disconnect the dongle and connect it again with the same results. How can I solve this. I'm on Ubuntu 16.04 64bit using Qt 5.7. The code I'm running is as below.
#include <QApplication>
#include <QString>
#include <QDebug>
#include <QList>
#include <QSerialPortInfo>
#include <QSerialPort>
#include <QDebug>
int main(int argc, char *argv[])
{
QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
QSerialPort *port = nullptr;
QString portName;
int counter = 0;
while(counter < ports.size())
{
portName = ports[counter].portName();
quint16 productId = ports[counter].productIdentifier();
quint16 vendorId = ports[counter].vendorIdentifier();
QString manufacturerName = ports[counter].manufacturer();
qDebug() << "Port Name: " << portName;
qDebug() << "Product ID:" << productId;
qDebug() << "Vendor Id: " << vendorId;
qDebug() << "Manufacturer: " << manufacturerName;
++counter;
if(manufacturerName.contains("Huawei", Qt::CaseInsensitive))
{
qDebug() << "found!" << " name: " << portName;
port = new QSerialPort(portName);
break;
}
}
//Write and send the SMS
bool opened = port->open(QIODevice::ReadWrite);
if(!opened)
{
qDebug() << "Error: " << port->error();
}
// some more code here
return 0;
}
The output is as below:
Port Name: "ttyS4"
Product ID: 11799
Vendor Id: 32902
Manufacturer: ""
Port Name: "ttyUSB0"
Product ID: 5382
Vendor Id: 4817
Manufacturer: "HUAWEI"
found! name: "ttyUSB0"
Error: QSerialPort::SerialPortError(PermissionError)
Serial devices are usually located in the /dev/ folder and is owned by root. It is likely that you need root access to open the device.
For example, with your dongle plugged in, you could get the permissions on the device with the following command:
ls -l /dev/ttyUSB0
Does it work if you run the program with 'sudo' or as root?
In a terminal, try running your program prefixed with the 'sudo' command. This will elevate your privileges to the root level:
sudo ./my_program
Open (as root) /etc/udev/rules.d/90-my-usb-dongle.rules and write:
SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1506", MODE="0666"
This tells linux to set R/W permissions for all to your device (note that idVendor and idProduct are hexadecimal).
Now reload udev rules:
# udevadm control --reload-rules
and check again
I'm trying to connect to a MS SQL Server on a remote box using QODBC in my Qt Linux application.
Here's what I have done so far:
Added QT += SQL in the .pro file.
Tested some db functions:
QStringList drivers = QSqlDatabase::drivers();
qDebug() << "Drivers: " ;
foreach(QString driver, drivers) {
qDebug() << ":: " << driver;
}
qDebug() << "Connection Names: ";
QStringList connames = QSqlDatabase::connectionNames();
foreach(QString conname, connames) {
qDebug() << ":: " << conname;
}
qDebug() << "---";
these both work, though connectionNames() is empty at this stage.
I have tried to added a database:
QString serverName = "server1";
QString dbName = "abc123";
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", "MyFirst");
db.setHostName(serverName);
QString myCon = QString("DRIVER={SQL Native Client};SERVER=%1;DATABASE=%2;Trusted_Connection = Yes").arg(serverName).arg(dbName);
db.setDatabaseName(myCon);
If I now list the connections, "MyFirst" is in the list.
Tried to open the database:
bool ok = db.open();
qDebug() << "OK: " << ok;
if (!ok) {
qDebug() << "error: " << db.lastError().text();
}
The db.open() fails with the following message:
"[unixODBC][Driver Manager]Can't open lib 'SQL Native Client' : file not found QODBC3: Unable to connect"
My questions are:
I picked up the connection string from a forum post, I figured it was as good a place to start as any, but what exactly should be in there? Where does "SQL NAtive Client" come from? What do I need to do to setup my Qt / Linux box to be able to connect to a remote MS SQL Server?
Sounds like you need to install the SQL Server ODBC Driver.
An explanation for how to do that is here:
https://technet.microsoft.com/en-us/library/hh568454(v=sql.110).aspx
In addition you need to refer to it by the correct name, which is "ODBC Driver 11 for SQL Server"