I have a function that accepts 3 parameters, these are used to construct SQL queries that do various things to various tables in my database. I have tried converting the current code which just uses standard NSString replacement in the query strings but am having a problem following a couple of simple looking guides.
This is what I had before:
NSString *queryStrInsert = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@)", tableName, columns, values];
This is what I now have:
NSString *queryStrInsert = [NSString stringWithFormat:@"INSERT INTO ? (?) VALUES (?)"];
const char *sqlInsert = [queryStrInsert UTF8String];
if ((sqlite3_open([[self filePath] UTF8String], &congressDB)==SQLITE_OK))
{
if (sqlite3_prepare_v2(congressDB, sqlInsert, -1, &stmtInsert, NULL)==SQLITE_OK)
{
if(sqlite3_bind_text(stmtInsert, 0, [tableName UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(@"Binding 0 did not work");
}
if(sqlite3_bind_text(stmtInsert, 1, [columns UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(@"Binding 1 did not work");
}
if(sqlite3_bind_text(stmtInsert, 2, [values UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(@"Binding 2 did not work");
}
}
}
My code has problems at sqlite3_prepare_v2 (have also tried sqlite3_prepare) with:
near "?": syntax error
The 3 bind statements never fire. I have tried moving above the prepare but the SLITE_OK also returns false for each one.
The code worked fine before (without parameterised queries) but would like it to be more secure and to handle apostrophes etc.
Thanks.
EDIT:
It seems part of the problem is that table and column names cannot be paramterized only the values can.
Updated code:
NSString *queryStrInsert = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (?)", tableName, columns];
[self openDB];
const char *sqlInsert = [queryStrInsert UTF8String];
if ((sqlite3_open([[self filePath] UTF8String], &congressDB)==SQLITE_OK))
{
if (sqlite3_prepare_v2(congressDB, sqlInsert, -1, &stmtInsert, NULL)==SQLITE_OK)
{
if(sqlite3_bind_text(stmtInsert, 1, [values UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
NSLog(@"Binding 2 did not work");
} else {
NSLog(@"Binding 2 worked - ,%@", stmtInsert);
}
}
}
This now gives error:
1 values for 6 columns
I think I have a much bigger problem here, I am trying to generate fairly dynamic SQL queries here and not have lots and lots of static insert queries. You can see from my original code I was trying to build a flexible query that can take different numbers of columns/values based on what table the query was being run against. I have effectively created a variable string for list of columns and their values but I'm fairly sure now that this approach will not work with parameters. For example the parameter for values in this case is:
'8ffed886-5f7c-e311-a863-000c29beef51','','','','1389623548','Rick Sanchez'
AS it's parameterised, the whole string gets treated as one value. Don't suppose there's a nice easy way of doing what I am trying here? If not I will have to revert to the original method and just carry out a basic NSString replace for ' to be '' etc...