如何在 SQLite android 中多次执行触发器?
How to execute a trigger multiple times in SQLite android?
我正在开发一个 android 应用程序,该应用程序具有 SQLite 数据库的实现,我想创建一个运行多次直到达到特定计数的触发器。
需要什么
有 2 个表 TABLE 1 和 TABLE 2
- 在 TABLE 1 上插入后,应调用触发器 12 次并且
insert 12 rows in TABLE 2 based on specific WHERE CLAUSE
- 第13次
触发器不应插入任何新行。
我试过的
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 行
我正在开发一个 android 应用程序,该应用程序具有 SQLite 数据库的实现,我想创建一个运行多次直到达到特定计数的触发器。
需要什么
有 2 个表 TABLE 1 和 TABLE 2
- 在 TABLE 1 上插入后,应调用触发器 12 次并且 insert 12 rows in TABLE 2 based on specific WHERE CLAUSE
- 第13次 触发器不应插入任何新行。
我试过的
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)
- 要么使用带有多组值的单个 INSERT,例如
我猜你需要做类似的事情:-
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 行