SQLITE3 вставляет нулевое значение - PullRequest
2 голосов
/ 30 ноября 2011
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);

Я получаю SIGABRT в NSString * f1 как *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithUTF8String:]: NULL cString' Пожалуйста, скажите мне, что я делаю неправильно.

1 Ответ

6 голосов
/ 30 ноября 2011

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

Вы обновили это, указав SIGABRT в строке NSString * f1.

Есть две проблемы с вашим кодом, которые я вижу:

  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 может вернуть NULL, если в данных содержится NULL, но initWithUTF8String: не принимает NULL в качестве значения.

Я предлагаю сделать это:

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

Используя это, вы получите ноль NSString, если у вас в столбце будет NULL.Вы можете принять решение по этому вопросу, и это просто сделать f1 ?: @"", когда вам действительно нужна строка.

Другой подход - изменить запрос:

SELECT Field FROM Table;

На:

SELECT COALESCE(Field,'') FROM Table;

Вы больше не сможете определить, был ли Филд изначально NULL, но, возможно, вам все равно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...