How to use variables in query - c++

I have to use a user input value in my query to select a row which has that value........
I have written this code in qt but it doesn't work...how can I fix it?
void MainWindow::on_pushButton_clicked()
{
int j=0;
float t;
t=ui->T_lineEdit->text().toFloat();
QSqlQuery qry;
if(qry.exec("select * from table where te='+t+'"))
{
ui->u_lineEdit->setText("hello");
}
}

You should use a prepared statement using QSqlQuery.
QSqlQuery qry;
qry.prepare("select * from table where te=?");
qry.addBindValue(t);
if(qry.exec())
{
ui->u_lineEdit->setText("hello");
}
Note that concatenating user's raw string to a SQL query is highly vulnerable to SQL Injection.

I'm not familliar with qt, but it seems to me that you used concatenation within a string, so "select * from table where te='+t+'" should be "select * from table where te='"+t+"'" .
Of course it is strange that you should place single quotes around a float value, but I don't know the type of column te. It could be necessary to convert t to string first:
"select * from table where te='" + QString::number(t) + "'"
Finally I have to add that this looks suspiciously like code where you allow SQL Injection. You should look into this and make sure to avoid it. See Frogatto's answer for that.

Related

How can I insert string value from .csv to SQLite database? Qt c++

This code can successfully insert an integer value from the .csv file to the SQLite database. However, when the value is a string. It does not insert the string value. Please help.
QFile f(csvFile);
if(f.open (QIODevice::ReadOnly)){
QSqlQuery que;
QTextStream ts (&f);
//Travel through the csv file "excel.csv"
while(!ts.atEnd()){
QString req = "INSERT INTO main VALUES(";
QStringList line = ts.readLine().split(',');
for(int i=0; i<line .length ();++i){
req.append(line.at(i));
req.append(",");
}
req.chop(1); // remove the trailing comma
req.append(");"); // close the "VALUES([...]" with a ");"
que.exec(req);
qDebug()<<req;
que.lastError();
}
qDebug()<< req ouput:
"INSERT INTO main VALUES(1,2,3);" "INSERT INTO main VALUES(a,b,c);"
Based on Prapin's answer I've decided to write up a quick how to.
Here is the link to QTs SQL statement documentation. There are multiple ways in which to query the database. I personally am a fan of #2 'named binding' over #3 'positional binding'. This is because it is very clear to the programmer what values are being accessed.

QSqlQuery ctor or prepare() syntax when more than 1 string literal

In a peer review I stumbled across some lines of Qt and more precisely on QSqlQuery that I never experienced before
QSqlQuery query(my_db);
query.prepare("SELECT * FROM Result "
"WHERE Tag=:some_tag AND Name=:my_name");
I was astonished by the syntax prepare("PlainOldCChain1" "PlainOldCChain2")
What kind of C++ object is "PlainOldCChain1" "PlainOldCChain2" (I would have thought to some Initializer list but without { , } I am a little bit lost. I found only the prototype bool prepare(const QString & query))
Adjacent string literals with white space in between are simply concatenated.
query.prepare("SELECT * FROM Result "
"WHERE Tag=:some_tag AND Name=:my_name");
is exactly the same as
query.prepare("SELECT * FROM Result WHERE Tag=:some_tag AND Name=:my_name");
Also see: How does concatenation of two string literals work?

How to perform IN in sql query using pqxx in c++ for postgresql?

How to perform IN in sql query using pqxx in c++ for postgresql ?
I have vector<long> of ids and I need to update every row in table students ( to set faculty_id to some new value).
I want to avoid loop, new value (faculty_id) I get when I insert faculty with prepared INSERT statement.
Is possible at all to pass so iterable structure or create prepared IN query using pqxx ?
void prepareChangeFaculty(connection_base &c){
const std::string sql =
"UPDATE students SET faculty_id=$2 WHERE id IN $1"; // here is a problem
c.prepare("change_faculty", sql);
}
$1 I have like vector of id of rows which I need to update
Why not something like that (How to concatenate a std::string and an int?) in C++11
string a="";
for (int k=0;k<myVector.size();k++){
a += string(myVector[k]);
if (k<myVector.size()-1){
a += ",";
}
}
std::string sql = "UPDATE students SET faculty_id=$2 WHERE id IN (" + a + ")";
I understand the concerns of #Massa, however I could not find a different solution than the #Alexandros one.
So, a bit improvement to this solution can be the use of std::copy
std::stringstream params;
std::copy(
myVector.begin(), myVector.end(),
std::ostream_iterator<std::string>(params, ","));
std::string sql = "UPDATE students SET faculty_id=$2 WHERE id IN ('"
+ params.str() + "')";

Replacing table name with a variable in a query

i have the following code.My table is called 'tableu'.I want replace 'tableu' with a variable that will hold the table name. How can i represent that.
query.prepare(
"INSERT INTO tableu (village, weight, diet, age)"
"VALUES (:village, :weight, :diet, :age)"
);
If you want to change your table name from tableu to lets say NewTableName, it can be done using any of the following syntax:
query.prepare(
"RENAME tableu TO NewTableName"
);
OR
query.prepare(
"ALTER TABLE tableu RENAME TO NewTableName"
);
Update:
May be the OP is looking for this.
QString tableName = QString("tableu");
QString sqlQuery = QString("INSERT INTO %1 (village, weight, diet, age) VALUES (:village, :weight, :diet, :age)").arg(tableName);
I'm not 100% sure what you want, but this code will let you have a variable that may contain different tables names placed in the query
char sBuffer [1024];
char sQueryTable[] = "tableu";
sprintf(sBuffer , "INSERT INTO %s (village, weight, diet, age) VALUES (:village, :weight, :diet, :age)", sQueryTable);
query.prepare(sBuffer);
Read about sprinft and formatting strings here
Note: you can always use std::strings as well and concatenate the string together from a variable holding your table name and the rest of the string

sqlite prepared statements - how to debug

I'm writing some c++ code that uses the sqlite3 library. I'm using a prepared statement to which I bind a variable at runtime.
How do I examine the SQL query in the statement after the bindings?
For example, the code below doesn't return a row. When using a premade string and sqlite3_exec, I get the results I expect.
sqlite3_stmt *statement;
const char *query = "SELECT * FROM foo WHERE (name='?');";
sqlite3_prepare_v2(db, query, strlen(query), &statemtnt, NULL);
sqlite3_bind_text(statement, 1, "bar", -1, SQLITE3_STATIC);
int result = sqlite3_step(statement);
// expected: result = SQLITE_ROW
// actual: result = SQLITE_DONE
edit: As Ferdinand stated below, the problem in the query above is the quotes around the ?. However, for the future, I'd still like to know how to inspect the sqlite3_stmt for the actual query that will be executed.
The SQL query does not change after the bindings -- your variables aren't inserted into the SQL string or anything.
In addition to what Neil said, drop the quotation marks around the ? placeholder:
"SELECT * FROM foo WHERE name = ?"
Otherwise SQLite won't replace the question mark but will treat it as the string "?".
Yes, you can do it by defining a profile function like this:
static void profile(void *context, const char *sql, sqlite3_uint64 ns) {
fprintf(stderr, "Query: %s\n", sql);
fprintf(stderr, "Execution Time: %llu ms\n", ns / 1000000);}
Then right after you open your database using sqlite3_open, make this call:
sqlite3_profile(fDBLink, &profile, NULL);
The third parameter of sqlite3_bind_text is supposed to be the value you want to bind - in your code you are trying to bind the query to itself!
Also, lose the semicolon at the end of the SELECT.
Don't know sqlite all that well, but the actual query might be logged or you might be able to flip a switch to get it to be logged.