我正在重写我的一些应用程序,这次是使用故事板和iOS 7编码。因此,我有兴趣从头开始。基本上,这些是从SQLite数据库中提取单词及其定义的应用程序,在表格视图中显示单词,然后允许用户点击单词以在另一个视图控制器中查看其定义。我的问题是,虽然我可以打开数据库,但我从未通过sql prepare语句。这是代码:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Set up the database variable
databaseName = @"MilSpeak.db";
// Get the path to the documents directory and append the database
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
NSLog(@"databasePath returns: %@", databasePath);
// Execute the "checkDatabaseStatus" method
[self checkDatabaseStatus];
// Query the database for all object records and construct the navyTerms array
[self runDatabaseQuery];
}
- (void)checkDatabaseStatus {
// Create a File Manager object to check the status of the database
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:databasePath] == YES) {
NSLog(@"Database exists");
}
}
- (void)runDatabaseQuery {
// Set up the database object
// Initialize the navyTerms array
wordArray = [[NSMutableArray alloc] init];
definitionArray = [[NSMutableArray alloc] init];
// Open the database from the device's filesystem
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(@"Opening the database for SQL pull");
// Set up the SQL statement and compile if for faster access
const char *sqlStatement = "select * from terms where usn = 'Y' or usn = 'y' order by word asc";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to wordArray and definitionArray
NSLog(@"Stepping through the database rows");
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the database from the resulting row(s)
NSString *aWord = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDefinition = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
// Populate the arrays with the values from the database pulls
[wordArray addObject:aWord];
NSLog(@"word: %@", aWord);
[definitionArray addObject:aDefinition];
}
}
else {
NSLog(@"There is a problem with the sqlite3_prepare_v2 statement.");
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
// Count the contents of the database arrays
NSLog(@"wordArray contains %lu items", (unsigned long)[wordArray count]);
NSLog(@"definitionArray contains %lu items", (unsigned long)[definitionArray count]);
allTerms = [NSDictionary dictionaryWithObjects:wordArray
forKeys:definitionArray];
NSLog(@"allTerms contains %lu items", (unsigned long)[allTerms count]);
}
// Close the database
sqlite3_close(database);
}
我不确定代码的粘贴(结束大括号)发生了什么,但它就在那里,我知道数据库存在且有条目 - 我用终端来调用条款表的内容
第一个号码是一个自动号码,所以我应该在我的表格视图中看到4,714个条目。更重要的是,如果你看一下runDatabaseQuery方法的代码,你会倾向于使用大量的日志语句来检查某些条件。我把一个作为其他的东西放到sql prepare if语句中,这就是触发的内容。
出于某种原因,我的应用程序不喜欢该声明。如果有人能给我任何帮助来解决这个问题,我将永远感激不尽。提前感谢任何回复。
在另一位用户的建议之后,我输入了一个sql_error语句。这是新的runDatabaseQuery方法:
- (void)runDatabaseQuery {
// Set up the database object
// Initialize the navyTerms array
wordArray = [[NSMutableArray alloc] init];
definitionArray = [[NSMutableArray alloc] init];
// Open the database from the device's filesystem
if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
NSLog(@"Opening the database for SQL pull");
// Set up the SQL statement and compile if for faster access
const char *sqlStatement = "select * from terms where usn = 'Y' or usn = 'y' order by word asc";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to wordArray and definitionArray
NSLog(@"Stepping through the database rows");
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the database from the resulting row(s)
NSString *aWord = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDefinition = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
// Populate the arrays with the values from the database pulls
[wordArray addObject:aWord];
NSLog(@"word: %@", aWord);
[definitionArray addObject:aDefinition];
}
}
else {
NSLog(@"There is a problem with the sqlite3_prepare_v2 statement.");
NSLog(@"%s SQLITE_ERROR '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database));
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
// Count the contents of the database arrays
NSLog(@"wordArray contains %lu items", (unsigned long)[wordArray count]);
NSLog(@"definitionArray contains %lu items", (unsigned long)[definitionArray count]);
allTerms = [NSDictionary dictionaryWithObjects:wordArray
forKeys:definitionArray];
NSLog(@"allTerms contains %lu items", (unsigned long)[allTerms count]);
}
// Close the database
sqlite3_close(database);
}
结果日志语句毫无意义。此数据库中只有一个表,名为terms,但显然,我的app无法识别表:
我使用了终端并获得了以下内容:
所以我很困惑这里到底发生了什么。任何和所有帮助将不胜感激。
我遵循了@ maddy关于更改sql open语句的建议:
if (sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK) {
仍然得到了相同的结果。在viewDidLoad和checkDatabaseStatus方法中,我试图验证数据库是否在正确的位置,但也许我没有正确地执行此操作。我将再次回顾代码,看看我可能错过了什么。
答案 0 :(得分:0)
我不确定发生了什么,但现在可行了。我稍微调整了checkDatabaseStatus方法,添加了一个复制命令以确保数据库在正确的位置。那段代码在这里:
- (void)checkDatabaseStatus {
// Create a File Manager object to check the status of the database
NSFileManager *fileManager = [NSFileManager defaultManager];
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
if ([fileManager fileExistsAtPath:databasePathFromApp] == YES) {
NSLog(@"Database exists");
}
else {
NSLog(@"Dude, where's my database?");
}
// Copy in the database from the application package
[fileManager copyItemAtPath:databasePathFromApp
toPath:databasePath
error:nil];
if ([fileManager fileExistsAtPath:databasePath] == YES) {
NSLog(@"Database exists");
}
else {
NSLog(@"Dude, again, where's my database?");
}
}
再次感谢Maddy。您对数据库位置的问题可能就是这样做的,但现在它运行得很好! (至少到目前为止:D)我现在必须弄清楚我想对所有数据做些什么。