QSqlQuery not positioned on a valid record - c++

I'm trying select a field of my date base, the code is:
if (db.db().isOpen())
{
qDebug() << "OK";
QSqlQuery query("SELECT state FROM jobs WHERE jobId = '553'", db.db());
qDebug() << query.value(0).toString();
}
else
qDebug() << "No ok";
The query is correct because when I do qDebug() << query.size;, it returns 1.
but with qDebug() << query.value(0).toString();, it returns:
OK
QSqlQuery::value: not positioned on a valid record
""
How can I fix it?

You should call query.first() before you can access returned data. additionally if your query returns more than one row, you should iterate via query.next().

Related

SQLite CREATE query in QT

dataBase = QSqlDatabase::addDatabase("QSQLITE");
dataBase.setDatabaseName("login_password.sqlite");
QSqlQuery authQuery;
if(!dataBase.open())
{
qDebug() << dataBase.lastError().text();
}
QString create("CREATE TABLE BASE(LOGIN VARCHAR(15) PRIMARY KEY NOT NULL, "
"PASSWRD TEXT(50) NOT NULL, RIGHTS INT NOT NULL);");
bool state = authQuery.exec(create);
if(!state) qDebug() << "Не удалось создать таблицу!";
What's wrong with query and is it possible to make text PRIMARY KEY?
From the docs:
Warning: You must load the SQL driver and open the connection before a
QSqlQuery is created. Also, the connection must remain open while the
query exists; otherwise, the behavior of QSqlQuery is undefined.
In your question, you are creating the QSqlQuery before opening the database, you have to move the authQuery declaration statement after the dataBase.open() call, like this:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("login_password.sqlite");
if (!db.open())
qDebug() << "error opening database: " << dataBase.lastError().text();
QSqlQuery authQuery;
QString create("CREATE TABLE BASE(LOGIN VARCHAR(15) PRIMARY KEY NOT NULL, "
"PASSWRD TEXT(50) NOT NULL, RIGHTS INT NOT NULL);");
if(!authQuery.exec(create)){
qDebug() << "error executing statement: " << authQuery.lastError().databaseText();
}

Copy tables between sqlite databases, qt, causes error

I want to write the contents of my SQlite database on user click to another SQlite database. For this I am trying to make connections to two databases and do select query from one db and in transaction do insert query to another. But I gets error on connection creation itself.
In header file:
private:
QSqlDatabase database;
QSqlDatabase mHistoryDB;
In source file:
qDebug() << Q_FUNC_INFO << "Invoked";
database = QSqlDatabase::addDatabase("QSQLITE");
mHistoryDB = QSqlDatabase::addDatabase("QSQLITE");
#ifdef Q_OS_WIN
database.setDatabaseName("C:/ANDROID_DATABASE/RestPos.sqlite");
mHistoryDB.setDatabaseName("C:/ANDROID_DATABASE/History/RestPos.sqlite");
#else
database.setDatabaseName("/mnt/sdcard/pos/RestPos.sqlite");
mHistoryDB.setDatabaseName("/mnt/sdcard/pos/History/RestPos.sqlite");
#endif
While running I gets the following error:
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
If I use only database connection there occurs no error. I am not sure how to do copy with single connection.
My current copy code is as below:
bool readStatus = false,
writeStatus = false;
if (database.isOpen() && mHistoryDB.open())
{
QSqlQuery readQuery (database);
QSqlQuery writeQuery(mHistoryDB);
readStatus
= readQuery.exec("SELECT costcentre_id, bill_no, bill_date "
"FROM BillHdr");
qDebug() << Q_FUNC_INFO << getLastExecutedQuery(readQuery);
if (readStatus)
{
mHistoryDB.transaction();
writeQuery.prepare("INSERT INTO BillHdr "
"(costcentre_id, bill_no, bill_date) "
"VALUES (:costcentre_id, :bill_no, :bill_date)");
while(readQuery.next())
{
if (readQuery.isValid())
{
BillHeader billHdr;
billHdr.costCenterId = readQuery.value(0).toString();
billHdr.billNumber = readQuery.value(1).toDouble();
billHdr.date = readQuery.value(2).toDate();
writeQuery.bindValue(":costcentre_id", billHdr.costCenterId);
writeQuery.bindValue(":bill_no", billHdr.billNumber);
writeQuery.bindValue(":bill_date", billHdr.date);
writeStatus = writeQuery.exec();
qDebug() << Q_FUNC_INFO << getLastExecutedQuery(writeQuery);
if (!writeStatus)
{
qDebug() << Q_FUNC_INFO << "error in write" <<
writeQuery.lastError().text();
mHistoryDB.rollback();
mHistoryDB.close();
break;
}
}
}
writeStatus = mHistoryDB.commit();
qDebug() << Q_FUNC_INFO << "commit:" << writeStatus;
if (!writeStatus)
{
mHistoryDB.rollback();
}
mHistoryDB.close();
}
}
qDebug() << Q_FUNC_INFO << "Exits" << writeStatus;
return writeStatus;
We can read from the Qt documentation about QSqlDatabase :
Warning: If you add a connection with the same name as an existing connection, the new connection replaces the old one. If you call this
function more than once without specifying connectionName, the default
connection will be the one replaced.
So when you add a database multiple times within a specific name or without specifying any (default connection), the connection is replaced and that warning appears.
you should call QSqlDatabase::addDatabase() once for each of the databases with different connection names :
database = QSqlDatabase::addDatabase("QSQLITE", "database_Connection");
mHistoryDB = QSqlDatabase::addDatabase("QSQLITE", "mHistoryDB_Connection");

