web-dev-qa-db-ja.com

SQLite削除カスケードが機能しない

Android 4.2、SQLite 3.7.11を使用して、Quizzesテーブルからスキーマを下にある行を削除すると、QuizQuestionsテーブルの対応する行が削除されません。

何が悪いのかわからない。入れてみました

db.execSQL("PRAGMA foreign_keys = ON;"); 

create tableステートメントの前後。

テーブルステートメントを作成します。

CREATE TABLE quizzes(quiz_name TEXT PRIMARY KEY COLLATE NOCASE);

CREATE TABLE quizQuestions(quiz_name TEXT, question_id INTEGER,
     PRIMARY KEY(quiz_name, question_id),
     FOREIGN KEY(quiz_name) REFERENCES quizzes(quiz_name) ON DELETE CASCADE,
     FOREIGN KEY(question_id) REFERENCES questions(question_id) ON DELETE CASCADE);
34
Dan14021

誰かがquizQuestionsまたはquizzesから削除している場合、データベースはquestionsから行を削除する必要があります。外部キーのサポートがオフになっていて、任意の値を含むことができる通常の列しかない場合、entire外部キー制約は無視されます。

SQLiteのデフォルトはPRAGMA foreign_keys = OFF毎回openデータベース。これは、テーブルまたはスキーマのプロパティではありません。

SQLiteOpenHelperを使用する場合は、onOpenに入れてください。これは、データベースが開かれるたびに呼び出される場所です。 onCreateは、データベースの作成時に一度だけです。


SQLiteOpenHelperを初めて呼び出すときにgetWriteableDatabaseが呼び出すのは

  1. onConfigure毎回、APIレベル> = 16が必要
  2. データベースファイルの存在とバージョンに応じて、トランザクション内で以下が呼び出されます
    • onCreateデータベースファイルがない場合。通常、これが発生するのは、アプリの存続期間全体で1回だけです。
    • onUpgradeデータベースのバージョン(PRAGMA user_version-データベースファイル内に保存)は、SQLiteOpenHelperのコンストラクタで提供されるバージョンよりも小さいです。コードでバージョンをバンプするたびに発生します。
    • ファイルが存在し、バージョンが一致する場合は何もありません。
  3. onOpen毎回

SQLiteOpenHelperの同じインスタンスがすでに開いているデータベースを持っている場合、それはそれを返すだけで、上記の何も起こりません。

67
zapl

Androidアプリでデータベースを開いた直後にこれを追加してみてください:

db.execSQL("PRAGMA foreign_keys=ON");

これにより、外部キーのサポートがオンになります。これは、ON DELETE CASCADEが正しく機能するために必要です。

24
mvp

Sqliteはデフォルトで外部キー制約を無効にするため、次のようにして有効にする必要があります以下のように、DBhelperクラスのonOpenメソッドを単にオーバーライドします

public class YourOwnDbHelper extends SQLiteOpenHelper {
    @Override
    public void onOpen(SQLiteDatabase db){
        super.onOpen(db);
        db.execSQL("PRAGMA foreign_keys=ON");
    }
}
7

visual Basicでも同じ問題が発生しました!!!次のようにコマンドテキストを記述する必要があります。

cone.CommandText = "PRAGMA foreign_keys = ON; DELETE FROM employees WHERE cod_emp = 0;"

何かを削除するたびにそれをしなければなりません

0
user3739283