2

sqlite の準備ステートメントに問題があります。複数の場所でチェックインしたにもかかわらず、テーブルが存在しないというエラーが表示され、テーブルが存在するため、混乱しています。

  • ファイルは正しいiPhone Simulator Applicationフォルダーにあります
  • ファイルがプロジェクトに追加され、プロジェクト ナビゲーターで表示可能になります
  • それは私のビルド段階にもあります-バンドルリソースのコピーエリア。
  • 掃除をしてまた走り始めました。
  • データベースが存在し、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() が空のデータベースを作成することは理解していますが、存在することはわかっているため、フラストレーションが生じます。あなたが私に与えることができるどんな助けや指導も大歓迎です.

4

3 に答える 3

6

あなたの差し迫った問題に関して言えば、それは単純なものになるでしょう。

  1. 「クリーンアップして再度ビルドした」と言っていますが、実際に古いアプリをシミュレーターから削除しましたか? アプリを手動で削除するか、より簡単に、「iOS シミュレーター」メニューから「コンテンツと設定のリセット」を選択してシミュレーターを完全にリセットします。Xcode は、どのファイルをコピーするかを把握するのが苦手な場合があります (特に、デバイスで Xcode を実行すると、シミュレーターのバンドル内のファイルのタイムスタンプが変更される可能性があるこのような場合に!)

  2. アプリを再度実行します。

  3. アプリが期待どおりに動作しない場合は、Mac からシミュレーター フォルダーのデータベースを開き、データベースをチェックアウトして、テーブルがそこにあり、期待どおりに正確であることを確認します。アプリに移動し、バンドルを開き (「パッケージの内容を表示する」オプションを選択する必要がある場合があります)、データベースの存在を確認しますが、同様に重要なこととして、お気に入りの Macsqlite3ツールでデータベースのこの特定のコピーを開きます。そこにテーブルの存在を確認します。

見つけたものをお知らせください。繰り返しますが、次のような単純なものにする必要があります。

  • おそらく、アプリを再構築するプロセスは、すべてを再インストールすることではありませんでした。シミュレーターへのインストール中に Xcode が何かを再コピーしないことを選択するという問題がときどきありました。

  • プロジェクト内のデータベースが誤ってサブディレクトリに配置された可能性があります。さらに悪いことに、2 つのコピーが異なるディレクトリに配置されている可能性があります。

  • おそらく、Xcode プロジェクトのデータベースにテーブルまたはファイルの名前がありません (またはタイプミスがあるか、(デバイスの場合は特に) ファイル名の大文字が正しくありません)。

  • 等。

これらのエラーの多くは、シミュレータ自体を完全にリセットするまで問題に気付かないでしょう。可能性のある小さなことは無数にありますが、シミュレーターを完全にリセットして最初からやり直すと、問題を見つけるのに役立つことを願っています。この種の問題に関しては、常に単純なことです。


その他のマイナーな観察事項:

  1. おそらく、バンドルからデータベースを開くべきではありません。プログラムでバンドルからDocumentsフォルダーにコピーし、そこからデータベースを開きます。不必要に思えることはわかっていますが、無数の理由で重要です (アプリの操作中に db が変更された場合、誤って db が作成された場合、変更されたものについて Xcode を混乱させないでください (ファイルのタイムスタンプだけであっても))。 Xcode の背後でバンドルが変更されるなど)

  2. データベースがそこにある必要がある場合は、sqlite3_open_v2フラグに SQLITE_OPEN_READWRITE または SQLITE_OPEN_READONLY のいずれかを使用して、 を使用する必要があります (ただし、は含めないSQLITE_OPEN_CREATEでください)。空のデータベースを作成したり、変更したりする機会を sqlite に与えてしまうと頭痛の種になります。

于 2013-02-02T02:40:11.640 に答える
1

私はあなたと同じ問題に遭遇しました。IOS が指定されたデータベース ファイルを見つけられない場合、デフォルトでは、エラーをスローする代わりに作成されます。そのため、IOS が作成した空白のデータベース ファイルを開く必要があります。そのため、予期したテーブルが含まれていることはありません。私が対処すること: 1 *.sqlite3 という名前のリソース ファイルをプロジェクトにバンドルする必要があります。 2 次に、[NSBundle mainBundle] pathFordirectory ...... 関数を使用して、適切なデータベース ファイルを検索する必要があります。その後、期待どおりのデータベース ファイルを開くことができ、適切に操作できます。

よろしくお願いします、

于 2014-05-02T01:55:35.783 に答える
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 ファイルを作成していたからです。

于 2015-02-23T16:54:53.217 に答える