我的sqlite prepare语句有些困难。我得到一个错误,说我的桌子不存在,虽然我已经在多个地方检查了它,它确实存在,所以我很困惑。
数据库存在并运行我的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()会为您创建一个空数据库,但我知道它存在,因此会产生挫败感。您可以给我的任何帮助或指导将非常感激。
答案 0 :(得分:6)
就你眼前的问题而言,它会变得简单。
你说你已经“清理并再次构建”了,但是你真的从模拟器中删除了旧的应用程序吗?手动删除应用程序,或者更简单,只需从“iOS模拟器”菜单中选择“重置内容和设置”即可完全重置模拟器。有时Xcode不知道要复制哪些文件(特别是在这种情况下,你在设备上运行它可能会改变模拟器包中文件的时间戳!)
再次运行该应用程序。
如果应用程序无法按预期工作,请从Mac打开模拟器文件夹中的数据库,然后检查数据库以确保表格在那里,并且正如您预期的那样。因此,导航到应用程序,打开包(您可能必须选择“显示包内容”选项),确认数据库的存在,但同样重要的是,在您喜欢的Mac中打开数据库的这个特定副本{ {1}}选择工具并确认那里存在的表格。
让我们知道您的发现。同样,它必须是简单的,例如:
也许重建应用程序的过程并非重新安装所有内容;我偶尔遇到Xcode选择在我的模拟器上安装时没有重新复制的问题;
也许您项目中的数据库被意外地放在子目录中,更糟糕的是,您可能有两个副本位于不同的目录中;
也许您的Xcode项目中的数据库丢失(或者在表或文件的名称中有拼写错误或(例如,在设备的情况下),文件名大写不正确);
等
对于很多这些错误,在完全重置模拟器本身之前,您不会注意到该问题。它可能有一百万件小事,但希望完全重置模拟器并重新开始将帮助您找到问题。当涉及到这些问题时,它总是 。
其他一些小的意见:
您可能不应该从捆绑包中打开数据库。以编程方式将其从捆绑包复制到sqlite3
文件夹,然后从那里打开数据库。我知道这似乎是不必要的,但这对于各种原因很重要(如果数据库在应用程序运行期间发生变化,如果db意外地在您身上创建,请不要让Xcode对变更的事情感到困惑(即使只是文件时间戳)在Xcode背后改变的捆绑等等。)
如果您需要数据库,则应使用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文件。