5

sqlite データベースに頻繁にアクセスするアプリケーションがあります。ほとんどの場合はうまく機能しますが、データベース関数の 1 つが失敗して次のように返されることがあります。

ファイルは暗号化されているか、データベースではありません

暗号化を有効にしていませんが、これがどのように起こっているかを特定できません。一貫して再現できるわけではなく、クラッシュ ログから、メイン スレッドで発生します。

前もって感謝します。

@synchronized(self) {
    sqlite3 *database = mydb;
    int result = 0;

    static sqlite3_stmt *stmt = nil;
    if (stmt == nil) {
        const char *sql = "select sum(not isAvailable) from table1 e inner join table2 f on e.key=f.pk where f.pk=? AND e.isDeleting=0;";
        if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK) {
            NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
        }
    }

    sqlite3_bind_int(stmt, 1, obj.primaryKey);

    if (sqlite3_step(stmt) == SQLITE_ROW) {
        int val = sqlite3_column_int(stmt, 0);
        result = val;
    } else {
        [NSException raise:@"SQL Fail" format:@"SQL Failed: %s", sqlite3_errmsg(database)];
    }
    // Reset the statement for future reuse.
    sqlite3_reset(stmt);

    return result;
}
4

4 に答える 4

1

新しい暗号化された SQLite データベースを作成するか、既存の暗号化された SQLite データベースを開くには、関数 sqlite3_key を呼び出すか、データベースを開いた直後に "pragma key=" コマンドを実行してから、他のデータベース操作を実行する必要があります。あなたは既存のデータベースを開こうとしたが、暗号化された SQLite データベースを開こうとせず、上記の方法のいずれかを使用して暗号化しようとしたのではないかと思います。これは機能しませんが、発生したエラー メッセージが表示されます。暗号化されていない既存の SQLite データベースを暗号化するには、function sqlite3_rekey または "pragma rekey=" コマンドを使用する必要があります。既存の暗号化された SQLite データベースの暗号化キーを変更するには、データベースを開き、sqlite3_key (または "pragma key=") を使用してから sqlite3_rekey (または "pragma rekey=") を適用する必要があります。

于 2013-04-02T12:17:41.467 に答える
0

DBファイルが何らかの形で文字化けした場合にエラーが発生します。ただし、これが発生する正確な理由は、ちょっとしたパズルです。

アプリで他のファイルを書き込んでいる場合、誤って DB ファイルを上書きしてしまった可能性があります。また、同じ DB ファイルを 2 回開いたり、DB で 2 つの「同時」操作を行ったりした場合、このシナリオを作成できる可能性があります (ただし、SQLite のほとんどのバージョンは、これを検出してエラーを発生させるコードでコンパイルされていると思います。競合があります)。(質問: 「データベースがロックされています」というエラーが表示されることはありますか?)

于 2013-02-17T15:52:04.830 に答える