我正在编写一个简单的导航视图iphone程序,使用sqlite进行学习。我之前在数据库中有一个表,但现在已将其更新为两个,并且我的INNER JOIN语句崩溃了。 SQL语句似乎可以直接运行它。在下面的代码中,未注释的语句可以正常工作,但如果我将它们切换出来,那么注释的语句将会出错。
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;
}
这些表位于同一个db:
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)
关键是检查sqlite3_errmsg
返回的错误消息。您报告的是NSAssert
行报告了该消息:
未能准备包含消息'no such table:match'
的声明
这意味着您打开的数据库没有match
表。如果你在模拟器上运行它,最简单的方法是在你选择的MacOS SQLite工具中打开数据库(我使用Base,你可以使用sqlite3
命令行工具;使用任何你想要的)。可以在~/Library/Application Support/iPhone Simulator
文件夹中找到该数据库。为了更容易找到此数据库,您可能希望取消隐藏~/Library
文件夹,方法是启动Terminal
应用程序,然后运行命令chflags nohidden ~/Library/
。
无论如何,我认为你会发现match
表不存在(也许整个数据库都是空白的)。一个常见的原因是在不存在的数据库上调用sqlite_open
,在这种情况下,它将为您创建一个空数据库。
如果是这种情况,您想要
删除您在Documents文件夹中可能包含的所有空白数据库(最简单的方法是从您的设备/模拟器中删除该应用程序)并再次运行它;和
检查数据库打开逻辑,该逻辑可能类似于:
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
不是这种情况。