みなさん、アロハ。
今回はストーリーボードと iOS 7 用のコーディングを使用して、いくつかのアプリを書き直しています。そのため、ゼロから始めることに興味がありました。基本的に、これらは SQLite データベースから単語とその定義を取得し、テーブル ビューに単語を表示し、ユーザーが単語をタップして別のビュー コントローラーでその定義を表示できるようにするアプリです。私の問題は、データベースを開くことはできますが、SQL 準備ステートメントを通過できないことです。コードは次のとおりです。
- (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);
}
コードの貼り付け (閉じ中かっこ) で何が起こったのかはわかりませんが、それはすべてそこにあります。データベースが存在し、エントリがあることはわかっています。ターミナルを使用して、terms テーブルの内容を呼び出しました。
最初の番号は自動番号なので、テーブル ビューには 4,714 のエントリが表示されるはずです。さらに重要なことに、runDatabaseQuery メソッドのコードを見ると、特定の条件をチェックするために多くのログ ステートメントを使用する傾向があることがわかります。私は1つを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という名前のテーブルが1つしかありませんが、明らかに、私のアプリはテーブルをそのように認識できません:
ターミナルを使用して、次のものを取得しました。
だから私はここで正確に何が起こっているのかについて非常に混乱しています。どんな助けでも大歓迎です。
sql open ステートメントをそのまま変更することに関する @maddy の提案に従いました。
if (sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK) {
それでも同じ結果が得られました。viewDidLoad メソッドと checkDatabaseStatus メソッドで、データベースが適切な場所にあることを確認しようとしましたが、正しく行われなかった可能性があります。コードをもう一度見直して、見逃している可能性があるものを確認します。