【问题标题】:SQLite Delete Cascade not workingSQLite删除级联不起作用
【发布时间】:2012-11-18 10:33:03
【问题描述】:

在Android 4.2中,使用SQLite 3.7.11,当我从Quizzes表中删除一行时,谁的架构在下面,QuizQuestions表中的相应行不会被删除。

我不知道出了什么问题。我试过把

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

在创建表语句之前和之后。

创建表语句:

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);

【问题讨论】:

  • 有错误信息吗?除了你注意到它不起作用......
  • 不,LogCat 中没有显示任何内容。
  • 可能是因为您的主键是复合键....可能是这样的。:PRIMARY KEY (quiz_name, question_id) ON CONFLICT IGNORE, CONSTRAINT "PrimaryKey" FOREIGN KEY ( "quiz_name", "question_id") REFERENCES "quizQuestions" ("quiz_name", "question_id") ON DELETE CASCADE);
  • 检查这个post out会对你有很大帮助。

标签: android sqlite cascading-deletes


【解决方案1】:

您的数据库应该从quizQuestions 中删除行,以防有人从quizzesquestions 中删除。如果关闭了外键支持并且您只有可以包含任何值的常规列,它将忽略 整个 外键约束。

每次您打开数据库时,SQLite 默认为PRAGMA foreign_keys = OFF。它不是表或模式的属性。

如果您使用SQLiteOpenHelper,请将其放入onOpen。那是每次打开数据库时调用的地方。 onCreate 只在数据库创建时使用一次。


当您第一次调用getWriteableDatabaseSQLiteOpenHelper 调用的内容是

  1. onConfigure 每次都需要 API 级别 >= 16
  2. 根据数据库文件的存在和版本,在事务中调用以下内容
    • onCreate 如果没有数据库文件。通常,这只会在应用的整个生命周期中发生一次。
    • onUpgrade 如果数据库版本(PRAGMA user_version - 保存在数据库文件中)小于 SQLiteOpenHelper 构造函数中提供的版本。每次您在代码中修改版本时都会发生这种情况。
    • 如果文件存在且版本匹配,则无任何内容。
  3. onOpen 每次

如果SQLiteOpenHelper 的同一个实例已经有一个打开的数据库,它只会返回它,而上述任何事情都不会发生。

【讨论】:

    【解决方案2】:

    尝试在您的 Android 应用中打开数据库后立即添加:

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

    这将打开对外键的支持,这是ON DELETE CASCADE 正常工作所必需的。

    【讨论】:

    • 是的,我正在这样做,但它仍然没有删除。
      例如,db.rawQuery("INSERT INTO quizzes (quiz_name) VALUES('Test1')", null);
      db.rawQuery("INSERT INTO questions (question) VALUES('Question1')", null);
      db.rawQuery("INSERT INTO quizQuestions (quiz_name, question_id) VALUES('Test1', 1)", null);
      db.rawQuery("DELETE FROM quizzes WHERE quiz_name = 'Test1'", null);
      保留 quizQuestions 表中的 Test1 行。
    • 似乎从 API 16 开始(这就是你所拥有的)你应该在 onConfigure() developer.android.com/reference/android/database/sqlite/…
    • 并使用db.setForeignKeyConstraintsEnabled(true) - 但最大的区别是:onConfigure 发生在onCreate/onUpdate 之前,因此您已经在那里启用了约束。例如。删除表将触发级联删除,这可能不是您想要的。
    【解决方案3】:

    Sqlite 默认禁用外键约束,因此您需要通过简单地覆盖 DBhelper 类中的 onOpen 方法来启用它,如下所示

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

    【讨论】:

      【解决方案4】:

      我在visual basic上遇到了同样的问题!!!您必须像这样编写命令文本:

      cone.CommandText = "PRAGMA foreign_keys = ON; 从员工中删除 WHERE cod_emp=0;"

      而且每次删除时都必须这样做

      【讨论】:

        猜你喜欢
        • 2013-06-22
        • 2013-03-03
        • 2011-06-11
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多