Добавление значений NULL в базу данных SQLite с помощью FMDB и NSDictionary

Я столкнулся с ловушкой 22. Я использую причудливый метод FMDB withParameterDictionary для вставки данных в мою базу данных SQLite следующим образом:

NSDictionary *aircraftDict = [NSDictionary dictionaryWithObjectsAndKeys:
                              self.aircraftIdTextField.text, @"aircraft_id",
                              self.makeModelTextField.text, @"make_model",
                              self.categoryClassTextField.text, @"category_class",                                  
                              @YES, @"updated_flag",                                 
                              nil];

NSString *addAircraftQuery = @"INSERT INTO aircrafts (aircraft_id, make_model, category_class, updated_flag) VALUES (:aircraft_id, :make_model, :category_class, :updated_flag)";

[db executeUpdate:addAircraftQuery withParameterDictionary:aircraftDict];

Проблема в том, что когда одно из этих текстовых полей пустое, оно усекает NSDictionary, поскольку значение nil сообщает словарю, что оно находится в конце списка значений.

Я могу прекрасно обойти эту проблему, убедившись, что у меня есть пустой объект для каждого значения в словаре (например, как строка @"").

Но затем мои значения поступают в мою базу данных SQLite как «пустое» значение вместо NULL. Это может не иметь большого значения, но я слышал, что использование NULL займет меньше места в базе данных.

Как я могу вставить NULL в мою базу данных без преждевременного усечения моего NSDictionary?


person Clifton Labrum    schedule 13.08.2013    source источник


Ответы (3)


Вы можете сделать это, не используя «причудливый» метод withParameterDictionary, а вместо этого используя скучный метод executeUpdate следующим образом:

NSString *addAircraftQuery = @"INSERT INTO aircrafts (aircraft_id, make_model, category_class, updated_flag) VALUES (?, ?, ?, ?)";

[db executeUpdate:addAircraftQuery, self.aircraftDict, self.makeModelTextField.text, self.categoryClassTextField.text, @YES];
person HalR    schedule 14.08.2013
comment
Возможно, я подумаю о том, чтобы добавить немного этой обыденности в мой в остальном дразнящий код. ;) Спасибо за вашу помощь. - person Clifton Labrum; 14.08.2013
comment
Спасибо мне тоже помогло - person malhal; 05.03.2014

Потратил некоторое время на изучение этого тоже. Решение для меня (используя Swift, но Objective C должен быть таким же) состоит в том, чтобы использовать NSNull вместо nil

person RRP    schedule 24.04.2015

Чтобы это было интересно, попробуйте это, у меня работает:

NSDMutableDictionary *aircraftDict = [NSDMutableDictionary dictionary];
// only insert non-nil text fields
if(self.aircraftIdTextField.text){
    aircraftDict[@"aircraft_id"] = self.aircraftIdTextField.text;
}
etc for all other text fields...

NSArray* keys = [aircraftDict allKeys];
NSMutableArray *prefixedKeys = [NSMutableArray array];
            [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                [prefixedKeys addObject:[NSString stringWithFormat:@":%@",obj]];
            }];
NSString *addAircraftQuery = [NSString stringWithFormat: @"INSERT INTO aircrafts (%@) VALUES (%@)",[keys componentsJoinedByString:@","],[prefixedKeys componentsJoinedByString:@","]];
[db executeUpdate:addAircraftQuery withParameterDictionary:aircraftDict];

Теперь вставка содержит только те поля, которые вы хотите вставить, поэтому она очень эффективна.

person malhal    schedule 06.03.2014