【问题标题】:sqlite3_step(statement) == SQLITE_DONE is always falsesqlite3_step(statement) == SQLITE_DONE 总是假的
【发布时间】:2013-06-03 06:37:13
【问题描述】:

我正在尝试在我的应用程序中注册一个用户。
我有一个带有 3 textfields (username, password and confirmpassword) 和一个 submit 按钮的视图控制器。

按下提交按钮时会调用以下方法:

-(IBAction)addUser
{
    NSString *tempUser,*tempPass, *tempConfPass;
    tempUser = [[NSString alloc]init];
    tempPass = [[NSString alloc]init];
    tempConfPass = [[NSString alloc]init];
    tempUser = [NSString stringWithFormat:@"%@",_mUserName.text];
    tempPass = [NSString stringWithFormat:@"%@",_mPassword.text];
    tempConfPass = [NSString stringWithFormat:@"%@",_mConfPassword.text];
    signupUser = [[UseDb alloc]init];

    flagUser = [signupUser addNewUser:_mUserName.text:_mPassword.text:_mConfPassword.text];
    if(flagUser)
    {
        myAlertViewUser = [[UIAlertView alloc] initWithTitle:@"Error" message:@"User Added"
                                                    delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];

        [myAlertViewUser show];
    }
    else {
       _mStatus.text = @"failed to add user";
       myAlertViewUser = [[UIAlertView alloc] initWithTitle:@"Error" message:@"passwords don't match"
                                delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];

       [myAlertViewUser show];
    }
}

并且这个方法被addUser方法调用:

-(BOOL)addNewUser:(NSString *)newUser :(NSString *)newPassword :(NSString *)confirmPass
{
   NSLog(@"%@....%@...%@",newUser, newPassword, confirmPass);
    sqlite3_stmt    *statement;
    const char *dbpath = [_mDatabasePathDb UTF8String];

    if (sqlite3_open(dbpath, &_mDb) == SQLITE_OK && [newPassword isEqualToString:confirmPass] && ![newUser isEqualToString:@""] && ![newPassword isEqualToString:@""])
    {
        self.userName = [NSString stringWithFormat:@"%@",newUser];
        self.password = [NSString stringWithFormat:@"%@",newPassword];

        NSString *insertSQL = [NSString stringWithFormat:
                               @"INSERT INTO USERDETAIL VALUES (\"%@\",\"%@\",\"%@\", \"%@\",\"%@\", \"%@\",\"%@\", \"%@\",\"%@\", \"%@\",\"%@\")",self.userName,self.password,@"",@"",@"",@"",@"",@"",@"",@"",@"" ];

        NSLog(@"%@",insertSQL);
        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(_mDb, insert_stmt, -1, &statement, NULL);

        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            return YES;
            /*    mUserName.text = @"";
             mPassword.text = @"";
             mConfPassword.text = @""; */

        }
        else {

            NSLog(@"failed to add user");
        }

        sqlite3_finalize(statement);
        sqlite3_close(_mDb);
    }
}

addNewUser方法中,if (sqlite3_step(statement) == SQLITE_DONE)总是出来是false,声明在之前有一些价值

sqlite3_prepare_v2(_mDb, insert_stmt, -1, &statement, NULL); 

但是在上面的语句执行完之后变成nil。我不明白为什么会这样。
请帮忙。

【问题讨论】:

  • 打印出来看看你得到了什么作为 sqlite3_step(statement)?
  • 备注:您不检查sqlite3_prepare_v2的返回值。 sqlite3_step() 返回什么?如果是 SQLITE_ERROR,sqlite3_errmsg() 告诉你什么?
  • 请注意,您的 INSERT 语句容易发生 SQL 注入 (xkcd.com/327)。您应该使用 sqlite3_bind_XXX() 函数将值绑定到准备好的语句。
  • NSLog(@"%d",sqlite3_step(statement));产生 21。这是什么意思?
  • 21 是 SQLITE_MISUSE。这可能意味着创建准备好的语句已经失败。您应该检查 sqlite3_prepare_v2() 的返回值!如果失败,请检查 sqlite3_errmsg()!

标签: ios objective-c xcode4.5


【解决方案1】:

这可能是您正在进行的检查的问题,请尝试 SQLITE_OK。它在docs 中表示为在旧接口(旧接口)中,返回值将是 SQLITE_BUSY、SQLITE_DONE、SQLITE_ROW、SQLITE_ERROR 或 SQLITE_MISUSE。使用“v2”接口,也可能返回任何其他结果代码或扩展结果代码。

if (sqlite3_prepare_v2(_mDb, insert_stmt, -1, &statement, nil) == SQLITE_OK)
        {
            if (sqlite3_step(statement) == SQLITE_DONE)
            {
               return YES;
            }
            else 
            {
              NSLog(@"failed to add user");
            }
            sqlite3_finalize(statement);
        }

您还可以找到类似的问题及其答案here

在prepare 语句后插入一个花括号,并在finalize 语句后关闭它。当您得到 SQLITE_MISUSE 时,可能是该例程调用不当。也许它是在已经完成的准备好的语句上调用的,或者是在之前返回 SQLITE_ERROR 或 SQLITE_DONE 的语句上调用的。或者可能是同一数据库连接同时被两个或多个线程同时使用。

希望这会有所帮助:)

【讨论】:

  • if (sqlite3_prepare_v2(_mDb, insert_stmt, -1, &statement, nil) == SQLITE_OK) 结果为假。
  • 检查您的查询。我猜它没有正确执行
  • 插入查询工作正常。我使用 SQLite 管理器进行了检查。
  • @MartinR 绝对不是,那是你错的地方。如果它不存在,它将创建一个新的空数据库
  • 在我使用 UseDb 的公共对象(共享实例)而不是为每个方法创建新对象后,问题得到了解决。谢谢你们的帮助..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 2012-03-22
  • 2015-03-28
  • 2019-10-11
  • 2020-10-13
  • 1970-01-01
相关资源
最近更新 更多