JOIN不工作在SQLite查询编译

问题描述:

我正在写一个简单的导航视图iPhone程序使用SQLite的学习目的。我以前在数据库中有一个表,但现在已经将它更新为两个,并且我的INNER JOIN语句崩溃了。 SQL语句似乎很好地直接运行它。在下面的代码中,未注释的语句工作得很好,但是如果我将它们切换出来,则注释掉的语句将会出错。JOIN不工作在SQLite查询编译

static sqlite3_stmt *init_statement = nil; 
static sqlite3_stmt *dehydrate_statment = nil; 

@implementation ICD9 
@synthesize primaryKey,text,priority,status,match; 

- (id)initWithPrimaryKey:(NSInteger)pk database:(sqlite3 *)db { 

    if (self = [super init]) { 
     primaryKey = pk; 
     database = db; 
     if (init_statement == nil) { 
      const char *sql = "SELECT text,priority,complete FROM todo WHERE pk=?"; 
     //const char *sql = "SELECT todo.*, match.code10 FROM todo INNER JOIN match ON match.text = todo.text WHERE pk=1;"; 
     if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) { 
       NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
     } 
    } 
    return self; 
} 

的表是在同一个数据库:

CREATE TABLE todo(pk INTEGER PRIMARY KEY, text VARCHAR(25), priority INTEGER, complete BOOLEAN); 
CREATE TABLE match(matchid INTEGER PRIMARY KEY, text VARCHAR(25), name VARCHAR(25)); 

我很新的这所以任何帮助,将不胜感激。

+0

请格式化问题。 –

+0

'SELECT todo。,'无效! –

+0

我认为'SELECT todo。*'是正确的,问题出现在'pk =?'中,没有传递参数值。 –

关键是要检查由sqlite3_errmsg返回的错误消息。您报告您的NSAssert行报告消息:

failed to prepare statement with message 'no such table: match'

这意味着,你已经打开的数据库没有一个match表。如果你已经在模拟器上运行了这个工具,最简单的方法就是在你选择的MacOS SQLite工具中打开数据库(我使用Base,你可以使用sqlite3命令行工具;使用你想要的任何东西)。该数据库可以在您的~/Library/Application Support/iPhone Simulator文件夹中找到。为了更容易找到这个数据库,您可能需要启动Terminal应用程序,然后运行命令chflags nohidden ~/Library/来取消隐藏您的~/Library文件夹。

无论如何,我认为你会发现match表不存在(也许整个数据库将是空白的)。一个常见的原因是在不存在的数据库上调用sqlite_open,在这种情况下,它会为您创建一个空白数据库。

如果是这样的话,你要

  • 删除你可能在你的文档文件夹中(这样做是从你的设备/模拟器删除的应用程序最简单的方式)的任何空白数据库和再次运行;和

  • 检查数据库开放的逻辑,这可能应该是这个样子:

    NSString *filename = @"yourdb.sqlite"; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:[filename stringByDeletingPathExtension] ofType:[filename pathExtension]]; 
    NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
    NSString *path = [documentsPath stringByAppendingPathComponent:filename]; 
    
    if (![fileManager fileExistsAtPath:path isDirectory:NO]) 
    { 
        NSError *error = nil; 
        [fileManager copyItemAtPath:bundlePath toPath:path error:&error]; 
        NSAssert(error == nil, @"Unable to copy %@ to %@", bundlePath, path); 
    } 
    

    显然,这种假设你有一个数据库,准备好你的包使用。如果你是以编程方式创建它,那么只需在if块中执行该操作,并确定它不是fileExistsAtPath

+0

这就是发生了什么事。谢谢你,罗伯! – AaronB