Qt Sql not able to bind variables to QSqlQuery prepare Statement - c++

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

Related

QtSql: binding doesn't change query with SQLite

I have the following code that's supposed to bind a value to a prepare statement:
QSqlQuery query(db);
query.setForwardOnly(true);
query.prepare("SELECT Entry.* FROM Entry WHERE body LIKE ?;");
query.addBindValue(QVariant("%" + name + "%"));
query.exec();
tDebug("%s", query.executedQuery().toUtf8().data());
For instance, if name was "thing", then the query should execute the statement SELECT Entry.* FROM Entry WHERE body LIKE "%thing%", but it executes SELECT Entry.* FROM Entry WHERE body LIKE ?, almost as if the bound value was ignored. Named placeholders have the same problem.
I tried this on an equivalent example and appropriately testing the result of "prepare" and "exec", which both return a Boolean. I tested that the values are bounded ok after exec with:
QList<QVariant> list = query.boundValues().values();
for (int i = 0; i < list.size(); ++i)
qDebug() << i << ": " << list.at(i).toString();
I tested that I got the expected result with
while (query.next())
qDebug()<<"result = "<<query.value(0);
Indeed, the executedQuery did not contain the bounded values, but the comment in Qt is somewhat vague on this:
"If a prepared query with placeholders is executed on a DBMS that does not support it, the preparation of this query is emulated.The placeholders in the original query are replaced with their bound values to form a new query. This function returns the modified query. It is mostly useful for debugging purposes."
So I assume that for postgresql (what I have) and SQLite, the executedQuery does return the original with placeholders and not bounded values.

C++ Query builder for SPARQL queries

This is my first post in stack-overflow, so sorry in advance for possible "bad practices".
Context: the goal is to send SPARQL queries through http-requests to a GraphDB data base.
Problem: to construct the queries on code in a safe way. Currently done by means of std::string dummyStr = "Hello"+" World" or dummyStr.append("bla") (I was told this was not safe due to XSS, but thats not the issue here)
Question: do you know any query builder library for doing this string concatenation?
A search for C++ query builder on the web returned this answer.
After implementing the approach with the suggested Qt QSqlQuery class, I'm able to ".prepare" the query, but not to ".bindValue".
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.open();
QSqlQuery startQuery;
/*Prepare query*/
startQuery.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
startQuery.bindValue(":id", 1001);
startQuery.bindValue(":forename", "Bart");
startQuery.bindValue(":surname", "Simpson");
/*convert query to std::string*/
QString startQueryString = startQuery.lastQuery();
std::string dummyQuery = startQueryString.toUtf8().constData();
Why can't I bind the values to the placeholders?
Is it because I have no "actual" database, but rather a dummy-database just to construct the query?
My actual Query looks something like this:
SELECT ?s WHERE { FILTER(STRSTARTS(STR(?s),":referenceIRI")). ?s rdf:type rdfs:Class.}
And I would like to treat :referenceIRI as a placeholder.
I've searched overall to try to overcome this problem, as I just need the query-builder functionality.
Also: on my actual SPARQL query I have both ? and :myVal elements, which are the 2 types of placeholders in QSqlQuery for binding values. Any idea on how to by-pass the ? placeholder and just consider the :myVal-type?

how to insert variable's value in SQlite Database in Qt cpp

i am using Qt and i have written c++ code,i have already connected with sqlite database.i want to insert name in database
std::string name="Hello";
qry.prepare( "INSERT INTO s_no (Name,Status) VALUES ('name','1' )");
if( !qry.exec() )
qDebug() << qry.lastError();
else
qDebug( "Inserted!" );
but in db i am finding name only , not hello;
please help me..thank you so much in advance
C++ and SQL are two different programming languages, and execute in different environments. This means that C++ objects are not visible in SQL.
In theory, it would be possible to construct the string containing the SQL command so that the value of the name variable is inserted directly into it:
qry.prepare("INSERT INTO s_no (Name,Status) VALUES('" + name + "', '1')"); // don't do this
However, this will blow up if the name contains a quote. Escaping quotes would be possible with additional code, but a better way of getting variable values into an SQL query is to use parameters:
qry.prepare("INSERT INTO s_no (Name,Status) VALUES(?, '1')");
qry.bindValue(0, name);
(This is the only sensible way of using blob values in a query.)
Try making name a QString. You can change std::string to QString by using: QString name2 = QString::fromStdString(name);. Don't forget to include: #include <QString>.

App connection with Sqlite in my app developed in qt

In my app in QT5 I have this code
QString sql = "Select * from table";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./au.sqlite");
db.open();
QSqlQuery query(sql);
query.exec();
But when I get the results only get one result, the select query only give me one result and I don't know how fix this. If I add query.next() in a while loop I only get one iteration.
There is a bool function that returns true if the query succeeded. Looking back to the docs:
Successfully executed SQL statements set the query's state to active so that isActive() returns true. Otherwise the query's state is set to inactive.
This is the way you can check the result. If it's false, then You should try to rewrite your sql query text so that functional sql words (such as SELECT, FROM and etc.) are in the upper case (the way it's shown in the docs) and try to execute the query once again.
Here's an example from the docs again:
QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
QString country = query.value(0).toString();
doSomething(country);
}
You might check sqlbrowser example that is included with Qt5 distribution. Run your query there on your db.

Qt SQLite can't perform Select querys

I know many questions were asked around the issue I have, I spent along time trying to implement all kinds of solutions but didn't help.
I am trying to read a .db file using Qt SQLite platform.
windows 8 Qt 5.3.2
Opening the db file in DB browser for SQLite and executing my simple query succeeds:
SELECT Name FROM Person ORDER BY Name
and there is a list of 10 rows at the output.
I would like to do it throw Qt. my code:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("C:\mydb.db");
if(db.open())
{
QSqlQuery qry(db);
if(qry.exec("SELECT Name FROM Person ORDER BY Name"))
{
while(qry.next())
{
//some code
}
}
QSqlError e;
QString s,d;
e = qry.lastError();
s = e.databaseText();
d = e.driverText();
}
this code falls, the qry.exec command returns false, and last error is "no such table; person"
Running the command: QStringList tables = db.tables(QSql::AllTables);
after the Data Base is open shows that there is one table in Data Base called: sqlite_master.
trying to replace the query within the exec command with the query: "SELECT tbl_name FROM sqlite_master WHERE type = 'table'"
as says at: http://www.sqlite.org/faq.html#q7
causes the exec command to return true but qry.next() returns false already from the first iteration, although I have 5 tables in my data base.
I would be great full to how ever can me with my problem!
thanks!!!
You should specify the path to the database file correctly. Instead of C:\mydb.db you should use C:\\mydb.db or C:/mydb.db.
That's because the compiler uses \ as an escape character in strings (for things like \t, \n or \r). so \\ is actually turned into \.