sqlite3查询适用于cmd行但在iOS 6 SImulator中不返回任何数据

时间:2012-10-05 17:59:59

标签: iphone ios xcode sqlite

我在iOS 6 app for iPad中使用了这个sqlite3表:

CREATE TABLE notes(id INTEGER PRIMARY KEY, note TEXT, noteDate TEXT, wasUploaded INTEGER);

从sqlite3命令行开始,此查询有效:

sqlite> Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `wasUploaded`=0;

1|Well|2012-10-04 22:46:23|0

在iOS iPad 6.0 Simulator上,每个查询都返回与上面完全相同的数据:

const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `id`=1";

const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `note`='Well'";

const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `noteDate`='2012-10-04 22:46:23'";

但是这个在命令行上工作正常的查询现在不返回任何数据:

const char *sqlStatement = "Select `id`,`note`,`noteDate`,`wasUploaded` FROM `notes` WHERE `wasUploaded`=0";

让我感到困惑。为什么最后一个查询不起作用?我是否需要将该列作为索引或其他内容?其他两个非索引列可以工作但不是这个。

没有错误。返回没有数据的最后一个查询给出了正常的返回代码101(sqlite3_step()已经完成执行),没有where子句的查询返回与其他三个查询相同的数据。

编辑:这是完整的代码

- (NSString *)getNotesToBeUploaded {
sqlite3 *stuDb;
NSString *thisNote;
NSMutableString *notes = [[NSMutableString alloc]init];

if (self.filePath == @"empty") {
    [self setDatabaseFilePath];
}

if (sqlite3_open([self.filePath UTF8String], &stuDb) == SQLITE_OK)
{
    // this is the query line that get changed to show stackoverflow the different results:
    const char *sqlStatement = "Select `id`,`note`,`noteDate` FROM notes WHERE `wasUploaded`=0";
    sqlite3_stmt *compiledStatement;
    int nResult = sqlite3_prepare_v2(stuDb, sqlStatement, -1, &compiledStatement, NULL);
    if ( nResult == SQLITE_OK)
    {
        int nret; // diagnostic used to watch return vaues when single stepping
        while ((nret = sqlite3_step(compiledStatement)) == SQLITE_ROW)
        {
            int id =  sqlite3_column_int(compiledStatement, 0);
            const unsigned char *note =  sqlite3_column_text(compiledStatement, 1);
            const unsigned char *noteDate =  sqlite3_column_text(compiledStatement, 2);
            int wu =  sqlite3_column_int(compiledStatement, 4);
            if (strlen((const char *)note) > 0 && strlen((const char *)noteDate) > 0)
            {
                thisNote = [NSString stringWithFormat:@"%d,%s,%s,%d\n",id, noteDate, note, wu];
                [notes appendString:thisNote];
            }
        }
    } else {
        sqlite3_finalize(compiledStatement);// prevent small memory leaks
        sqlite3_close(stuDb);
        thisNote =
        [NSString stringWithFormat:@"prepare failed with status:%d in %s at line %d path was %@,0,0\n",nResult,__FILE__,__LINE__,self.filePath];
        [notes appendString:thisNote];
        [notes appendString:@"\n"];
        return (NSString *)notes;
    }
    sqlite3_finalize(compiledStatement);
    sqlite3_close(stuDb);
}

1 个答案:

答案 0 :(得分:3)

您是否正在查看sqlite3来电的退货代码?而且,如果您未获得SQLITE_OKSQLITE_ROW,则应检查sqlite3_errmsg结果以诊断正在发生的情况。如果您希望我们帮助您,您真的应该分享您的代码。 但是,第一次使用iOS SQLite应用程序时最常见的问题是

  • 未能将数据库包含在您应用的捆绑包中。检查目标设置,确保已将数据库包含在Build Phases中。您还可以通过查看~/Library/Application Support/iPhone Simulator文件夹中模拟器中的应用程序包来确认这一点。如果您想这样做,如果您没有在终端命令行界面中输入~/Library,则可能需要取消隐藏chflags no hidden ~/Library文件夹。

  • 如果您计划从应用程序更新数据库,则在尝试开始使用之前,无法先将数据库从软件包复制到Documents文件夹。

  • 使用sqlite3_open并将成功的返回代码解释为数据库已成功打开的证据...但如果找不到数据库,sqlite3_open函数会恼人地创建一个新的空白数据库...我总是建议人们使用sqlite3_open_v2代替,如果没有找到,那么你可以省略参数来创建一个空数据库。

当然,也可能存在大量与代码相关的问题(调用函数的顺序,无法检查返回代码等)。如果没有看到代码,就无法进一步评论。

我觉得有必要分享我的最终SQLite编程建议,值得查看FMDB Objective-C SQLite wrapper library,这极大地简化了iOS中的SQLite编程。


<强>更新

看了你的代码,它看起来很好。我刚刚运行它(仅调整到NSLog而不是附加说明):

- (void)test2
{
    sqlite3 *stuDb;
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *databaseName = [documentsDirectory stringByAppendingPathComponent:@"test.db"];

    if (sqlite3_open([databaseName UTF8String], &stuDb) == SQLITE_OK)
    {
        // this is the query line that get changed to show stackoverflow the different results:
        const char *sqlStatement = "Select `id`,`note`,`noteDate` FROM notes WHERE `wasUploaded`=0";
        sqlite3_stmt *compiledStatement;
        int nResult = sqlite3_prepare_v2(stuDb, sqlStatement, -1, &compiledStatement, NULL);
        if ( nResult == SQLITE_OK)
        {
            int nret; // diagnostic used to watch return vaues when single stepping
            while ((nret = sqlite3_step(compiledStatement)) == SQLITE_ROW)
            {
                int id =  sqlite3_column_int(compiledStatement, 0);
                const unsigned char *note =  sqlite3_column_text(compiledStatement, 1);
                const unsigned char *noteDate =  sqlite3_column_text(compiledStatement, 2);
                int wu =  sqlite3_column_int(compiledStatement, 4);
                if (strlen((const char *)note) > 0 && strlen((const char *)noteDate) > 0)
                {
                    // thisNote = [NSString stringWithFormat:@"%d,%s,%s,%d\n",id, noteDate, note, wu];
                    // [notes appendString:thisNote];
                    NSLog(@"%d,%s,%s,%d\n",id, noteDate, note, wu);
                }
            }
        } else {
            //sqlite3_finalize(compiledStatement);// prevent small memory leaks, not needed if the prepare failed
            sqlite3_close(stuDb);
            NSLog(@"prepare failed with error %s", sqlite3_errmsg(stuDb));
            return;
        }
        sqlite3_finalize(compiledStatement);
        sqlite3_close(stuDb);
    }
}

我得到了结果:

2012-10-05 15:44:06.075 test8[1574:c07] 1,2012-10-05 19:43:37,ABC,0
2012-10-05 15:44:06.076 test8[1574:c07] 2,2012-10-05 19:43:46,XYZ,0

所以问题必须在数据库本身。从你上次的评论来看,听起来重建数据库就是为你做的。那很好。

相关问题