Database creation error in Qt - c++

I am using this code to create a database. But I am getting "false" in debug. I tried a lot but its not working. What is the error in this?
QSqlQuery query;
qDebug() << query.exec("CREATE TABLE glucose (id INTEGER PRIMARY KEY AUTOINCREMENT, value INTEGER, date TEXT, time TEXT, duration TEXT, note TEXT");
qDebug() << query.prepare("INSERT INTO glucose(id, value, date, time, duration, note)""VALUES(?, ?, ?, ?, ?, ?)");
query.bindValue(1,edit_glucose->text().toInt());
query.bindValue(2,datetime->date());
query.bindValue(3,datetime->time());
query.bindValue(4,"a");
query.bindValue(5,edit_note->toPlainText());
qDebug() << query.exec();

you forget to close your CREATE TABLE query with ")"

QSqlQuery has the method lastError(), returns error information :)

You are passing in the INSERT query the id field. You must remove it.
The query should be:
Debug() << query.prepare("INSERT INTO glucose(value, date, time, duration, note)
VALUES(?, ?, ?, ?, ?)");

Related

Qt Sql not able to bind variables to QSqlQuery prepare Statement

I am trying to fetch some records from MySQL database by using a prepared statement by using QSqlQuery as:
QString username=ui->textEdit_password->toPlainText();
QString password=ui->textEdit_password->toPlainText();
QSqlQuery query;
query.prepare("SELECT * FROM login_access WHERE username=? AND password=?");
query.addBindValue(username);
query.addBindValue(password);
query.exec();`
When i run :
std::string q_str1=query.executedQuery().toUtf8().constData();
std::cout<<"Query : "<<q_str1<<"\n";
It outputs : Query : SELECT * FROM login_access WHERE username=? AND password=? where the "?" has not been replaced and the query returns nothing since the "?" character is compared to the database records.
On running the query: SELECT * FROM login_access, the query returns all the database records in the login_access table.
I have also tried replacing the "?" with placeholders ":uname",":pass" and changed query.addBindValue(username); to query.bindValue(":uname",username);, and done same with password field.
I am running QtCreator 4.4.1
Thanks.
Use query.bindValue( ...) because this sets the placeholder value.
I tested executedQuery() on one of my SQL statements with placeholders and it returned a string with just the placeholders, not the values. The documentation does say that in most cases it the same string as lastQuery().
http://doc.qt.io/qt-5/qsqlquery.html#executedQuery
You have confirmed that your SQL statement without the where clause works so the next stage is to check you are binding what you think you are binding. To do this use boundValue(const QString placeholder) to find out if the placehold value is being bound.
It might also be useful to check the query has run OK.
So, after your query.exec you should put the following (assuming these are your placeholders) just to check these things:
qDebug() << query.lasterError();
qDebug() << query.boundValue(":uname");
qDebug() << query.boundValue(":pass");

Qt - GUI Database programming

I am using Qt GUI to save data in MySQL using C++.
I am using QDateTimeEdit widget for this. Whatever the value changed by user in GUI of QDateTimeEdit, it should be inserted in MySQL.
Can anyone tell me how to do that?
How to access value from QDateTimeEdit and converting it in proper format like QString and using MySQL query inserting it into database?
An alternative is not to convert it to a QString but let the driver do that for you. If you expect some precision in the conversion some cases this might be better, other cases it can be worse:
QDateTime date = ui->dateTimeEdit->dateTime();
QSqlQuery query(myDatabase);
query.prepare("INSERT INTO my_table (id, date) "
" VALUES (:id, :date)");
query.bindValue(":id", 1001);
query.bindValue(":date", date);
query.exec();
The QSqlQuery::bindValue() function will take the QDateTime and pass it through as a QVariant and then the driver should know how to convert a QVariant::DateTime to the correct string that the database understands.
About second part "how to access value":
You somehow in code created object of QDateTimeEdit and place it on some layout. Typically it will be pointer with name for example mpDTPicker.
QDateTimeEdit * mpDTPicker = new QDateTimeEdit();
//place mpDTPicker on layout.
For access current time we need use method dateTime:
//User actions with date -> emitted signal -> execute slot with our logic
{
QDateTime momentum = mpDTPicker->dateTime();
// So here we need convert QDateTime to QString and we will use [toString Method](http://doc.qt.io/qt-4.8/qdatetime.html#toString)
QString result_string = momentum.toString("dd:mm:yy");
QDebug() << result_string;
}
So that is all about converting QDateTime to QString.
About first part of Question how to get that user changed value of DateTimeEdit is total another question.
And about third part how to store it in mysql database everything depended on structure of your table. But typicaly it can be solved with simple query:
QSqlQuery query;
QString mQuerry = "INSERT INTO mytable (id, date) VALUES (0, \"" +result_string "\" )";
query.exec(mQuerry);
And please READ DOCS especial when them so cool :)

Inserting binary data via QSQL

How to insert binary data to table "test" from "database" with 2 columns text "name" and bin "pic"
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setUserName("user");
db.setPassword("pwd");
db.setPort(1234);
db.setDatabaseName("database");
You can have a look at http://www.java2s.com/Code/Cpp/Qt/UsingsqldatabasefromQt.htm snippets
First you need to open the DB db.open();
One way would be
QSqlQuery query;
query.prepare("INSERT INTO test (name, pic) "
"VALUES (:name, :pic)");
query.bindValue(":name", "Bart");
query.bindValue(":pic", "Bart.jpg");
query.exec();

Problem with % n *** %n in writable segment detected *** C++ i Qt

Problem with % n * %n in writable segment detected * C++ i Qt
I have program that process big data, that can't be modified. In one file we encounter "100% na" and application stop.
When I checked it with debuger, it return * %n in writable segment detected *.
I can't change visible that data, user must see "100% na". I thought of inserting some whitespace other then space after %.
Rewriting the whole applications is not a point. It runs on Windows and Linuks.
Currently the problem is in this code. I checked this in other places and it was the same. The variables are QStrings.
QSqlQuery query;
query.exec("insert into table_name ("+variable_with_columns_names+" values ("+variable_with_data_to_insert+");");
Do you have any ideas how to evade it?
edit
Prepare the query solved the problem in this spot. But it is breaking in others points. Update , Select ... where ...='100% na'(as variable), generating reports and other stuff. Whats more that this data is used by at least 5 modules, each using more then 5 data tables. So I will wait sometime, if anyone have other solution.
PS. One more question:
Why is "% n" interpreted as "%n", when it shouldn't?
Funny thing is if I change "100% na" to "100%% na", I get in data base "100%% na" when it should be changed to "100% na".
Use prepare to prepare the query. Then insert the values using bindValue. Prepared statements should always be used in such scenarios, as they handle the escaping of special characters for you.
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
query.bindValue(0, 1001);
query.bindValue(1, "Bart");
query.bindValue(2, "Simpson");
query.exec();
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
query.exec();
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (?, ?, ?)");
query.bindValue(0, 1001);
query.bindValue(1, "Bart");
query.bindValue(2, "Simpson");
query.exec();
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (?, ?, ?)");
query.addBindValue(1001);
query.addBindValue("Bart");
query.addBindValue("Simpson");
query.exec();
any of these help?

Subsequent insertion of records with QSqlTableRecord fail after first error

I have a problem with inserting data into SQLite database using QSqlTableModel. The table is created like this:
QSqlQuery createTblSMS("CREATE TABLE sms_tbl("
"isRead BOOLEAN NOT NULL,"
"readTime DATETIME,"
"arrivalTime DATETIME NOT NULL,"
"sender TEXT NOT NULL,"
"receiver TEXT NOT NULL,"
"smsContent TEXT,"
"PRIMARY KEY(arrivalTime, sender, receiver));");
I am inserting the records like this:
smsModel->insertRecord(-1, sms);
QString error = smsModel->lastError().text();
smsModel->submitAll();
smsModel is QSqlTableModel.
If i put for example a record wih this values (false, NULL, '2010-06-30 17:27:55', '075710383', 'ONE 142140', 'TOP 15 # 2') - the record is inserted.
After that record if put for example a record wih this values (false, NULL, '2010-06-30 10:05:29', '075710383', 'ONE 142140', 'TOP 15 # 3') - also this record is inserted.
But if i try to reinsert the record (false, NULL, '2010-06-30 17:27:55', '075710383', 'ONE 142140', 'TOP 15 # 2') which is already in the database, the smsModel will give an error like this :"columns arrivalTime, sender, receiver are not unique Unable to fetch row" - which is expected. Any other subsequent insertions of unique records will fail and the model gives me the same error. Do you have any clue why is this happening?
I ran into this problem of two fold.
When you are in manual submit mode, QSqlTableModel does not clear its cache when a submitAll fails (which it should when you send it a record that violates your constraints).
To correct this, you need to call either call select() or revertAll to remove those pending changes.
The doc doesn't make this very obvious, but it is there, check it out: http://doc.qt.io/qt-4.8/qsqltablemodel.html#submitAll
After a while i didn't manage to find solution with QSqlTableModel, so I made a workaround with QSqlQuery. The code is this:
QSqlQuery query(QSqlDatabase::database(mConnectionName));
query.prepare("INSERT INTO sms_tbl (isRead, readTime, arrivalTime,"
"sender, receiver, smsContent) "
"VALUES (:isRead, :readTime, :arrivalTime, "
":sender, :receiver, :smsContent)");
query.bindValue(":isRead", sms.value("isRead").toBool());
query.bindValue(":readTime", sms.value("readTime").toString());
query.bindValue(":arrivalTime", sms.value("arrivalTime").toString());
query.bindValue(":sender", sms.value("sender").toString());
query.bindValue(":receiver", sms.value("receiver").toString());
query.bindValue(":smsContent", sms.value("smsContent").toString());
query.exec();
You can't add a record with same primary key again. You have a primary key which contains the columns arrivalTime, sender, receiver. So you can't a value with same values of this three values.
You can change your create statement and a auto increment sms_table_id of type int.