sqlite3_step(statement)== SQLITE_DONE一直返回false

时间:2014-10-25 15:00:40

标签: ios objective-c iphone sqlite ios8.1

伙计我的代码片段存在问题。我还必须说我是新手。我正在尝试将数据插入到sqlite中。但我一直都失败了,因为sqlite_step == sqlite_done一直都会返回false。我在这里做错了什么。之前我做过类似的事情并且工作正常。以下是代码

sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];

if(sqlite3_open(dbpath, &_db) == SQLITE_OK){
    NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO userInfo (name, email, username, password) VALUES (\"%@\",\"%@\",\"%@\",\"%@\")", self.txtName.text, self.txtEmail.text, self.txtUsername.text, self.txtPassword.text];
    if([self validateRegistration])
    {
        const char *insert_statement = [insertSQL UTF8String];
        sqlite3_prepare_v2(_db, insert_statement, -1, &statement, NULL);

        if(sqlite3_step(statement) == SQLITE_DONE){
            [self showUIAlertWithMessage:@"User added to the database" andTitle:@"Message"];
            self.txtName.text = @"";
            self.txtEmail.text = @"";
            self.txtUsername.text = @"";
            self.txtPassword.text = @"";
            self.txtConfirmPassword.text = @"";
        }else{
            [self showUIAlertWithMessage:@"Failed to add the user" andTitle:@"Error"];
        }
        sqlite3_finalize(statement);
        sqlite3_close(_db);
    }
}

4 个答案:

答案 0 :(得分:1)

必须检查sqlite3_prepare_v2的返回值。

如果sqlite3_prepare_v2sqlite3_step失败,您必须获得sqlite3_errmsg的实际错误消息。

答案 1 :(得分:-1)

如果您检查sqlite3_prepare_v2的结果,则几乎肯定不是SQLITE_OK。如果你看sqlite3_errmsg,它会告诉你究竟出了什么问题:

if (sqlite3_prepare_v2(_db, insert_statement, -1, &statement, NULL) != SQLITE_OK) {
    NSLog(@"insert failed: %s", sqlite3_errmsg(_db));

不相关,但您不应使用stringWithFormat来构建SQL。您应该在SQL中使用?占位符,然后使用sqlite3_bind_text()(或其他)手动绑定值。

const char *insert_statement = "INSERT INTO userInfo (name, email, username, password) VALUES (?, ?, ?, ?)";

if (sqlite3_prepare_v2(_db, insert_statement, -1, &statement, NULL) != SQLITE_OK) {
    NSLog(@"prepare failed: %s", sqlite3_errmsg(_db));

if (sqlite3_bind_text(statement, 1, [self.txtName.text UTF8String], -1, NULL) != SQLITE_OK) 
    NSLog(@"bind 1 failed: %s", sqlite3_errmsg(_db));

if (sqlite3_bind_text(statement, 2, [self.txtEmail.text UTF8String], -1, NULL) != SQLITE_OK) 
    NSLog(@"bind 2 failed: %s", sqlite3_errmsg(_db));

if (sqlite3_bind_text(statement, 3, [self.txtUsername.text UTF8String], -1, NULL) != SQLITE_OK) 
    NSLog(@"bind 3 failed: %s", sqlite3_errmsg(_db));

if (sqlite3_bind_text(statement, 4, [self.txtPassword.text UTF8String], -1, NULL) != SQLITE_OK) 
    NSLog(@"bind 4 failed: %s", sqlite3_errmsg(_db));

if(sqlite3_step(statement) == SQLITE_DONE) {
    [self showUIAlertWithMessage:@"User added to the database" andTitle:@"Message"];
    self.txtName.text = @"";
    self.txtEmail.text = @"";
    self.txtUsername.text = @"";
    self.txtPassword.text = @"";
    self.txtConfirmPassword.text = @"";
}else{
    NSLog(@"step failed: %s", sqlite3_errmsg(_db));
    [self showUIAlertWithMessage:@"Failed to add the user" andTitle:@"Error"];
}

如果您觉得这很麻烦,我建议您考虑FMDB,一个SQLite包装器,它会为您?占位符执行所有适当的值绑定。

答案 2 :(得分:-2)

您可以使用sqlite3_exec()

char *err;
int code = sqlite3_exec(_db,insert_statement,NULL,NULL,&err);
if (code != SQLITE_OK) {
    NSLog(@"something went wrong: %s", err);
}

然后,您倾向于使用prepare函数来读取这样的数据:

sqlite3_stmt *stmt;
int code = sqlite3_prepare_v2(_db,_query,-1,&stmt,NULL);
if (code == SQLITE_OK) {
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        // Retrieve data here e.g.
        // int num = sqlite3_column_int(stmt, 0);
    }
}

请参阅sqlite3_exec()

的文档here

答案 3 :(得分:-2)

我遇到了这个问题,因为我没有根据我的插入语句更新我的create table语句,因为我更改了一些我要插入的值。