QSqlDatabase::open() always returns true - c++

i'm trying to connect to a sql database with the Qt-Framework.
Unfortunately db.open() always returns true (you can set any password, hostname, etc...), despite no connection is established(?). I derive that from the query not having any effect on the database.
I'm using LAMPP on Ubuntu 14.04.
I've got the following code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QSql>
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlQuery>
void MainWindow::on_ButtonSQL_clicked()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "con1");
db.setHostName("localhost");
db.setDatabaseName("kinectshop2015");
db.setUserName("root");
db.setPassword("");
QMessageBox msgBox;
if (db.open()) {
msgBox.setText("Yay! Your database host is "+db.hostName()+" .\n"+" The name of the database is "+db.databaseName()+".");
msgBox.exec();
}
QSqlQuery query;
query.exec("INSERT INTO users (id, username, balance, isAdmin)" "VALUES(3, 'somebody', 10000, 1)");
}

One problem is that you are specifying a connectionName.
QSqlDatabase QSqlDatabase::addDatabase(const QString & type, const QString & connectionName = QLatin1String( defaultConnection ))
If connectionName is not specified, the new connection becomes the default connection
Given that your db connection is not the default connection, you need to tell the QSqlQuery which db to use, i.e.
QSqlQuery query(db);
query.exec("INSERT INTO users (id, username, balance, isAdmin)" "VALUES(3, 'somebody', 10000, 1)");
The other 'problem' is that with sqlite you always create a new database by the call you are making, thus the problem is not that the DB is not open but that its contents are not right (since it will be empty if you specify a non existing filename). If I take your code and add
qDebug() << query.lastError();
after the query.exec it rightfully complains that
QSqlError(1, "Unable to execute statement", "no such table: users")
If I include a statement to create the table before the insert query
QSqlQuery createTable("create table users ( id INTEGER, username TEXT, balance REAL, isAdmin INTEGER)",db);
createTable.exec();
I correctly get the table in the newly create db file and it has the entry that you are trying to insert.
Does this help?

Here is what solved my problem. I used the driver QMYSQL instead of QSQLITE. I had only used the latter, because the first one couldn't be loaded. On Ubuntu & QT5 simply type sudo apt-get install libqt5sql5-mysql to resolve the problem.

Related

QSqlQuery causing ODBC Function sequence error

I searched SO and Google but didn't find much help on this question. It seems due to ODBC functions being called out out of order. But since I am using QSql that wraps ODBC, it is hard for me to track down the function. Please help...
I was able to connect to the sql server database
I tested a very simply query and still got the error. I don't think it's due to column binding.
I was able to run the query with sql server, so I think the sql query is ok.
The tools I am using:
VS c++ 2017, CMake, Qt 5.09.2, sql server 2017
Below are the error messages:
QODBCResult::exec: Unable to execute statement: "[Microsoft][ODBC Driver Manager] Function sequence error"
QSqlError("0", "QODBC3: Unable to execute statement", "[Microsoft][ODBC Driver Manager] Function sequence error")
Test coding:
This coding generate the error message above.
int main()
{
QSqlDatabase GUIInpDB = QSqlDatabase::addDatabase("QODBC", "MainSQLDB");
GUIInpDB.setConnectOptions();
QString inpSqlServer = "DESKTOP-085AEA8\\SQLEXPRESS";
QString dbName = "test";
QString connString = QString("Driver={ODBC Driver 13 for SQL Server};Server=%1;DATABASE=%2;Trusted_Connection=Yes;")
.arg(inpSqlServer).arg(dbName); //the argument replace the %1 and %2
GUIInpDB.setDatabaseName(connString);
QSqlDatabase db = QSqlDatabase::database("MainSQLDB");
if (!db.open())
{
qDebug() << "Connection for db not working";
return 1;
}
QSqlQuery query("SELECT * FROM TBL.tbl_test", db);
if (!query.exec())
qDebug() << query.lastError();
int num_of_rows = query.size();
getchar();
return 0;
}
I found this discussion on QtCenter that might help you, even if I am doubtful about why it fixed the issue
You migth try to use the QSqlQuery constructor that does not exec as mentionned
http://www.qtcentre.org/threads/18832-ODBC-function-sequence-error

"Unable to find table" error when calling QSqlTableModel setTable method

