I have to insert a string into a sqlite data base
my command ..
Err=sqlite_exec(DB, "create table tbl5(TEXT varchar(100));", xCallback, (void*)"First Test", &ErrMsg);
Err=sqlite_exec(DB, "insert into tbl5 values ('some string');", xCallback, (void*)"First Test", &ErrMsg);
works fine but when I want to put s="some string" ie
Err=sqlite_exec(DB, "insert into tbl5 values (s);", xCallback, (void*)"First Test", &ErrMsg);
then this is not working so how to add variable then It is not working so how to insert variable in sqlite database
thank u
Don't use sprintf() but sqlite3_mprintf(). Here is the documentation.
char s[20] = "some string";
char* query = sqlite3_mprintf("insert into tbl5 values ('%q');", s);
Otherwise you have a risk of SQL injection.
The resulting query string should be freed using sqlite3_free().
Also note the '%q' instead of the usual '%s'.
Other than the suggestions already given, you can also use prepared statements with bound parameters (this is also useful if you intend to repeat the statement several times with different parameters). see the sqlite3_prepare_v2 and sqlite3_bind_* for more information
sqlite3_stmt *stmt;
// Create a prepared statement.
Err = sqlite3_prepare_v2(DB, "insert into tbl5 values (?)", -1, &stmt, NULL);
if (Err != SQLITE_OK)
{
//...
}
// Bind our string to the statement.
Err = sqlite3_bind_text(stmt, 1, "some string", -1, SQLITE_TRANSIENT);
if (Err != SQLITE_OK)
{
//...
}
// Execute the statement.
Err = sqlite3_step(stmt);
if (Err != SQLITE_DONE)
{
//...
}
// Free the prepared statement.
Err = sqlite3_finalize(stmt);
You could use sprintf to create a formatted string.
char s[20] = "some string";
char query[100];
sprintf(query, "insert into tbl5 values (%s);", s);
It's up to you to make sure query is big enough.
Related
I have been trying to use the SQLite tutorial here to learn how to use SQLite in C. I was having trouble figuring out exactly how to use it, as it only mentions the sqlite3_exec, which seems incredibly un-intuitive to use for basic querying (it uses a callback for everything). Then I came across this answer, https://stackoverflow.com/a/31168999/11954200, which addresses this same issue and suggests using the various four sqlite statements that are essentially merged into the sqlite3_exec shorthand form. Here is my understanding so far:
// Query to get the rows
// Part1 -- Prepare the query: cursor.execute()
// http://www.sqlite.org/c3ref/prepare.html
sqlite3_stmt *stmt; // this is the prepared statement that the sqlite3_prepare writes to
rc = sqlite3_prepare(db, "SELECT * FROM mytable LIMIT 20", -1, &stmt, NULL);
if (rc != SQLITE_OK) {
printf("error: %s", sqlite3_errmsg(db));
return 0;
}
// Part2 -- equivalent of cursor.fetchone()
// http://www.sqlite.org/c3ref/step.html
int rownum=1;
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
// Part3 -- reference the values from the row
// http://www.sqlite.org/c3ref/column_blob.html
int id = sqlite3_column_int(stmt, 0);
const unsigned char * date = sqlite3_column_text(stmt, 1);
printf("Row: %d | ID: %d | Date: %s\n", rownum, id, date);
rownum++;
}
// Part4 -- equivalent of cursor.close()
// http://www.sqlite.org/c3ref/finalize.html
sqlite3_finalize(stmt);
In other words, in higher language parlance:
sqlite3_prepare(...) works like cursor.execute(...)
sqlite3_step(...) works like cursor.fetchone(...)
sqlite3_finalize(...) works like cursor.close(...);
Is this an accurate assessment of how these statements work in sqlite? Would the sqlite3_exec ever be used when fetching results?
Introduction
I'm attempting to incorporate variables into queries using C. I'm following this tutorial using sqlite tutorialspoint , and my first exposure to using SQL. The tutorial has shown me how to use Queries such as these:
Query
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
"SELECT * from COMPANY";
*So how would i go about incorporating variables into this statement, for example if i wanted to replace 1 with a variable assigned to 'ID'.
For example(My failed attempt)
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=" + variable + ";" \
"SELECT * from COMPANY";
I've googling around however I couldn't really find any material on using variables in sql queries using the C language syntax. How would i go about this in the correct and safe way, to incorporate variables and without making a program vulnereable to SQL injection?
The C-API provides the functions sqlite3_prepare_v2 and sqlite3_bind so that you can bind parameters to prepared statements. What that means is, you can use a placeholder where you want to substitute parameters within a string.
Each placeholder is referenced by an index, so you can use as many parameters as you like (up to the compile-time limit set by SQLITE_MAX_VARIABLE_NUMBER). You then bind a parameter to the placeholder at a specified index.
There are a number of functions and methods to accomplish parameter substitution, but to get you started, here's an example which binds an integer to the 1st placeholder in an sql statement:
int rc;
sqlite3 *db;
sqlite3_stmt *stmt = NULL;
...
// here I assume you open the db, and provide any other working code as needed...
...
// the employee id number.
int id_num;
...
// create the sql statement, with a single placeholder marked by '?'.
char *sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=?";
// prepare the sql statement.
rc = sqlite3_prepare_v2(db, sql, strlen(sql)+1, &stmt, NULL);
if (rc != SQLITE_OK) {
printf("Failed to prepare statement: %s\n\r", sqlite3_errstr(rc));
sqlite3_close(db);
return 1;
}
else {
printf("SQL statement prepared: OK\n\n\r");
}
// bind an integer to the parameter placeholder.
rc = sqlite3_bind_int(stmt, 1, id_num);
if (rc != SQLITE_OK) {
printf("Failed to bind parameter: %s\n\r", sqlite3_errstr(rc));
sqlite3_close(db);
return 1;
}
else {
printf("SQL bind integer param: OK\n\n\r");
}
// evaluate the prepared statement.
rc = sqlite3_step(stmt);
// other successful return codes are possible...
if (rc != SQLITE_DONE) {
printf("Failed to execute statement: %s\n\r", sqlite3_errstr(rc));
sqlite3_close(db);
return 1;
}
// deallocate/finalize the prepared statement when you no longer need it.
// you may also place this in any error handling sections.
sqlite3_finalize(stmt);
...
// close the db when finished.
sqlite3_close(db)
...
// finish your code.
The function below is supposed to check whether or not a specific entry exists in a table. If the entry exists, it returns a 1. If it doesn't, it returns a 0. However, it only returns a 0.
Table used: Database( ID int Primary Key, char(100) Place, char(100) Room ), all are NOT NULL. All of the queries shown in the results below are in Database.
//database is already open at this point
int searchForRoom(sqlite3 *db, char *place, char *room){
int result = 1;
sqlite3_stmt *stmt;
//Create SQL statement
char * sql = sqlite3_mprintf(
"Select EXISTS(Select * From Database "
"Where Place = '%q' and Room = '%q');"
, place, room);
sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);
if (sqlite3_step(stmt) != SQLITE_ROW) {
printf("ERROR 1 reading data: %s\n", sqlite3_errmsg(db));
}
//only this line of code does not output the correct result
result = sqlite3_column_int(stmt, 0);
if (sqlite3_step(stmt) != SQLITE_DONE) {
printf("ERROR 2 reading data: %s\n", sqlite3_errmsg(db));
}
printf("%s, %s evals to %d\n", place, room, result);
sqlite3_finalize(stmt);
return result;
}
The result:
place1, venue1 evals to 0
place2, venue2 evals to 0
place3, venue3 evals to 0
"Select EXISTS(Select * From Database "
The EXISTS query returns either 0 (when no such row(s) exist) or 1 (when they do). It returned 0, so no such rows existed.
I don't know why or how, but it seems that restarting my computer actually solved the problem. The function now works perfectly fine. Sorry for wasting everyone's time.
I'm trying to update a name column inside sqlite database on my C program using the following function:
void update_name(int row, wchar_t* name, int maxnamelen){
const wchar_t* update_tempate = L"UPDATE mytable SET name='%s' WHERE(id=%d);";
wchar_t* update = calloc(sizeof(wchar_t*), maxnamelen+wcslen(update_template));
swprintf(update, update_template, name, row);
sqlite3_stmt *stmt;
sqlite3_prepare16(sqdb, update, sizeof(update), &stmt, 0);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
}
but I don't get the row updated unfortunately, because I get the error near "UP" : syntax error.
How can I fix that problem?
The third parameter of sqlite3_prepare16 must be the length of the statement, in bytes.
However, sizeof(update) is the size of the update variable, which is just a pointer, which happens to have the same size as two characters.
You have to give either the actual length (which was already computed by swprintf), or just -1.
Please note that this will still blow up when the name contains a quote.
You should use parameters to avoid such formatting problems:
void update_name(int row, wchar_t* name)
{
const wchar_t* update = L"UPDATE mytable SET name=? WHERE id=?";
sqlite3_stmt *stmt;
// error handling is missing
sqlite3_prepare16(sqdb, update, -1, &stmt, 0);
sqlite3_bind_text16(stmt, 1, name, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, row);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
}
So I'm trying to build my sql statement in the for loop.
But on executing, it shows error at the very first point of the string.
Is the concatenation method wrong, cause I printed the sql statement and manually execute in postgresql and it works.
Also I had tried
char *sqlStatement = "INSERT INTO record()..VALUES();\
INSERT INTO record()..VALUES();\
INSERT INTO record()..VALUES();
"
That works.
Note that I have reduced the loop to only once and reduced the number of columns for brevity.
The code:
char sqlStatement[8000];
for(int i=0;i<1;i++) {
sprintf(&sqlStatement[0] + strlen(sqlStatement), "INSERT INTO record (\"user_id\", \"filename\", \"ports\", \"timestamp\" ... )VALUES (1, 'example%d', 0, '123456789%d', ... );", i, i,);
}
pgResult = PQexec(pgConn, sqlStatement);
if (PQresultStatus(pgResult) != PGRES_COMMAND_OK) {
printf("%s", PQresultErrorMessage(pgResult));
PQclear(pgResult);
closeSQL(pgConn);
exit(-1);
}
Error message:
ERROR: syntax error at or near ""
LINE 1: INSERT INTO captures ("user_id", "filename", "ports", "time...
^
You're calling strlen(sqlStatement) but sqlStatement is uninitialized at that point. That's undefined behavior.
Put
sqlStatement[0] = '\0';
before the loop to start out with an empty string.
By the way, exit(-1) is wrong. The only standard C exit values are 0/EXIT_SUCCESS and EXIT_FAILURE. On Unix you can use any value between 0 and 255. I'm not sure about Windows but it's probably similar. I don't know any OS where -1 is valid.
char sqlStatement[11111];
size_t_pos;
pos=0;
pos += sprintf(sqlStatement+pos, "INSERT INTO record() VALUES(%s);\n" , "Argh!" );
pos += sprintf(sqlStatement+pos, "INSERT INTO record(...);\n" ... );
pos += sprintf(sqlStatement+pos, "INSERT INTO record(...);\n" ... );
...
A real program should of course first check the return value from sprintf, before using it to increment the pos position.