#objective-c #sqlite #nsmutablearray
#objective-c #sqlite #nsmutablearray
Вопрос:
Я пытаюсь вставить данные, хранящиеся в NSMutableArray, и сохранить их в базе данных SQLite.. До сих пор я смог вставить только первые 5 элементов массива или вставить их все в первый столбец базы данных. Я не могу понять, где это ломается / не работает.
Содержимое LockInfo (NSMutableArray):
LOCKINFO (
51974,
0,
2,
15,
1,
51975,
0,
24,
15,
1,
51976,
0,
20,
15,
1,
51977,
0,
23,
15,
1
)
Все, что вставляется в первую строку, это:
51974,
0,
2,
15,
1
Код:
-(void)insertLock:(NSMutableArray *)lockInfo{
char *error;
NSString *databasePath = [self dataPath:@"eloqdb.sqlite3"];
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String], amp;database) != SQLITE_OK) {
sqlite3_close(database);
NSLog(@"Could not open database");
}else{
NSLog(@"DB opened");
}
//for each element in the array, save the array index, and the contact:
NSLog(@"count %@", lockInfo);
NSLog(@"count %i", lockInfo.count);
for (int i = 0; i < lockInfo.count; i ) {
sqlite3_stmt *statement;
NSString *SQLInsert = @"INSERT OR REPLACE INTO LOCK_PLAN_CHANGE (ID, FLAG, ITEM_DOOR_ID, KEY_SERIAL, TIMEZONE_ITEM_ID) "
@"VALUES (?, ?, ?, ?, ?);";
if (sqlite3_prepare_v2(database, [SQLInsert UTF8String], -1,
amp;statement, nil) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 2, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 3, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 4, [[lockInfo objectAtIndex:3] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 5, [[lockInfo objectAtIndex:4] UTF8String], -1, NULL);
}
if (sqlite3_step(statement) != SQLITE_DONE) {
// NSAssert1(0, @"Cannot Update Table", error);
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
Ответ №1:
Ваш массив на самом деле содержит данные в lockInfo.count / 5
строках.
Измените свой цикл на:
for (int i = 0; i < lockInfo.count; i = 5) {
Затем обновите привязки до:
sqlite3_bind_text(statement, 1, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 2, [[lockInfo objectAtIndex:i 1] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 3, [[lockInfo objectAtIndex:i 2] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 4, [[lockInfo objectAtIndex:i 3] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 5, [[lockInfo objectAtIndex:i 4] UTF8String], -1, NULL);
Эти изменения поместят правильные значения в правильные столбцы и добавят правильное количество строк.
Кстати — это действительно плохая структура данных. Вы должны определить класс или структуру с 5 свойствами. Затем создайте массив этого класса или структуры.
Помимо этой основной проблемы, вы также неправильно используете подготовленную инструкцию. Вы должны подготовить инструкцию только один раз перед циклом.
Вот ваш код, написанный правильно, с улучшенной проверкой ошибок:
- (void)insertLock:(NSMutableArray *)lockInfo {
NSString *databasePath = [self dataPath:@"eloqdb.sqlite3"];
sqlite3 *database;
if (sqlite3_open([databasePath UTF8String], amp;database) != SQLITE_OK) {
NSLog(@"Could not open database");
return;
} else {
NSLog(@"DB opened");
}
//for each element in the array, save the array index, and the contact:
NSLog(@"lockInfo %@", lockInfo);
NSLog(@"count %i", lockInfo.count);
sqlite3_stmt *statement;
NSString *SQLInsert = @"INSERT OR REPLACE INTO LOCK_PLAN_CHANGE (ID, FLAG, ITEM_DOOR_ID, KEY_SERIAL, TIMEZONE_ITEM_ID) VALUES (?, ?, ?, ?, ?);";
if (sqlite3_prepare_v2(database, [SQLInsert UTF8String], -1, amp;statement, nil) == SQLITE_OK) {
for (NSInteger i = 0; i < lockInfo.count; i = 5) {
sqlite3_bind_text(statement, 1, [lockInfo[i] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 2, [lockInfo[i 1] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 3, [lockInfo[i 2] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 4, [lockInfo[i 3] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 5, [lockInfo[i 4] UTF8String], -1, NULL);
if (sqlite3_step(statement) != SQLITE_DONE) {
// NSAssert1(0, @"Cannot Update Table", error);
}
sqlite3_reset(statement);
}
sqlite3_finalize(statement);
} else {
NSLog(@"Can't prepare: %s", sqlite3_errmsg(database));
}
sqlite3_close(database);
}
Комментарии:
1. Отличное объяснение — очень четкое. Спасибо… Я проведу исследование, используя лучшую структуру данных..