SQLITE out of memory Unable to execute statement

I tried using sqlite in qt but I’ve come across an error.
qDebug() << QSqlDatabase::drivers();
QSqlDatabase DB = QSqlDatabase::addDatabase("QSQLITE");
DB.setDatabaseName("/Volumes/MAJID/majid/Naminic/db0.db");
QSqlQuery createQuery;
qDebug()<< "open: " << DB.open();
createQuery.exec("CREATE TABLE contact(name,tell)");
qDebug() << createQuery.lastError().text();
qDebug() << "insert : " << createQuery.exec("insert into contact(name,tell) values('a','b')");
qDebug() << createQuery.lastError().text();
and this is the out put of the debug :
(“QSQLITE”, “QODBC3”, “QODBC”)
open: true
out of memory Unable to execute statement
insert : false
out of memory Unable to execute statement
A couple problems I see that should get this working.
1. You need to pass the database object to the QSqlQuery when you create it.
The below line is wrong
QSqlQuery createQuery;
Change it to the following and you should be good
QSqlQuery createQuery(DB);
2. You need to open the database before you create the QSqlQuery object. The connection to the database needs to be open if you initialize the QSqlQuery object with it. So instead of this:
QSqlQuery createQuery(DB);
qDebug()<< "open: " << DB.open();
do this
qDebug()<< "open: " << DB.open();
QSqlQuery createQuery(DB);
That should get things working.
open database before set the query(db) works for me.
add this to the head.
if(!db.isOpened()) db.open();
if(db.isOpenError()) return false;

Invalid QSqlRecord after performing another query to DB

Here is the code:
QSqlQuery q1(db_connection), q2(db_connection);
q1.exec("SELECT * from users");
while(q1.next())
{
q2.exec("delete from table1");
if (!q2.isValid())
qDebug() << "q2 is not valid";
if (q1.isActive() && q1.isValid())
qDebug() << q1.record();
}
q1 is the correct query.
q2 is KNOWINGLY wrong one, cuz there is no table with name "table1".
The deal is: why q1 returns wrong (empty) data with QSqlQuery::record() method, but absolutely right data with QSqlQuery::value() method after q2 is beeing exec()'d?

Qt Sqlite table column appears to be gone

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":temp:");
if (!db.open()) {
qDebug() << "Database open error." << db.lastError();
return;
}
QSqlQuery query(db);
query.prepare("create table if not exists dew (id int, title varchar(255) not null)");
if (!query.exec()) {
qDebug() << "Query exec error. " << query.lastError();
return;
}
qDebug() << "Insert query exec OK";
if (!query.exec("insert into dew(id, title) values (1, 'hello')")) qDebug() << query.lastError();
Shows the output as
Insert query exec OK
QSqlError(1, "Unable to execute statement", "table dew has no column named id")
Insertion finished.
Table creation seems to be OK. But where is id field? I'm confused with this code. I test query.record().contains("id"); and it is false
":temp:" is not a valid name for a temporary database, this creates a regular database on disk which stays after the database connection is closed.
To create a temporary or an in-memory sqlite database, that won't be saved to a file, you need to pass respectively an empty string (*) or the special string ":memory:" as the database name.
http://www.sqlite.org/inmemorydb.html
Qt doesn't allow an empty QString as the database name, but a QString starting with a '\0' should work: db.setDatabaseName(QChar(0));