如何在 SQLite android 中多次执行触发器?

How to execute a trigger multiple times in SQLite android?

我正在开发一个 android 应用程序,该应用程序具有 SQLite 数据库的实现,我想创建一个运行多次直到达到特定计数的触发器。

需要什么

有 2 个表 TABLE 1 和 TABLE 2

我试过的

onOpen function in DatabaseHelper class

 @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        if (!db.isReadOnly()) {
            // Enable foreign key constraints
            db.execSQL("PRAGMA foreign_keys=ON;");
            db.execSQL("PRAGMA recursive_triggers = ON;\n");
        }
    }

onCreate function in DatabaseHelper class

  public void onCreate(SQLiteDatabase db) {
        createTables(db);
         db.execSQL("CREATE TRIGGER multi_insertion AFTER INSERT ON TABLE1 \n" +
                    " WHEN (SELECT COUNT (*) from TABLE2 where MYNUMBER=1) < 12\n" +
                    "  BEGIN\n " +
                    "          insert into SCHEDULE (COLUMN1,COLUMN2) values ('001','002');  \n   " +
                    "  END;");
    }

输出:它只插入了 1 行 TABLE 2

有人可以帮我实现这个目标吗?任何帮助将不胜感激

一种可能的解决方案是使用触发器,但您必须小心,我不确定使用递归触发器解决此类问题是否是一种好的做法。

您的代码无法运行,因为您在 TABLE1 上调用了一次触发器,它在 TABLE2 中执行了一个 INSERT,仅此而已。

但是,请检查下面的代码片段。我在 TABLE2 上添加了另一个触发器,它插入同一行 11 次。

@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("PRAGMA recursive_triggers = ON;\n");

        db.execSQL("CREATE TABLE TABLE1 (NAME VARCHAR(20))");

        db.execSQL("CREATE TABLE TABLE2 (COL1 NUMBER, COL2 NUMBER)");

        db.execSQL("CREATE TRIGGER multi_insertion_table1 BEFORE INSERT ON TABLE1 \n" +
                " WHEN (SELECT COUNT (*) from TABLE2 where COL1=1 and COL2=2) < 12\n" +
                "  BEGIN \n" +
                "          insert into TABLE2 values (1, 2);  \n   " +
                "  END;");

        db.execSQL("CREATE TRIGGER multi_insertion_table2 AFTER INSERT ON TABLE2 \n" +
                " WHEN (SELECT COUNT (*) from TABLE2 where COL1=1 and COL2=2) < 12\n" +
                "  BEGIN \n" +
                "          insert into TABLE2 values (1, 2);  \n  " +
                "  END;");
    }

在这种情况下,第二个触发器必须是 AFTER STATEMENT,否则数据库将抛出异常并显示消息 too many levels of trigger recursion。检查这个 answer.

我相信你的问题不是你的触发器在理论上是错误的而是你有 3 tables:-

  • TABLE1,
  • TABLE2 和
  • BN_MS_LS_SCHEDULE

并且您从 TABLE2 获取行数,但插入到 BN_MS_LS_SCHEDULE.

  • 这个答案是基于 12 次插入 table 1 触发 12 次,而不是解释 After insert on TABLE 1 a trigger should be called 12 次并插入 12 行 意味着当插入 table1 中的第一行时应该插入 12 行,如果这是要求那么你可以:-

    • 要么使用带有多组值的单个 INSERT,例如INSERT INTO BN_MS_LS_SCHEDULE (column1,column2) VALUES('001','002'),('003','004') ......
    • 或在 BEGIN .... END 构造中使用 12 INSERT statements/actions(给定的示例显示了这样的多个 (2) statements/actions)

我猜你需要做类似的事情:-

public void onCreate(SQLiteDatabase db) {
    createTables(db);
     db.execSQL("CREATE TRIGGER multi_insertion AFTER INSERT ON TABLE1 " +
                " WHEN (SELECT COUNT (*) from TABLE2 where MYNUMBER=1) < 12" +
                " BEGIN " +
                " INSERT into BN_MS_LS_SCHEDULE (COLUMN1,COLUMN2) VALUES ('001','002');" +
                " INSERT into TABLE2 VALUES(?????????); " + //<<<<<<<<< insert a row into table 2 to act as a counter 
                "  END;");
}
  • 显然 ?????????? 应替换为一个或多个适当的值。

  • 这将在 table 2 中添加一行并且 WHEN 子句将适当地执行。

    • 如您所见,在 TRIGGER 的 BEGIN .... END 结构中可以有多个 ACTIONS。

例子

根据可以从您的代码中收集到的内容考虑这个工作示例,但 table2 添加了一个额外的列,用于将 table1 中的值记录到table1,从而展示了如何在 TRIGGER.

中使用 new.column
DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;
DROP TABLE IF EXISTS BN_MS_LS_SCHEDULE;
DROP TRIGGER IF EXISTS multi_insertion;

CREATE TABLE IF NOT EXISTS table1 (mydata);
CREATE TABLE IF NOT EXISTS table2 (mynumber,valuefromtable1);
CREATE TABLE IF NOT EXISTS BN_MS_LS_SCHEDULE (COLUMN1,COLUMN2,OTHERCOLUMNS);


CREATE TRIGGER IF NOT EXISTS multi_insertion
    AFTER INSERT ON table1
    WHEN (SELECT COUNT (*) from TABLE2 where MYNUMBER=1) < 12
    BEGIN
        INSERT INTO table2 VALUES(1,new.mydata /* record value that caused insert */); /*<<<<<<<<<< ADDED TO TRIGGER >>>>>>>>>>*/
        INSERT into BN_MS_LS_SCHEDULE (COLUMN1,COLUMN2) VALUES ('001','002');
    END;


/* Add some testing data which will exceed the 12 rows */
INSERT INTO table1 VALUES('a');
INSERT INTO table1 VALUES('b');
INSERT INTO table1 VALUES('c');
INSERT INTO table1 VALUES('d');
INSERT INTO table1 VALUES('e');
INSERT INTO table1 VALUES('f');
INSERT INTO table1 VALUES('g');
INSERT INTO table1 VALUES('h');
INSERT INTO table1 VALUES('i');
INSERT INTO table1 VALUES('j');
INSERT INTO table1 VALUES('k');
INSERT INTO table1 VALUES('l');
INSERT INTO table1 VALUES('m');
INSERT INTO table1 VALUES('n');
INSERT INTO table1 VALUES('o');
INSERT INTO table1 VALUES('p');
INSERT INTO table1 VALUES('q');
INSERT INTO table1 VALUES('r');

/* Results */
SELECT * FROM table1;
SELECT * FROM table2;
SELECT * FROM BN_MS_LS_SCHEDULE;

/* Cleanup Text Environment */
DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;
DROP TABLE IF EXISTS BN_MS_LS_SCHEDULE;
DROP TRIGGER IF EXISTS multi_insertion; 

结果

运行 以上结果为:-

Table1 即插入了所有 18 行。

表2

  • 突出显示的列显示从 table 1
  • 检索到的数据
  • 可以看出只添加了12行

BN_MS_LS_SCHEDULE

  • 同样只添加了 12 行