библиотечная процедура вызвана из последовательности - PullRequest
1 голос
/ 01 апреля 2011

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

-(void) writeintoDatabase:(id)value1:(id)value2:(id)value3 {
sqlite3 *database;


    const char *sql = "insert into UserData(firstName,lastName,userName) Values(?, ?, ?)";
    sqlite3_stmt *insert_statement;
    sqlite3_prepare_v2(database, sql, -1, &insert_statement, NULL);

    sqlite3_bind_text(insert_statement, 1, [value1 UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(insert_statement, 2, [value1 UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(insert_statement, 3, [value1 UTF8String], -1, SQLITE_TRANSIENT);

    NSInteger keyID;
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database) ); 

        keyID = sqlite3_last_insert_rowid(database);


    sqlite3_reset(insert_statement);

}

Ответы [ 4 ]

5 голосов
/ 05 апреля 2011

спасибо mmcomb, спасибо мат. Из ваших советов я полностью решил проблему.

  • Сначала Я не проверял путь к БД, а затем открывал подключение.

  • Во-вторых после подготовки заявления и ограничения соответствующие переменные мне пришлось вызвать sqlite3_step перед вызовом sqlite3_last_insert_rowid.

  • В-третьих Мне нужно было позвонить sqlite3_finalize, чтобы освободить ресурсы.

  • В-четвертых мне нужно sqlite3_close соединение.

Ошибка «библиотечная подпрограмма вызвана вне последовательности» произошла из-за неправильного открытия и закрытия соединения.

Это правильный код:

NSInteger keyID; // in .h class
NSMutableArray *user;// in .h class

-(void) writeintoUserDatabase:(NSString*)value1:(NSString*)value2:(NSString*)value3 
{
sqlite3* database;
databaseName = @"UserData";// create a db with this name and keep it in app resources folder
NSString *pathToDatabase;
NSArray *documentPaths =         NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
pathToDatabase = [documentsDir stringByAppendingPathComponent:databaseName];
int databaseReturnCode = sqlite3_open([pathToDatabase UTF8String], &database);
NSLog(@"databaseReturnCode %d",databaseReturnCode);
if(databaseReturnCode == SQLITE_OK) {

const char *sql = "insert into UserData(firstName,lastName,userName) Values(?, ?, ?)";
sqlite3_stmt *insert_statement;
    sqlite3_prepare_v2(database, sql, -1, &insert_statement, NULL);

    sqlite3_bind_text(insert_statement, 1, [value0 UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(insert_statement, 2, [value1 UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 3, [value2 UTF8String], -1, SQLITE_TRANSIENT);

printf( "is there an error?: %s\n", sqlite3_errmsg(database) ); 

    while(sqlite3_step(insert_statement) == SQLITE_ROW) 
    {
        NSString *aFirstName  = [NSString stringWithUTF8String:      (char*)sqlite3_column_text(insert_statement, 1)];
        NSString *aLastName  = [NSString stringWithUTF8String:(char *)sqlite3_column_text(insert_statement, 2)];
        NSString *aUserName  = [NSString stringWithUTF8String:(char *)sqlite3_column_text(insert_statement, 3)];
users = [[NSMutableArray alloc]initWithObjects:aFirstName,aLastName,aUserName,nil];
    }

keyID = sqlite3_last_insert_rowid(database);


    sqlite3_reset(insert_statement);

sqlite3_finalize(insert_statement);

}
sqlite3_close(database);    
}
2 голосов
/ 01 апреля 2011

В вашем коде отсутствует звонок на sqlite3_step. Вы должны вызвать это после того, как подготовили оператор и связали соответствующие переменные, и прежде чем вызывать sqlite3_last_insert_rowid.

Подробности смотрите в документации по sqlite3_step, а всегда проверяйте коды ошибок, возвращаемые этим типом функции.

Не вызывайте sqlite3_errormsg, если ошибки не произошло, ее результат в этом случае не определен.

Наконец, вам нужно вызвать sqlite3_finalize в операторе, если вы где-то не держите его в руках. В противном случае вы получите утечки ресурсов и, в конечном итоге, вылетите. sqlite3_reset не освобождает ресурсы, он просто «очищает» оператор, чтобы вы могли повторно запустить его с другими связанными значениями.

1 голос
/ 01 апреля 2011

Перед подготовкой вашего sqlite stament / запроса вам необходимо открыть соединение с вашей базой данных ...

sqlite3* database;
NSString pathToDatabase = @"/blah/blah/database.db";
const char* pathToDatabaseUTF8 = [databasePath UTF8String];
databaseReturnCode = sqlite3_open(pathToDatabaseUTF8, &database);

См. Документацию по sqlite для метода sqlite3_open для получения дополнительной информации.

О, и не забудьте закрыть это соединение ...

int sqlite3_close(database);
0 голосов
/ 16 декабря 2016

В моем случае это была строка, содержащая некоторые специальные символы, как это было (') одиночное двоеточие, я заменил его на ("") пробел, и он начал работать. [[[items objectAtIndex: locBtn.tag] valueForKey: @ "description"] stringByReplacingOccurferencesOfString: @ "'" withString: @ ""]

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