大家好,
我正在重写我的一些应用程序,这次使用故事板和 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 方法的代码,您会发现我倾向于使用大量日志语句来检查某些条件。我将一个作为 else 放到 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 的表,但显然,我的应用程序无法识别该表:
我使用终端并得到以下信息:
所以我对这里到底发生了什么感到非常困惑。任何和所有的帮助将不胜感激。
我遵循了@maddy 关于更改 sql open 语句的建议:
if (sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK) {
仍然得到相同的结果。在 viewDidLoad 和 checkDatabaseStatus 方法中,我试图验证数据库是否在正确的位置,但也许我没有正确地做到这一点。我将再次回顾代码,看看我可能错过了什么。