Qt Sqlite table column appears to be gone - c++

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

Related

I can't insert data into my sqlite3 database using qt 6

I have a test.db database on my project directory, which I'm trying to insert data into. The database is connected, but I can't seem to insert data in it. The query is not executed at all (it seems), since the qDebug shows "Bad".
QSqlDatabase connectDB(){
QSqlDatabase db= QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("test.db");
return db;
}
void planner::on_dataSend_clicked()
{
QSqlDatabase datba = connectDB();
if (datba.open()){
qDebug()<< "DB Suc";
} else{
qDebug() << "DB Fail";
}
QString what = ui->addPlan->text();
QSqlQuery qry;
qry.prepare("insert into plan values :what");
qry.bindValue(":what",what);
if (qry.exec()){
qDebug()<< "Good";
qry.clear();
} else{
qDebug()<<"Bad";
qDebug()<<qry.lastError();
qry.clear();
}
datba.close();
ui->addPlan->clear();
}
I'm using DB Browser for SQLite, and this is the database
The error that QSqlError shows is parameter count mismatch here
On SQLITE table, there is a default column as a primary key called rowid, you need to spécify the column that you want to add like this:
qry.prepare("insert into plan (column_name) values (:what)");

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;

QSqlQuery not positioned on a valid record

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