SQLITE3插入一个空值

Vic*_*tor 2 sqlite ipad ios4

sqlite3_bind_int(statement, 1, nil);
Run Code Online (Sandbox Code Playgroud)

我怎样才能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);
 }
Run Code Online (Sandbox Code Playgroud)

选择 :

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);
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*her 6

sqlite3_bind_int(statement, 1, nil)将0绑定到第一个绑定点,而不是NULL.0和NULL在SQL中不是一回事.

我想你在找sqlite3_bind_null.它将NULL绑定到绑定点,如:

sqlite3_bind_null(statement, 1);
Run Code Online (Sandbox Code Playgroud)

这里没有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);
    
    Run Code Online (Sandbox Code Playgroud)

    应该:

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

我建议这样做:

NSString *f1 = field1 ? [[NSString alloc] initWithUTF8String:field1] : nil;
Run Code Online (Sandbox Code Playgroud)

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

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

SELECT Field FROM Table;
Run Code Online (Sandbox Code Playgroud)

至:

SELECT COALESCE(Field,'') FROM Table;
Run Code Online (Sandbox Code Playgroud)

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