iPhone - Использование базы данных sql - оператор вставки не выполнен - PullRequest
2 голосов
/ 29 декабря 2010

Я использую базу данных sqlite в своем приложении для iphone. У меня есть таблица, которая имеет 3 целочисленных столбца. Я использую следующий код для записи в эту таблицу базы данных.

-(BOOL)insertTestResult {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* dataBasePath = [documentsDirectory stringByAppendingPathComponent:@"test21.sqlite3"];     

BOOL success = NO;
sqlite3* database = 0;
if(sqlite3_open([dataBasePath UTF8String], &database) == SQLITE_OK) 
{
    BOOL res = (insertResultStatement == nil) ? createStatement(insertResult, &insertResultStatement, database) : YES;
    if(res)
    {
        int i = 1;
        sqlite3_bind_int(insertResultStatement, 0, i);
        sqlite3_bind_int(insertResultStatement, 1, i);
        sqlite3_bind_int(insertResultStatement, 2, i);

        int err = sqlite3_step(insertResultStatement);
        if(SQLITE_ERROR == err) 
        {
            NSAssert1(0, @"Error while inserting Result. '%s'", sqlite3_errmsg(database));
            success = NO;
        }
        else 
        {
            success = YES;
        }
        sqlite3_finalize(insertResultStatement);
        insertResultStatement = nil;            
    }
}
sqlite3_close(database);    
return success;}

Команда sqlite3_step всегда дает ошибку как 19. Я не могу понять, в чем проблема.

Таблицы создаются с использованием следующих запросов:

CREATE TABLE [Patient] (целое число PID NOT NULL ПЕРВИЧНОЕ КЛЮЧЕВОЕ КЛЮЧЕВОЕ АВТОНИЦИРОВАНИЕ, текст PFirstName NOT NULL, текст PLastName, текст PSex NOT NULL, текст PDOB NOT NULL, текст обучения НЕ NOT, текст PHandedness, текст PType) * 1008

CREATE TABLE PatientResult(PID INTEGER,PFreeScore INTEGER NOT NULL,PForcedScore INTEGER NOT NULL,FOREIGN KEY (PID) REFERENCES Patient(PID))

У меня только одна запись в таблице пациентов с PID = 1

BOOL createStatement(const char* query, sqlite3_stmt** stmt, sqlite3* database){
BOOL res = (sqlite3_prepare_v2(database, query, -1, stmt, NULL) == SQLITE_OK);
if(!res) 
    NSLog( @"Error while creating %s => '%s'", query, sqlite3_errmsg(database));
return res;}

Ответы [ 4 ]

1 голос
/ 31 декабря 2010

Я обновил ваш код. Сделай так:

-(BOOL)insertTestResult {
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];
    NSString* dataBasePath = [documentsDirectory stringByAppendingPathComponent:@"test21.sqlite3"];     

    BOOL success = NO;
    sqlite3* database = 0;
    if(sqlite3_open([dataBasePath UTF8String], &database) == SQLITE_OK) 
    {
        BOOL res = (insertResultStatement == nil) ? createStatement(insertResult, &insertResultStatement, database) : YES;
        if(res)
        {
            int i = 1;
            sqlite3_bind_int(insertResultStatement, 1, i);  //updated
            sqlite3_bind_int(insertResultStatement, 2, i);  //updated
            sqlite3_bind_int(insertResultStatement, 3, i);  //updated

            int err = sqlite3_step(insertResultStatement);
            if(SQLITE_ERROR == err) 
            {
                NSAssert1(0, @"Error while inserting Result. '%s'", sqlite3_errmsg(database));
                success = NO;
            }
            else 
            {
                success = YES;
            }
            sqlite3_finalize(insertResultStatement);
            insertResultStatement = nil;            
        }
    }
    sqlite3_close(database);    
    return success;
}

Причина в том, что вы начали индекс с 0, это неправильно. Когда вы вставляете в таблицу базы данных, вам нужно начать вставку из индекса 1. Индекс 0 начинается при попытке извлечь данные из базы данных.

1 голос
/ 31 декабря 2010

Я сделал небольшое изменение (методом проб и ошибок) и его работа.Я не знаю причину, почему он работает ........ Вот мое изменение в коде:

sqlite3_bind_int(insertResultStatement, 1, i);
sqlite3_bind_int(insertResultStatement, 2, i);
sqlite3_bind_int(insertResultStatement, 3, i);

Изменение состоит в том, что ранее мой первый второй параметр sqlite3_bind_int был запущен с "0", а не начиная с" 1 ".

Если кто-то найдет причину, обновите эту цепочку ......

1 голос
/ 29 декабря 2010

Гугл нашел это , который сказал мне это:

#define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */

Вы где-то нарушаете ограничение. Либо ваш PID не является уникальным, либо внешний ключ к пациенту не относится к действительному идентификатору пациента, это мои предположения.

0 голосов
/ 29 декабря 2010

Было бы полезно, если бы вы также опубликовали свой код createStatement ().Без этого я собираюсь догадаться, что вы не можете указать значение в INSERT для одного из столбцов NOT NULL.

...