2014-10-24 1 views
0

ОБНОВЛЕНО ВОПРОСА, проверить конец постаИОСА обитающих SQLite ошибки базы данных, окончательные данные не записывается

Я делаю приложение iPhone, и я хочу, когда первые пользователь ланчи приложения, для приложения к создать новую базу данных и заполнить ее данными plist-файла.

Вот мой взгляд сделал код загрузки:

//get database path 
NSString *symptomDatabasePath = [self symptomsDatabasePath]; 

//check if database exists and initialize if it doesn't 
if(![[NSFileManager defaultManager] fileExistsAtPath:symptomDatabasePath]) 
{ 
    [self createAndPopulateDatabase]; 
} 

Моя функция symptomDatabasePath:

//get the path of the symptoms database 
- (NSString *) symptomsDatabasePath 
{ 
NSArray *pathsArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [pathsArray objectAtIndex:0]; 
return [documentsDirectory stringByAppendingPathComponent:@"symptoms.sqlite"]; 
} 

И, наконец, моя createANdPopulateDatabase функция:

- (void) createAndPopulateDatabase 
{ 
//get query to insert symptoms into database 
NSArray *pathsArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [pathsArray objectAtIndex:0]; 
NSString *databaseDataFile = [documentsDirectory stringByAppendingPathComponent:@"symptomsDatabaseList.plist"]; 
NSString *symptomData = [NSString stringWithContentsOfFile:databaseDataFile encoding:NSUTF8StringEncoding error:NULL]; 

sqlite3 *database; 
if (sqlite3_open([[self symptomsDatabasePath] UTF8String], &database)!=SQLITE_OK) 
{ 
    sqlite3_close(database); 
    NSAssert(0, @"Failed to open database"); 
} 

NSString *createTableQuery = @"CREATE TABLE IF NOT EXISTS tbl_symptoms (symptomCode varchar(15) NOT NULL PRIMARY KEY,title varchar(255) NOT NULL,shortTitle varchar(255) NOT NULL,inclusions varchar(255) NOT NULL,exclusions varchar(255) NOT NULL,symptomCategory varchar(255) NOT NULL);"; 

char *errorMsg; 
//create new table 
if(sqlite3_exec(database, [createTableQuery UTF8String], NULL, NULL, &errorMsg)!=SQLITE_OK) 
{ 
    sqlite3_close(database); 
    NSAssert(0, @"Error creating table: %s", errorMsg); 
} 

NSString *insertQueryString = @"INSERT INTO tbl_symptoms (symptomCode, title, shortTitle, inclusions, exclusions, symptomCategory) VALUES "; 
//array containing the seperate symptom data 
NSArray *symptomArray = [symptomData componentsSeparatedByString:@"),"]; 
sqlite3_stmt *statement; 
//nsmutable array with all queries 
NSMutableArray *queryArray = [[NSMutableArray alloc] init]; 
//loop through the aray with symptoms build queries and store them in an array 
for(int i=0; i<[symptomArray count]; i++) 
{ 
    //create query string with insert command 
    NSMutableString *insertString = [[NSMutableString alloc] initWithString:insertQueryString]; 
    //append the specific symptoms data 
    [insertString appendString:[symptomArray objectAtIndex:i]]; 
    [insertString appendString:@");"]; 
    [queryArray insertObject:insertString atIndex:i]; 
} 

    //insert data into database 

for(int i=0; i<[queryArray count]; i++) 
{ 
    const char *insertChar = [[queryArray objectAtIndex:i] UTF8String]; 

    if(sqlite3_prepare_v2(database, insertChar, -1, &statement, nil)!=SQLITE_OK) 
    { 
     sqlite3_close(database); 
     NSAssert(0, @"Error filling table: %s", errorMsg); 
    } 
    if (sqlite3_step(statement)!=SQLITE_DONE) 
    { 
     NSAssert(0, @"Error inserting data into database: %s", errorMsg); 
    } 
    //finalize changes 
} 
sqlite3_finalize(statement); 
sqlite3_close(database); 
} 

