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>.
Related
I have a C++Builder SQL Statement with a parameter like
UnicodeString SQLStatement = "INSERT INTO TABLENAME (DATETIME) VALUES (:dateTime)"
Can I add the parameter without quotes?
Usually I'd use
TADOQuery *query = new TADOQuery(NULL);
query->Parameters->CreateParameter("dateTime", ftString, pdInput, 255, DateTimeToStr(Now()));
which will eventually produce the SQL String
INSERT INTO TABLENAME (DATETIME) VALUES ('2022-01-14 14:33:00.000')
but because this is a legacy project (of course, it always is) and I have to maintain different database technologies, I need to be able to inject database specific date time conversion methods, so that the endresult would look like
INSERT INTO TABLENAME (DATETIME) VALUES (to_date('2022-01-14 14:33:00.000', 'dd.mm.yyyy hh24:mi:ss')))
If I try injecting this via my 'usual' method (because I don't think I can inject a second parameter into this one) it'd look like:
TADOQuery *query = new TADOQuery(NULL);
query->Parameters->CreateParameter("dateTime", ftInteger, pdInput, 255, "to_date('" + DateTimeToStr(Now()) + "', 'dd.mm.yyyy hh24:mi:ss')");
but of course the result would look like:
INSERT INTO TABLENAME (DATETIME) VALUES ('to_date('2022-01-14 14:33:00.000', 'dd.mm.yyyy hh24:mi:ss')'))
and therefore be invalid
Or is there another way to do this more cleanly and elegantly? Although I'd settle with 'working'.
I can work around this by preparing two SQL Statements and switch the statement when another database technology is but I just wanted to check if there is another way.
Why are you defining the parameter's DataType as ftInteger when your input value is clearly NOT an integer? You should be defining the DataType as ftDateTime instead, and then assigning Now() as-is to the parameter's Value. Let the database engine decide how it wants to format the date/time value in the final SQL per its own rules.
query->Parameters->CreateParameter("dateTime", ftDateTime, pdInput, 0, Now());
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 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 :)
I'm just getting started implementing some client software for a PostgreSQL database.
The queries will allow input parameters that come from an untrusted source. Therefore I need to sanitize my transactions before actually commiting them.
As for libpq I've found PQescapeStringConn, that may do want I need. However, as my code will be written in C++, I'd prefer to use a libpqxx equivalent. I could not find anything related. (Except probably the Escaper, which however lies in the internal namespace...)
I'd appreciate any suggestions on best practices, reading, links to the documentation, whatever.
Using pqxx::transaction_base::quote is the way to go.
Here's a simple example:
// connection to the database
std::string login_str = "TODO: add credentials";
pqxx::connection conn(login_str);
pqxx::work txn(conn);
// a potentially dangerous input string
std::string input = "blah'; drop table persons; --";
// no proper escaping is used
std::string sql_1 = "select * from persons where lastname = '%s'";
std::cout << boost::format(sql_1) % input << std::endl;
// this is how it's done
std::string sql_2 = "select * from persons where lastname = %s";
std::cout << boost::format(sql_2) % txn.quote(input) << std::endl;
The output is:
select * from persons where lastname = 'blah'; drop table persons; --'
select * from persons where lastname = 'blah''; drop table persons; --'
For reference:
http://pqxx.org/devprojects/libpqxx/doc/development/Reference/a00196.html#details
Actually in order to give a better view, I was having an issue with this kind of things this week and we started using std::string pqxx::transaction_base::esc
You just have to add it in the argument you going to insert or update, and it will do the job.
The quote function mentioned up there, its add the quote to the argument, but it does not fix the problem.
For example; if you do something like UPDATE person set name = w.quote(name) where id = 1;
There you are using the quote correctly in order to put between quotes the argument.
So in order to insert a single quote or avoid SQL Injection, you have to do:
UPDATE person set name = + "'" + w.esc(name) + "'" where id = 1 OR
UPDATE person set name = w.quote(w.esc(name)) where id = 1;
Being W the pqxx::work variable already initialized with the connection to the database.
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);