sqlite prepare语句错误 - 没有这样的表

时间:2013-02-01 23:36:36

标签: iphone ios objective-c sqlite

我的sqlite prepare语句有些困难。我得到一个错误,说我的桌子不存在,虽然我已经在多个地方检查了它,它确实存在,所以我很困惑。

  • 该文件位于正确的iPhone模拟器应用程序文件夹中
  • 该文件已添加到我的项目中,并可在项目导航器中查看
  • 它也在我的构建阶段 - 复制捆绑资源区域。
  • 我已经清理并再次开始跑步。
  • 数据库存在并运行我的sql语句让我只是 结果我预料到了。

    - (NSMutableArray *) getMyWorkout{
    NSMutableArray *workoutArray = [[NSMutableArray alloc] init];
    @try {
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    
    NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"IOSDB.sqlite"];
        NSLog(@"Db path is %@",dbPath);
    BOOL success = [fileMgr fileExistsAtPath:dbPath];
    
    if(!success) {
        NSLog(@"Cannot locate database file '%@'.", dbPath);
    }
    
    if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)){
        sqlite3_close(db);
        NSLog(@"Failed to open database with message '%s'.", sqlite3_errmsg(db));
    }
    
    const char *sql = "SELECT Id, type, difficulty, duration, description FROM workoutTbl";
    sqlite3_stmt *sqlStatement;
    
    if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK){
    
    NSLog(@"%s Prepare failure '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(db), sqlite3_errcode(db));
    }        //...
    

当我运行它时,我得到文件路径和以下错误

    2013-02-01 18:07:08.060 TriShake[9251:c07] -[MyWorkoutList getMyWorkout] Prepare failure 'no such table: workoutTbl' (1)

我已经检查了其他这些问题,但一直无法找到解决方案

据我所知,如果数据库路径不存在,sqlite3_open()会为您创建一个空数据库,但我知道它存在,因此会产生挫败感。您可以给我的任何帮助或指导将非常感激。

3 个答案:

答案 0 :(得分:6)

就你眼前的问题而言,它会变得简单。

  1. 你说你已经“清理并再次构建”了,但是你真的从模拟器中删除了旧的应用程序吗?手动删除应用程序,或者更简单,只需从“iOS模拟器”菜单中选择“重置内容和设置”即可完全重置模拟器。有时Xcode不知道要复制哪些文件(特别是在这种情况下,你在设备上运行它可能会改变模拟器包中文件的时间戳!)

  2. 再次运行该应用程序。

  3. 如果应用程序无法按预期工作,请从Mac打开模拟器文件夹中的数据库,然后检查数据库以确保表格在那里,并且正如您预期的那样。因此,导航到应用程序,打开包(您可能必须选择“显示包内容”选项),确认数据库的存在,但同样重要的是,在您喜欢的Mac中打开数据库的这个特定副本{ {1}}选择工具并确认那里存在的表格。

  4. 让我们知道您的发现。同样,它必须是简单的,例如:

    • 也许重建应用程序的过程并非重新安装所有内容;我偶尔遇到Xcode选择在我的模拟器上安装时没有重新复制的问题;

    • 也许您项目中的数据库被意外地放在子目录中,更糟糕的是,您可能有两个副本位于不同的目录中;

    • 也许您的Xcode项目中的数据库丢失(或者在表或文件的名称中有拼写错误或(例如,在设备的情况下),文件名大写不正确);

    对于很多这些错误,在完全重置模拟器本身之前,您不会注意到该问题。它可能有一百万件小事,但希望完全重置模拟器并重新开始将帮助您找到问题。当涉及到这些问题时,它总是


    其他一些小的意见:

    1. 您可能不应该从捆绑包中打开数据库。以编程方式将其从捆绑包复制到sqlite3文件夹,然后从那里打开数据库。我知道这似乎是不必要的,但这对于各种原因很重要(如果数据库在应用程序运行期间发生变化,如果db意外地在您身上创建,请不要让Xcode对变更的事情感到困惑(即使只是文件时间戳)在Xcode背后改变的捆绑等等。)

    2. 如果您需要数据库,则应使用sqlite3_open_v2,使用SQLITE_OPEN_READWRITE或SQLITE_OPEN_READONLY作为标志(但包括Documents) 。这会让头痛给sqlite一个机会为你创建一个空白数据库,或者修改它,所以永远不要给它机会。

答案 1 :(得分:1)

我遇到了与你相同的问题。如果IOS找不到指定的数据库文件,默认情况下它会为您创建一个而不是抛出错误。所以你必须打开为你创建的IOS数据库文件,这是空白的,所以它当然包含你期望的表。 我处理的是什么: 1您必须将名为* .sqlite3的资源文件捆绑到项目中 2然后你必须使用[NSBundle mainBundle] pathFordirectory ......函数来搜索你正确的数据库文件。  然后你可以打开你想要的数据库文件,并且可以正常运行

致以最诚挚的问候,

答案 2 :(得分:1)

没有足够的代表评论杰克的帖子,但这对我很有帮助。

在我的情况下,我错误地输入了资源扩展的路径:

// Wrong
NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:@"productList"
                                                         ofType:@"sqlite3"];

// Should have been (added db ext)
NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:@"productList"
                                                     ofType:@"db"];

我总是会超越:

if (sqlite3_open([sqLiteDb UTF8String], &_database) == SQLITE_OK))

因为它自动为我创建了一个db文件。