0

伙计们,我的片段有问题。我还必须说我是新手。我正在尝试将数据插入到 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

4 回答 4

1

必须检查 的返回值sqlite3_prepare_v2

如果其中一个sqlite3_prepare_v2或失败,您必须使用sqlite3_errmsgsqlite3_step获得实际的错误消息。

于 2014-10-25T15:23:07.027 回答
-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 包装器,它为您完成所有适当的值绑定到?占位符。

于 2014-10-25T15:43:59.670 回答
-2

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

于 2014-10-25T15:44:00.933 回答
-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()

于 2014-10-25T15:12:05.320 回答