SQLITE3插入一个空值

时间:2011-11-29 21:06:50

标签: ios4 sqlite ipad

sqlite3_bind_int(statement, 1, nil);

如何在上面的语句中添加null,因为我将此字段设为自动增量。

这是我的代码:

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);
 }

选择:

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);

我在NSString * f1中获得SIGABRT为*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithUTF8String:]: NULL cString' 请告诉我我做错了什么。

1 个答案:

答案 0 :(得分:6)

sqlite3_bind_int(statement, 1, nil)将0绑定到第一个绑定点,而不是NULL。 0和NULL在SQL中不是一样的东西。

我认为你正在寻找sqlite3_bind_null。它将NULL绑定到绑定点,如:

sqlite3_bind_null(statement, 1);

此处没有NULL参数;它是以函数的名义。

此外,未绑定参数默认为NULL。因此,除非您使用sqlite3_reset,否则根本不需要使用此功能。

(由于我们的主题是绑定和重置,我应该提到sqlite3_clear_bindings,它将所有参数绑定为NULL。)

问题2

你更新了这个以在NSString * f1行中提到SIGABRT。

我看到您的代码存在两个问题:

  1. sqlite3_column_text基于0;第一列是0,而不是1.(是的,列基于0。即使绑定是从1开始的。)

    char *field1 = (char *)sqlite3_column_text(statement, 1);
    

    应该是:

    char *field1 = (char *)sqlite3_column_text(statement, 0);
    
  2. 如果sqlite3_column_text在数据中,则
  3. NULL可以返回NULL,但initWithUTF8String:不接受NULL作为值。

  4. 我建议这样做:

    NSString *f1 = field1 ? [[NSString alloc] initWithUTF8String:field1] : nil;
    

    如果您在数据中有NSString列,则使用此结果时,您最终会得到一个NULL。您可以对此做出决定,当您真正需要字符串时,f1 ?: @""很容易做到。

    另一种方法是更改​​查询:

    SELECT Field FROM Table;
    

    要:

    SELECT COALESCE(Field,'') FROM Table;
    

    你将无法再判断Field最初是​​NULL,但也许你不在乎。