I need to populate a QTableView by retrieving data from a QSqlTableModel object. I use following commands to make a connection to a sql server database:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
QString connectionTemplate = "DRIVER={SQL Native Client};SERVER=%1;DATABASE=%2;Uid=username;Pwd=password;Trusted_Connection=Yes;";
QString connectionString = connectionTemplate.arg("localhost").arg("mydb");
db.setDatabaseName(connectionString);
I validate the database connection by the methods isValid() and open() from QSqlDatabase class. I am also able to query from the database tables properly. ٍEvery thing is ok so far. But the problem arises when I use following commands:
QSqlTableModel* model = new QSqlTableModel(parent,db);
model->setTable("mytable");
qDebug() << model->lastError().text(); // the error message is printed on consul.
The method setTable not working and causes an error: Unable to find table \"mytable\".
I found the solution. I should open the database right after setDatabaseName and before creation of QSqlTableModel:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
QString connectionTemplate = "DRIVER={SQL Native Client};SERVER=%1;DATABASE=%2;Uid=username;Pwd=password;Trusted_Connection=Yes;";
QString connectionString = connectionTemplate.arg("localhost").arg("mydb");
db.setDatabaseName(connectionString);
db.open(); // :)
QSqlTableModel* model = new QSqlTableModel(parent,db);
model->setTable("mytable");
According to http://doc.qt.io/qt-5/qsqltablemodel.html#QSqlTableModel
the constructor of QSqlTablemodel:
Creates an empty QSqlTableModel and sets the parent to parent and the
database connection to db. If db is not valid, the default database
connection will be used.
In the event that your db object is not valid you would connect to a default database where your table is not available.
Double check the parameters used to initialize and setup QSqlDatabase db.

QSqlQueryModel complains that my database is not open

I am trying to use QSqlQueryModel in order to retrieve some values from my database like such:
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL", "test1");
db.setHostName(Vars::strDbHost);
db.setDatabaseName(Vars::strDbName);
db.setPort(Vars::strDbPort);
db.setUserName(Vars::strDbUsername);
db.setPassword(Vars::strDbPassword);
db.open()
QSqlQueryModel model;
model.setQuery(QString("SELECT * FROM users WHERE login=%2").arg(Vars::strUserLogin));
But I keep getting a QSqlQuery::exec: database not open error.
Why is this, and how can I correctly use QSqlQueryModel to retrieve the values I want?
You are calling the wrong version of setQuery. This only works with db which have the default name. In your case, you need to call void QSqlQueryModel::setQuery(const QString &query, const QSqlDatabase &db):
model.setQuery(QString("SELECT * FROM users WHERE login=%2").arg(Vars::strUserLogin)
, db);

Get primaryKey programmatically with Qt

I try to get primaryKey programmatically and convert it to col name. this function not work as mast be.
QString getPrimaryFiled( const QString &tableName )
{
QSqlDatabase m_SqlDataBase = QSqlDatabase::database(StaticConnection::getDatabaseConnectionName());
return m_SqlDataBase.primaryIndex( tableName ).name();
}
But I can't find way to make it work, It's give me blank string
You are misusing the following method:
QSqlDatabase QSqlDatabase::database(const QString & connectionName = QLatin1String( defaultConnection ), bool open = true) [static]
Returns the database connection called connectionName. The database connection must have been previously added with addDatabase(). If open is true (the default) and the database connection is not already open it is opened now. If no connectionName is specified the default connection is used. If connectionName does not exist in the list of databases, an invalid connection is returned.
You should have written this:
QSqlDatabase m_SqlDataBase = QSqlDatabase::database( StaticConnection::getDatabaseConnectionName() );
Provided that you followed the documentation properly about addDatabase().

can not make a table in sqlite3 by Qt

i have made a database in terminal by this command:
sqlite3 test.db
then i tried to make a table by using these codes:
ui->setupUi(this);
db1.setDatabaseName("test.db");
bool k=db1.open();
QSqlQuery q(db1);
q.prepare("CREATE TABLE by_code(id INT)");
q.exec();
qDebug()<<"isOpen: "<<k<<" Error:"<<q.lastError();
the output is :
isOpen: true Error: QSqlError(-1, "Unable to fetch row", "No query")
whats problem and how can i solve it?
Qt tried to get the result of the query, but a CREATE TABLE statement does not return a result.
This is not considered an actual error.
To check whether the query succeeded, check the return value of the exec function.