web-dev-qa-db-fra.com

SQLite Delete Cascade ne fonctionne pas

Dans Android 4.2, à l'aide de SQLite 3.7.11, lorsque je supprime une ligne de la table Quizz, dont le schéma est situé en dessous, les lignes correspondantes de la table QuizQuestions ne sont pas supprimées.

Je ne peux pas comprendre ce qui ne va pas. J'ai essayé de mettre 

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

avant et après les instructions create table.

Créer des déclarations de 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);
30
Dan14021

Votre base de données doit supprimer les lignes de quizQuestions au cas où quelqu'un supprime de quizzes ou de questions. Il ignorera la contrainte de clé étrangère entière au cas où la prise en charge de la clé étrangère est désactivée et que vous ne disposez que de colonnes ordinaires pouvant contenir n'importe quelle valeur.

La valeur par défaut de SQLite est PRAGMA foreign_keys = OFF à chaque fois que vous ouvrez la base de données. Ce n'est pas une propriété d'une table ou du schéma.

Si vous utilisez SQLiteOpenHelper, mettez-le dans onOpen. C'est l'endroit qui est appelé chaque fois que la base de données est ouverte. onCreate une seule fois lors de la création de la base de données.


Ce que SQLiteOpenHelper appelle lorsque vous appelez getWriteableDatabase pour la première fois est

  1. onConfigure à chaque fois, niveau d'API> = 16 requis
  2. en fonction de l'existence et de la version du fichier de base de données, le texte suivant est appelé dans une transaction
    • onCreate s'il n'y a pas de fichier de base de données. En règle générale, cela ne se produit qu'une fois dans toute la durée de vie de l'application.
    • onUpgrade si la version de la base de données (PRAGMA user_version - enregistrée dans le fichier de base de données) est inférieure à la version fournie dans le constructeur de SQLiteOpenHelper. Cela se produit chaque fois que vous insérez la version dans votre code.
    • Rien si le fichier existe et que la version correspond.
  3. onOpen à chaque fois

Si la même instance de SQLiteOpenHelper a déjà une base de données ouverte, elle la renverra et rien ne se passera.

58
zapl

Essayez d'ajouter ce droit après avoir ouvert la base de données dans votre application Android:

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

Cela active la prise en charge des clés étrangères, qui est nécessaire pour que ON DELETE CASCADE fonctionne correctement. 

22
mvp

Sqlite désactiver la clé étrangère par défaut, vous devez donc l'activer par substituez simplement la méthode onOpen dans votre classe DBhelper comme ci-dessous

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

j'ai eu le même problème sur Visual Basic !!! vous devez écrire le texte de la commande comme ceci:

cone.CommandText = "PRAGMA foreign_keys = ON; SUPPRIMER DES EMPLOYÉS WHERE cod_emp = 0;"

et vous devez le faire chaque fois que vous supprimez quelque chose

0
user3739283