【问题标题】:Cannot select from sqlite3 database无法从 sqlite3 数据库中选择
【发布时间】:2012-04-09 11:41:19
【问题描述】:

我在读取 sqlite3 数据库时遇到了一些问题。

-(void) readMessengesFromDatabase {
    sqlite3 *database;

    messenges = [[NSMutableArray alloc] init];

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        NSLog(@"Connection OK");
        const char *sqlStatement = "select * from MessagesData";
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) NSLog(@"connect to table OK");    else NSLog(@"connect to table FALSE");
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { //не проходит условие
            NSLog(@"Connection to table OK");
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                NSLog(@"Read rows OK");
                NSString *dbMessageID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                NSString *dbMessageText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *dbMessageDate = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
                NSString *dbMediaOrNot = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

                Message *messege = [[Message alloc] initWithName:dbMessageText messageID:dbMessageID messageDate:dbMessageDate mediaOrNot:dbMediaOrNot];

                [messenges addObject:messege];

                [messege release];
            }
        }
        sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);    
}

我的第一个 NSLog 显示了与数据库的连接是否正常。但下一步“从 MessagesData 中选择 *”和 if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) NSLog(@"connect to table OK"); else NSLog(@"connect to table FALSE"); 显示“连接到 FALSE 表”。尝试使用终端从我的数据库表中选择并得到错误 "unable to open database file" 。我的错误在哪里?我的代码中没有发现任何问题...

【问题讨论】:

  • 您选择不使用 Core Data 的任何原因?
  • 我很乐意使用 Core Data,但我的编程水平太低了,还不能使用它:)
  • @Eugene 我听说 FMDB 太晚了。我的项目几乎准备好了,在这个阶段不想编辑它......
  • 你是从线程调用这个函数吗?

标签: objective-c ios sqlite


【解决方案1】:

如果您打印sqlite3_prepare_v2 返回的错误代码,则诊断问题会容易得多。数值可以在this page找到。

int errorCode = sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);
if(errorCode != SQLITE_OK) {
    NSLog(@"Connect to table failed: %d", errorCode); 
}

但是,如果您在sqlite3 命令行工具中甚至无法从数据库中进行选择,我建议您检查该文件是否存在、是否可读且格式是否正确。

尝试在您的模拟器中重现错误(如果失败,请将数据库文件复制到您的计算机,例如使用 Organizer)。尝试使用sqlite3 运行查询(我知道您确实尝试过,但请确保您正在检查以下内容)。

如果您收到消息Error: file is encrypted or is not a database,则表示数据库文件已损坏。如果你得到Error: no such table:,这意味着你的数据库不存在,是空的,或者根本没有得到表。如果你得到(如你的问题):Error: unable to open database(你在打开 sqlite 时得到这个,而不是在执行查询时得到),这意味着 sqlite 无法读取文件(例如权限)。

【讨论】:

  • 我的错误代码是“1”。会是什么?缺少数据库?尝试运行我的旧项目版本,它们有同样的错误(但它以前工作过!)。
  • 您确定该文件存在于该路径中吗? [[NSFileManager defaultManager] fileExistsAtPath: databasePath]会告诉你
  • 很奇怪。刚刚从 Simulator 文件夹打开数据库,实际上数据库文件存在,但它不包含任何表。但是我的项目数据库有 2 个表。
  • 我重复了我的查询并得到了与我上一篇文章中相同的错误。更重要的是,当我从模拟器中删除数据库并手动从 PC 复制它时,我的项目开始完全按照我想要的方式工作。所以我认为问题包含在应对过程中。
【解决方案2】:

我猜你的数据库无法连接。 试试我的答案来自Here...

我在这里提到了一些事情,我相信你会没事的

让我知道它有效

【讨论】:

  • 我也尝试运行我的旧项目版本,他们有同样的错误,但他们以前工作过。可能是 xCode 或 Simulator 错误?
【解决方案3】:

编写代码来检查表是否存在。在你执行查询选择之前,你应该检查创建表是否不存在......

NSLog(@"连接正常");

 sqlite3_exec(database,"CREATE TABLE IF NOT EXISTS MessagesData (ID INTEGER PRIMARY KEY AUTOINCREMENT ,"
                             "FirstName TEXT,LastName TEXT"));

   const char *sqlStatement = "select * from MessagesData";

如果好用请点赞

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多