iPhone上的SQLite表无效?
我一直试图通过我的iphone访问SQLite3数据库,但我一直没有得到这样的表:user\u info作为一个错误 以下是我所经历的步骤: 通过命令行创建数据库: sqlite3 users.sqlite 创建表格用户信息名称文本、信息文本; 插入用户信息值'Name1','这是Name1'的信息; 从用户信息中选择*; [结果]:名称1 |这是名称1的信息 从sqlite_master中选择*; [结果]:表格|用户信息|用户信息| 3 |创建表格用户信息名称文本,信息文本 将其复制到XCode中的resources文件夹中,并选择将其复制到适当的目录中 尝试访问它并获取错误no-this table:user\u info 好的,那我怎么做3?嗯,我已经更新了一点,所以现在我尝试创建不存在的表。这是我目前的代码:iPhone上的SQLite表无效?,iphone,objective-c,cocoa-touch,ios,sqlite,Iphone,Objective C,Cocoa Touch,Ios,Sqlite,我一直试图通过我的iphone访问SQLite3数据库,但我一直没有得到这样的表:user\u info作为一个错误 以下是我所经历的步骤: 通过命令行创建数据库: sqlite3 users.sqlite 创建表格用户信息名称文本、信息文本; 插入用户信息值'Name1','这是Name1'的信息; 从用户信息中选择*; [结果]:名称1 |这是名称1的信息 从sqlite_master中选择*; [结果]:表格|用户信息|用户信息| 3 |创建表格用户信息名称文本,信息文本 将其复制到XCo
static NSString *dbname = @"users.sqlite";
-(NSString *) dbFilePath {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES
);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:dbname];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if (!success) {
fprintf(stderr, "Database is not writeable!\n");
}
return dbPath;
}
- (void)createEditableCopyOfDatabaseIfNeeded {
BOOL success;
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *writeableDBPath = [self dbFilePath];
success = [fileManager fileExistsAtPath:writeableDBPath];
if (success) {
return;
}
NSString *defaultDBPath =
[[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:dbname];
success = [fileManager
copyItemAtPath:defaultDBPath
toPath:writeableDBPath
error:&error];
if (!success) {
fprintf(stderr, "Failed to create writable database file\n");
}
}
-(void) openDB {
if (sqlite3_open([[self dbFilePath] UTF8String], &db) != SQLITE_OK) {
sqlite3_close(db);
fprintf(stderr, "Database failed to open.\n");
}
}
-(void) createTableIfNeeded {
NSString *result = @"";
sqlite3_stmt *statement;
char *sql = sqlite3_mprintf(
"CREATE TABLE IF NOT EXISTS user_info (name text info text);"
);
dbresult = sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL);
if (SQLITE_OK != dbresult) {
NSAssert1(0, "no user_info table!", nil);
fprintf(
stderr,
"Error in preparation of query: %s\n",
sqlite3_errmsg(db)
);
sqlite3_close(db);
return;
}
sqlite3_finalize(statement);
sqlite3_free(sql);
}
- (NSString *)getDatabaseEntry:(NSString *)i_name {
NSString *result = @"";
sqlite3_stmt *statement;
char *sql = sqlite3_mprintf(
"SELECT 'info' FROM 'user_info' WHERE name='%q'",
[i_name cStringUsingEncoding:NSASCIIStringEncoding]
);
dbresult = sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL);
if (SQLITE_OK != dbresult) {
fprintf(
stderr,
"Error in preparation of query: %s\n",
sqlite3_errmsg(db)
);
sqlite3_close(db);
return result;
}
dbresult = sqlite3_step(statement);
if (SQLITE_ROW == dbresult) {
char *nfo = (char *)sqlite3_column_text(statement, 0);
result = [NSString stringWithUTF8String:nfo];
}
sqlite3_finalize(statement);
sqlite3_free(sql);
return result;
}
// viewDidAppear
- (void)viewDidAppear:(BOOL)animated {
[self createEditableCopyOfDatabaseIfNeeded];
[self openDB];
[self createTableIfNeeded];
}
// Later, when I have a valid user:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
...
NSString *nfo = [self getDatabaseEntry:name.text];
...
}
这堵墙我已经贴了好几天了,所以非常感谢您的帮助。好吧,我已经修好了,但我不确定如何修好。 我创建了一个空白项目,并按照教程进行操作: 并确保这一切都有效。是的 然后我使用了这里的钻头: 将数据库复制到可写入的位置。我以前有非常相似的代码 所以现在它起作用了。 我专门用sqlite3扩展构建了一个新表。我不知道这是否真的有区别。 我还使用了:
[[NSBundle mainBundle] pathForResource:@"users" ofType:@"sqlite3"];
与之相反:
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbname];
同样,不知道这是否重要
希望这对其他人有帮助
//----------------------------------------------------------------------------
-(NSString *) dbFilePath {
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:@"users.sqlite3"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if (!success) {
fprintf(stderr, "Database is not writeable! Attempting to create writeable database.\n");
NSString *bundle_path = [[NSBundle mainBundle] pathForResource:@"users" ofType:@"sqlite3"];
success = [fileManager copyItemAtPath:bundle_path toPath:dbPath error: &error];
if (!success) {
fprintf(stderr, "Failed to create writeable database file\n");
}
}
return dbPath;
}
//----------------------------------------------------------------------------
-(void) openDB {
if (sqlite3_open([[self dbFilePath] UTF8String], &db) != SQLITE_OK) {
sqlite3_close(db);
NSAssert(0, @"Database failed to open.");
fprintf(stderr, "Database failed to open.\n");
}
}
//----------------------------------------------------------------------------
- (NSString *)getDatabaseEntry:(NSString *)i_name {
NSString *result = @"";
sqlite3_stmt *statement;
char *sql = sqlite3_mprintf(
"SELECT info FROM user_info WHERE name='%q'",
[i_name cStringUsingEncoding:NSASCIIStringEncoding]
);
dbresult = sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL);
if (SQLITE_OK != dbresult) {
fprintf(stderr,
"Error in preparation of query: %s\n",
sqlite3_errmsg(db));
sqlite3_close(db);
sqlite3_free(sql);
return result;
}
dbresult = sqlite3_step(statement);
if (SQLITE_ROW == dbresult) {
char *nfo = (char *)sqlite3_column_text(statement, 0);
result = [NSString stringWithUTF8String:nfo];
}
sqlite3_finalize(statement);
sqlite3_free(sql);
return result;
}
只有受虐狂才会在Objective-C中直接使用SQLite C API,或者取而代之。先生,我是受虐狂:我开始研究CoreData接口,但我已经了解SQL和关系数据库,因此从理论上讲,这应该是更快的解决方案。然后查看FMDB。它只是围绕SQLite C API的一个包装器,这样您就可以用本机对象和更类似可可的方式与之交互。@DaveDeLong谢谢Dave,听起来很有趣。GitHub页面上的文档非常简单,粗略的web搜索并没有引起太多关注。对FMDB的教程和文档有什么建议吗?我发现它附带的示例非常简单。如果您有问题,请随时在这里发布。我也可能会写一些文件,然后提交给ccgus的回购协议。