【问题标题】:while (sqlite3_step(statement) == SQLITE_ROW) Loop is not workingwhile (sqlite3_step(statement) == SQLITE_ROW) 循环不工作
【发布时间】:2014-04-10 11:09:33
【问题描述】:

我调试过代码,但不知道为什么 While 语句没有执行。放置 NSlog 后,我知道它与结果不匹配。 101 并且 SQLITE_ROW 等于 100。

但是查询有结果。如果我从表名中获取 Select *,它将返回结果并执行 while 语句。如果我获取结果

sql_stmt = [NSString stringWithFormat:@"SELECT * FROM DeviceType WHERE upper(TypeName) = upper('%@')", deviceType];

虽然语句永远不会执行,所以请帮忙。不知道问题出在哪里。

代码如下:

NSArray* paths  =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString* documentsDirectory = [paths objectAtIndex:0];

NSString* path = [documentsDirectory stringByAppendingPathComponent:@"ClientDB.sqlite"];

NSString* sql_stmt = [self searchStringForLocalData];

BOOL found = NO;

if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
    const char* sql1 =  [sql_stmt UTF8String]; 

    sqlite3_stmt *statement;

    NSNumber *typeCount;

    typeCount = 0;

    if (sqlite3_prepare_v2(database, sql1, -1, &statement, NULL) == SQLITE_OK)
    {

        NSLog(@" %d, %d ",sqlite3_step(statement),SQLITE_ROW);

        while (sqlite3_step(statement) == SQLITE_ROW)   {

            // The second parameter indicates the column index into the result set.
            int primaryKey1 = sqlite3_column_int(statement, 0);


    NSNumber *typeId = [[NSNumber alloc] initWithInt:primaryKey1];

NSString *typeName =[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];

            NSString* sql_stmt1 = [NSString stringWithFormat:@"SELECT COUNT(*) FROM Devices WHERE DeviceTypeId =%d",primaryKey1];


            const char *sql1 =  [sql_stmt1 UTF8String];

            sqlite3_stmt *statement;

            NSNumber *typeCount;

            typeCount = 0;

【问题讨论】:

  • 那么,sqlite3_step 返回什么代码,sqlite3_errmsg 报告什么??
  • 那么,sqlite3_step 返回什么代码,sqlite3_errmsg 报告什么??

标签: ios iphone objective-c sqlite


【解决方案1】:

尝试使用以下语法

while(sqlite3_step(stmt)!=SQLITE_DONE)
{
     //do ur processing
   for(i=0;i<NO_OF_COLS;i++)
   {
    char * tmp1=sqlite3_column_text(stmt,i);
        if(tmp1!=NULL)
        {
            //use the value
        }
        else
        {
            //use a default
        }
   }
}

【讨论】:

  • 我已经尝试过这种方式。它允许进入while循环内部。但是当代码尝试获取第一行的结果时,它会使应用程序崩溃并显示行内没有任何内容 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'*** + [NSString stringWithUTF8String :]: NULL cString' *** 第一次抛出调用栈:
  • 如果表中的 col 为空 sqlite3 api 返回一个空指针,因此请尝试添加一个检查 sqlite3_column_text(stmt,i)!=null
  • 我改变了这个语句 sql_stmt = [NSString stringWithFormat:@"SELECT * FROM DeviceType WHERE upper(TypeName) = upper('%@')", deviceType]; To sql_stmt = [NSString stringWithFormat:@"SELECT COUNT(*) FROM DeviceType WHERE upper(TypeName) = upper('%@')", deviceType] 现在打印 NSLog (100,100) 但我现在想知道它的匹配。但它仍然没有进入循环,任何想法
  • 当您执行 count(*) 查询时,它会返回单独返回的行数。没有数据,所以它会退出循环。这是预期的行为。试试那个空检查
  • 是的,它为空。但是当我执行这个语句 const char *sql = "SELECT * FROM DeviceType ORDER BY lower(TypeName)";它返回我 7 结果
【解决方案2】:

正如评论中已经提到的,代码为NSLog 调用了一次sqlite3_step,然后在while 循环的条件下调用了第二次。 如果您的查询只返回一条记录,则第一个 sqlite3_step 调用将跳转到该记录,然后第二个 sqlite3_step 调用将报告(正确)没有进一步的结果可用。

只需删除 NSLog 调用即可。

或者,只调用一次sqlite3_step,并为日志记录和循环使用相同的返回值:

int rc;
...
while (1) {
    rc = sqlite3_step(statement);
    NSLog(@" %d, %d ", rc, SQLITE_ROW);
    if (rc != SQLITE_ROW)
        break;
    ...
}
if (rc != SQLITE_DONE)
    NSLog(@"error: %s", sqlite3_errmsg(database));

【讨论】:

  • -1 因为您没有记录 sqlite3_errmsg 错误。
【解决方案3】:

这表明您的桌子完全是空的。您可能需要检查插入是否正常工作。如果您使用sqlite3_prepare_v2 准备带有一些? 标记的语句,请记住毕竟要执行您的查询。就像这样:

if(sqlite3_step(stmt) == SQLITE_DONE) NSLog(@"INSERTED");
else NSLog(@"NO INSERTED");

注意:只有当你的查询错误时才会显示错误,而不是你准备好的语句是否被执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2015-05-14
    相关资源
    最近更新 更多