Ios 联接在sqlite查询编译中不起作用

Ios 联接在sqlite查询编译中不起作用,ios,iphone,sqlite,xcode3.2,Ios,Iphone,Sqlite,Xcode3.2,为了便于学习,我正在使用sqlite编写一个简单的导航视图iphone程序。我以前在数据库中只有一个表,但现在已将其更新为两个,我的内部JOIN语句崩溃了。直接运行SQL语句似乎工作得很好。在下面的代码中,uncommented语句工作得很好,但是如果我将它们切换出去,注释语句将导致错误 static sqlite3_stmt *init_statement = nil; static sqlite3_stmt *dehydrate_statment = nil; @implementatio

为了便于学习,我正在使用sqlite编写一个简单的导航视图iphone程序。我以前在数据库中只有一个表,但现在已将其更新为两个,我的内部JOIN语句崩溃了。直接运行SQL语句似乎工作得很好。在下面的代码中,uncommented语句工作得很好,但是如果我将它们切换出去,注释语句将导致错误

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));

我对这一点还很陌生,所以如果有任何帮助,我将不胜感激。

关键是检查sqlite3\u errmsg返回的错误消息。您报告NSAssert行报告以下消息:

无法准备包含消息“无此类表:匹配”的语句

这意味着您打开的数据库没有匹配表。如果您已经在模拟器上运行过,最简单的方法就是在我使用的MacOS SQLite工具中打开数据库,您可以使用sqlite3命令行工具;你想用什么就用什么。数据库可以在~/Library/Application Support/iPhone模拟器文件夹中找到。为了更容易找到此数据库,您可能希望通过启动终端应用程序,然后运行命令chflags nohidden~/Library/来取消隐藏~/Library文件夹

无论如何,我想你会发现匹配表不在那里,也许整个数据库都是空白的。一个常见的原因是在不存在的数据库上调用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);
}
显然,这是假设您有一个数据库可以在包中使用。如果您是以编程方式创建的,那么只需在确定fileExistsAtPath不是这种情况的If块中执行该操作


请格式化问题。选择待办事项无效!我认为SELECT todo.*是正确的,问题在于pk=?,没有传递参数值。崩溃到底是什么意思?很抱歉,我的匹配表CREATE语句应该声明code10 VARCHAR25而不是name。崩溃是指程序中止,在NSAssert1行结束。pk正在通过程序传递一个值,我还添加了一个手动值以进行双重检查。我还尝试编辑SELECT todo.*以列出各个列,使其不受影响。我试图弄明白为什么程序直接转到NSAssert1,而不是在SELECT语句中成功执行表连接。这正是发生的情况。谢谢你,罗布!