【问题标题】:SQLite will not prepare query when accessing database in Xcode在 Xcode 中访问数据库时 SQLite 不会准备查询
【发布时间】:2012-07-21 05:57:55
【问题描述】:

我是一名初学 iPhone 开发人员,试图从 Xcode 4.3 中的 sqlite 数据库中获取信息。我的数据库(名为 DB_Info.sqlite)与 .h 和 .m 文件位于同一目录中,并且我还将数据库拖到 Xcode 左侧栏中的文件夹部分。

能否请您快速查看一下我的代码并告诉我我的错误在哪里?我使用 NSLogs 在最后一个 if 语句中确定问题发生的位置,并且它是用 cmets 编写的。提前非常感谢您!

#import <sqlite3.h>
@implementation Player
{
    sqlite3 *DB_Info;
    NSString *databasePath;
    NSString *docsDir;
    NSArray *dirPaths;
}

-(Player*)createPlayer:(NSString*)playerName
{        

    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = [dirPaths objectAtIndex:0];
    databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"DB_Info.sqlite"]];
    const char *dbpath = [databasePath UTF8String];
    sqlite3_stmt *statement;

    if (sqlite3_open(dbpath, &DB_Info) == SQLITE_OK) { //works fine

        NSString *querySQL = [NSString stringWithFormat: @"SELECT * FROM playerlist WHERE fullName=\"%@\"", playerName];

        const char *query_stmt = [querySQL UTF8String];

        if (sqlite3_prepare_v2(DB_Info, query_stmt, -1, &statement, NULL) == SQLITE_OK) { //PROBLEM: This is where the problem is, and the if statement never goes through
        //....rest of code here
        } else {
        NSLog(@"Error");
        }
}

【问题讨论】:

  • NSLog(@"%@", querySQL);并仔细检查 querySQL 是正确的查询
  • 您正在打开文档文件夹中的数据库。你那里抄的?因为如果它不存在,sqlite3_open 将为您创建一个空白数据库。您大概 (a) 想要将 db 从捆绑包复制到文档(假设您将其包含在捆绑包中); (b) 使用 sqlite3_open_v2 而不是 sqlite_open。

标签: objective-c ios database xcode sqlite


【解决方案1】:

首先,不仅仅是说“错误”,而是记录 SQL 错误消息

NSLog(@"%s SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database));` 

它会准确地告诉你出了什么问题。人们第一次做SQL项目的一个常见错误是找不到表。如果是这样,请继续阅读。 (如果没有,请随意忽略其余部分。)

其次,您正在 Documents 文件夹中查找您的数据库。您是否在某个时候明确地将它从您的捆绑包复制到您的 Documents 文件夹中?还是您以编程方式创建它?但如果你提前准备好,它不会在 Documents 文件夹中,直到你复制到那里。

第三,我还建议您考虑使用sqlite3_open_v2 而不是sqlite3_open。您正在检查这是否是 SQLITE_OK,但这可能会给人一种错误的安全感。 sqlite3_open 将创建一个数据库,如果它不存在,这显然不是你的意图。在您使用此方法之前,您的应用程序可能应该从捆绑包中复制数据库或为您创建数据库和表(并且您没有显示,所以我不确定您是否正在这样做)。无论如何,如果sqlite3_open_v2 函数不存在,它不会创建数据库,除非您通过包含SQLITE_OPEN_CREATE 明确请求它这样做。因此,如果找不到,类似以下内容将不会创建数据库:

if (sqlite3_open_v2(dbpath, &DB_Info, SQLITE_OPEN_READWRITE, NULL) == SQLITE_OK) {

如果为您创建了一个空白数据库,我建议您通过模拟器菜单上的“重置内容和设置”重置您的模拟器,或者明确删除该应用程序,以便任何可能有的空白数据库已创建可以删除。如果您在设备上运行此应用,请删除该应用并重新安装。

第四,如果数据库已经提前创建好了,你确认数据库已经包含在“Copy Bundle Resources”设置中了吗?例如:

第五,如果您在模拟器上运行应用程序,您可以随时浏览模拟器的文件结构并确保您的文件在您认为的位置。您还可以运行 Mac OS sqlite 程序来检查模拟器正在使用的数据库,以确保一切正常。您甚至可以直接在模拟器使用的数据库中测试您的 SQL,这对于诊断目的很有用。 (或者,如果您不喜欢基于 Mac 文本的 sqlite 程序,您还可以购买/下载图形工具,例如 Base。)在您执行此操作之前,您可能需要先配置您的 Mac,以便您可以轻松浏览模拟器的文件,需要您启动终端程序,然后发出命令:

chflags nohidden ~/Library

然后您可以浏览到“~/Library/Application\ Support/iPhone\ Simulator/5.1/Applications/”,然后浏览您拥有的各种应用程序并确保您的 db 文件在那里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多