QSqlQueryModel complains that my database is not open - c++

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);

Related

not positioned on a valid record

Im New in Qt
I have problem in my app.
This is my code:
voidDialog::on_tableView_activated(constQModelIndex&index)
{
QString valu=ui->tableView->model()->data(index).toString();
QSqlQuery qryview;
qryview.prepare("SELECT* FROM employ where nomper='"+valu+"' or prenomper='"+valu+"'");
ui->lineEdit_2->setText(qryview.value(0).toString());
ui->lineEdit_3->setText(qryview.value(1).toString());
}
I want to recuperate my data in QLineEdit.
When I use SQLite, there is no problem.
But when I use MySQL no result shows in lineEdit.
qsqlquery::value: not positioned on a valid record.
The problem is that you are trying to retrieve the row without initializing it. The right way to do this is by using query.next(), below is the code example:
QString valu=ui->tableView->model()->data(index).toString();
QSqlQuery qryview;
qryview.prepare("SELECT* FROM employ where nomper='"+valu+"' or prenomper='"+valu+"'");
qryview.exec();
while(qryview.next()) {
ui->lineEdit_2->setText(qryview.value(0).toString());
ui->lineEdit_3->setText(qryview.value(1).toString());
}
This should work, if not try to print the lastQueryError and see if query is executed coreectly.

"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.

Can't retrieve identity field after insert in sql database

Using C++ Qt framework and sql server 2008 I've been trying to insert a record into a table with an identity field and retrieve the identity value. Below is a simplified code sample which actually does do the insert but just doesn't retreive the identity. The identity returned from query.value(0) is an invalid QVariant.
QSqlQuery query(*pConn);
query.prepare("insert into [VH_MANUFACTURER] values ('sRRS test man code','RRS type','RRS logo file',1,'RRS SEO para','RRS description','RS');"
"select SCOPE_IDENTITY();");
if(query.exec())
{
if(query.next())
{
QVariant identity = query.value(0);
int id=identity.toInt();
}
}
I've tried using select ##identity instead of scope_identity with no improvement and also QSqlQuery .lastInsertId() which also returns an invalid QVariant, see below.
bool bFeature = pConn->driver()->hasFeature(QSqlDriver::LastInsertId);
QSqlQuery query(*pConn);
query.prepare("insert into [VH_MANUFACTURER] ([MFG_NAME],[MFG_TYPE],[MFG_LOGO],[MFG_ACTIVE],[MFG_SEO_CONTENT],[MFG_DESCRI],[MFG_CAPMANCODE]) values ('sRRS test man code','RRS type','RRS logo file',1,'RRS SEO para','RRS description','RS')");
if(query.exec())
{
QVariant id=query.lastInsertId();
}
hasFeature returns true, so the driver is supposed to support what I'm trying to do.
Just to test the sql , I ran the sql directly through Sql Server Management Studio and it inserts as expected and returns the identity value correctly.
Finally found a work around using OUTPUT clause in sql. I don't exactly know why the other methods I tried don't work. There is a sql server bug associated with this feature but that doesn't explain why it worked in ssms but not in c++ Qt code. The sample below show's the work around. Here's the reference I used to solve this.
bool bFeature = pConn->driver()->hasFeature(QSqlDriver::LastInsertId);
QSqlQuery query(*pConn);
query.prepare("insert into [VH_MANUFACTURER] ([MFG_NAME],[MFG_TYPE],[MFG_LOGO],[MFG_ACTIVE],[MFG_SEO_CONTENT],[MFG_DESCRI],[MFG_CAPMANCODE]) OUTPUT INSERTED.MFG_ID values ('sRRS test man code','RRS type','RRS logo file',1,'RRS SEO para','RRS description','RS')");
if(query.exec())
{
if(query.next())
{
QVariant id=query.value("MFG_ID");
}
}

QSqlDatabase::open() always returns true

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.

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().