Мой код немного грязный, потому что Я пытался использовать различные решения. Во всяком случае, у меня есть данные, которые я хочу ввести в этом файле в моем файле phlist:

('Z27', 'Страх перед социальной проблемой', 'Страх перед социальной проблемой', 'беспокойство/страх перед тем, социальная проблема »,« если у пациента есть социальная проблема, кодируйте проблему »,« Социальные проблемы »), (« Z28 »,« Ограниченная функция/инвалидность (Z) »,« Ограниченная функция/инвалидность (Z) », , '', '', 'Социальные проблемы'), ('Z29', 'Социальные проблемы NOS', 'Социальные проблемы NOS', 'экологические проблемы, симуляция', '', 'Социальные проблемы'

в моем файле 320 таких записей, это последние 3, потому что это те, с которыми у меня возникают проблемы.

Приложение копирует все остальные 317 записей, но не эти 3. И я знаю, что он отсутствует в конце, но это потому, что мой код добавляет его в каждый цикл.

я получаю ошибку SIGABRT и следующий код ошибки:

«завершающее приложение из-за неперехваченного исключением„NSInternalInconsistencyException“, причина:„Ошибка заполнения таблицы: (нуль)“»

Может кто-нибудь мне помочь ? Я, вероятно, сделал что-то не так с sqlite3, хотя я не понимаю, почему он не копирует последние 3 записи.

Также ранее он не копировал только последнюю запись, но после того, как я скопировал ее, чтобы увидеть, была ли проблема с самой записью, она не начала копировать последние 3: S.

Любая помощь будет принята с благодарностью

UPDATE

Так получается, что я получаю ошибки, потому что я использовал NSAssert. Теперь я использую NSLogs для регистрации моих ошибок, и приложение запускается правильно, но я все еще получаю ошибку при копировании последних 3 записей.

По моим бревнам моли в sqlite3_prepare_v2 и функции sqlite3_step терпит неудачу, но только для последних 3 записей: S

+0

Где в вашем коде это сбой? Что вы строите свой запрос с помощью изменяемой строки вместо того, чтобы использовать 'sqlite3_bind_xxx' для привязки значения в один, подготовленный оператор? – rmaddy

+0

он падает на конечные петли. Я нашел это в Интернете, но я не очень хорошо понимал инструкции. Должен ли я связывать каждую вставку отдельно весь весь запрос вместе, а затем запускать его? –

+0

Какая точная строка кода падает? – rmaddy

ответ

1

Проблемы заключается в том, что у вас есть умные цитаты.Например, я вижу, у вас есть

..., 'Social problems’), ... 

Примечания, вы начинаете, что со стандартным апостроф, но завершив его закрытие одной цитаты. Если вы посмотрите очень внимательно, они выглядят по-другому.

Замените эти умные кавычки стандартным апострофом, и это должно устранить непосредственную проблему.


Я предлагаю вам зарегистрировать SQL и тщательно изучить его. Кроме того, когда ошибка sqlite3_prepare_v2 не выполняется, вы не регистрируете соответствующее сообщение об ошибке. Вы можете сделать что-то вроде:

if (sqlite3_prepare_v2(database, insertChar, -1, &statement, nil)!=SQLITE_OK) { 
    NSLog(@"prepare failure: %s", sqlite3_errmsg(database)); 
    sqlite3_close(database); 
    NSAssert(0, @"Error filling table"); 
} 
+0

OP проверяет результат 'sqlite3_prepare_v2', но регистрирует неправильную ошибку. Фактически, для большинства проверок сбоев регистрируется неправильная ошибка. OP - используйте 'sqlite3_errmsg', чтобы получить ошибку. – rmaddy

+0

Следует также указать, что запрос должен быть подготовлен только один раз, перед циклом, предполагая, что код обновлен для правильного использования 'sqlite3_bind_xxx' для каждого значения. – rmaddy

+0

Следуя учебнику (просто получив зависание при использовании sqlite3 с xcode), так что любые ссылки с некоторыми хорошо написанными учебниками, которые помогут мне учиться, будут очень оценены. –