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?
Related
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");
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>.
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 :)
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.
We were using stringstream to prepare select queries in C++. But we were strongly advised to use QUERY PARAMETERS to submit db2 sql queries to avoid using of stringstream. Can anyone share what exactly meant by query parameter in C++? Also, share some practical sample code snippets.
Appreciate the help in advance.
Edit: It is stringstream and not strstream.
Thanks,
Mathew Liju
I suspect this refers to parameterized queries in general, rather than constructing the query in a string, they supply sql variables (or parameters) and then pass those variables separately. These are much better for handling SQL Injection Attacks. To illustrate with an example:
"SELECT * FROM Customers WHERE CustomerId = " + _customerId;
Is bad, while this:
"SELECT * FROM Customers where CustomerId = #CustomerId"
is good. The catch is that you have to add the parameters to the query object (I don't know how this is done in C++.
References to other questions:
https://stackoverflow.com/questions/1973/what-is-the-best-way-to-avoid-sql-injection-attacks
Stored Procedures vs Parameterized Queries
Wild Wild Web:
http://www.justsoftwaresolutions.co.uk/database/database-tip-use-parameterized-queries.html
Sql query in parameterized query form is safe than string format to avoid sql injection attack.
Example of parameterized query
StringBuilder sqlstr = new StringBuilder();
cmd.Parameters.AddWithValue("#companyid", CompanyID);
sqlstr.Append("SELECT evtconfigurationId, companyid,
configname, configimage FROM SCEVT_CONFIGURATIONS ");
sqlstr.Append("WHERE companyid=#companyid ");
Example of query string format
StringBuilder sqlstr = new StringBuilder();
sqlstr.Append("SELECT evtconfigurationId, companyid, configname,
configimage FROM SCEVT_CONFIGURATIONS ");
sqlstr.Append("WHERE companyid" + CompanyID);