问题
sqlite3_bind_int(statement, 1, nil);
How can I add a null
in my above statement , as I am making this field auto increment.
Here's my code :
if (sqlite3_open([[self dataFilePath] UTF8String], &database)!= SQLITE_OK)
{
sqlite3_close(database);
NSAssert(0, @"Failed to open database");
}
NSLog(@"json count ========== %i",[jsonArray count]);
for (int i =0 ; i < [jsonArray count]; i++)
// while (i < [jsonArray count])
{
dictionary = [jsonArray objectAtIndex:i];
char *errorMsg;
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(database, [insertQuery UTF8String], -1, &statement, nil) == SQLITE_OK)
{
// NSLog(@"%@",[dictionary valueForKey:@"text"]);
sqlite3_bind_null(statement, 1);
sqlite3_bind_text(statement, 2, [[dictionary valueForKey:@"date"] UTF8String], -1, NULL);
// NSLog(@"date %@",[dictionary valueForKey:@"date"]);
sqlite3_bind_text(statement, 3, [[dictionary valueForKey:@"text"] UTF8String], -1, NULL);
// NSLog(@"text %@",[dictionary valueForKey:@"text"]);
}
if (sqlite3_step(statement) != SQLITE_DONE)
{
NSAssert1(0, @"Error updating table: %s", errorMsg);
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
To select :
sqlite3 *database;
if (sqlite3_open([[self dataFilePath] UTF8String], &database)
!= SQLITE_OK) { sqlite3_close(database);
NSAssert(0, @"Failed to open database");
}
NSString *query = [self selectQueryInDB];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String],
-1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW)
{
int row = sqlite3_column_int(statement, 0);
if (row == indexPathRow+1)
{
char *field1 = (char *)sqlite3_column_text(statement, 1);
char *field2 = (char *)sqlite3_column_text(statement, 2);
NSString *f1 = [[NSString alloc] initWithUTF8String:field1];
NSString *f2 = [[NSString alloc] initWithUTF8String:field2];
NSString *fullData = [NSString stringWithFormat:@"%@ %@",f1,f2];
NSLog(@"%@",fullData);
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
I am getting SIGABRT in NSString *f1 as *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithUTF8String:]: NULL cString'
Please tell me what i am doing wrong.
回答1:
sqlite3_bind_int(statement, 1, nil)
will bind 0 to the first bind point, not NULL. 0 and NULL are not the same things in SQL.
I think you're looking for sqlite3_bind_null
. It binds NULL to a bind point, as in:
sqlite3_bind_null(statement, 1);
There's no parameter here for NULL; it's in the name of the function.
Also, unbound parameters default to NULL. So unless you're using sqlite3_reset
, you shouldn't need to use this at all.
(Since we're on the topic of bindings and resets, I should mention sqlite3_clear_bindings
, which binds all parameters to NULL.)
Problem 2
You updated this to mention a SIGABRT in the NSString *f1 line.
There's two problems with your code that I see:
sqlite3_column_text
is 0 based; the first column is 0, not 1. (Yes, columns are 0 based. Even though bindings are 1-based.)char *field1 = (char *)sqlite3_column_text(statement, 1);
should be:
char *field1 = (char *)sqlite3_column_text(statement, 0);
sqlite3_column_text
can returnNULL
ifNULL
is in the data, butinitWithUTF8String:
does not acceptNULL
as a value.
I suggest doing this:
NSString *f1 = field1 ? [[NSString alloc] initWithUTF8String:field1] : nil;
Using this, you'll end up with a nil NSString
if you had a NULL
column in the data. You can make decisions on this, and it's easy to do f1 ?: @""
when you really need a string.
Another approach is to change the query:
SELECT Field FROM Table;
To:
SELECT COALESCE(Field,'') FROM Table;
You'll no longer be able to tell if Field was originally NULL
, but maybe you don't care.
来源:https://stackoverflow.com/questions/8317732/sqlite3-inserting-a-null-value