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);
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());
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?
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>.
prep_stmt = con->prepareStatement("SELECT * FROM table WHERE customers in ( ? ) and alive = ?");
prep_stmt->setString(1,customer_string);
prep_stmt->setInt(2,1);
res = prep_stmt->executeQuery();
Here the customer_string is "12,1,34,67,45,14"
When I pass it as a String it always returns a single row, takes the first value only 12.
The sql statement prepared is:
SELECT * FROM table WHERE customers in ( "12,1,34,67,45,14" ) and alive = 1
but I want sql statement to be prepared as:
SELECT * FROM table WHERE customers in (12,1,34,67,45,14 ) and alive = 1
What is the easiest way to achieve the same in C++?
I am assuming you are using the MySQL C++ Connector. Unfortunately it seems that it is not possible to pass array as parameter of prepared statement using this API:
Connector/C++ does not support the following JDBC standard data types: ARRAY, BLOB, CLOB, DISTINCT, FLOAT, OTHER, REF, STRUCT.
https://dev.mysql.com/doc/connector-cpp/en/connector-cpp-usage-notes.html
You can place the value into the query directly by concatenating strings. Be VERY careful to not introduce SQL injection vulnerability. Alternatively use some other API.
I have to prepare strings to be suitable for queries because these strings will be used in the queries as field values. if they contain a ' etc the sql query fails to execute.
I therefore want to replace ' with '' I have seen the code to find and replace a substring with a substring. but I guess the problem is a little tricky because replacing string also contains two single quotes '' replacing one quote ' so when I have to find the next occurance it would encounter a ' which was intentionally replaced.
I am using Sql lite C api and the example query might look like this
select * from persons where name = 'John' D'oe'
Since John Doe contain a ' the query will fail , so I want all occurances of ' in the name to replaced with ''
Any ideas how you guys prepares your field values in query to be used in sql ??? may be it's a basic thing but I am not too smart in C/C++.
your help would be very helpful
Use queries with arguments instead of replacing stuff, which could lead to several problems (like SQL injection vulnerabilities).
MySQL example:
sql::Connection *con = ...;
string query = "SELECT * FROM TABLE WHERE ID = ?";
sql::PreparedStatement *prep_stmt = con->prepareStatement(query);
prep_stmt->setInt(1, 1); // Replace first argument with 1
prep_stmt->execute();
This will execute SELECT * FROM TABLE WHERE ID = 1.
EDIT: more info for SQLite prepared statements here and here.
It depends on the SQL Library you are using. Some of them will have the concept of a PreparedStatement, which you will use question marks in place of the variables, then when you set those variables on the statement, it will internally ensure that you cannot inject sql commands.