如何处理SQLite缺少的功能:disable triggers
?
我没有存储特定表的触发器名称。
例如,如何删除所有触发器?
你会做什么?
答案 0 :(得分:7)
SQLite在内置sqlite_master
表中存储架构(元)信息。
要获取可用触发器列表,请使用以下查询:
SELECT name FROM sqlite_master
WHERE type = 'trigger' -- AND tbl_name = 'a_table_name'
答案 1 :(得分:7)
我编写了一个非常简单的扩展函数来将布尔值设置为true或false。
一个检索此值的函数(GetAllTriggersOn())。
使用此功能,我可以定义所有触发器,如:
CREATE TRIGGER tr_table1_update AFTER UPDATE ON TABLE1 WHEN GetAllTriggersOn()
BEGIN
-- ...
END
答案 2 :(得分:6)
所以这是2015年,仍然没有“禁用触发器”#39;在SQLite中。对于移动应用程序而言,这可能会有问题 - 特别是如果它是需要离线功能和本地数据的企业应用程序。
即使您没有在单个事务中包装每个插入内容,也可以通过触发器执行来减慢初始数据加载速度。
我很简单地使用SQLite SQL解决了这个问题。我有一个不参与init加载的设置表。它拥有' list'键/值对。我有一个名为“fireTrigger'位值为0或1.每个触发器都有一个选择值的表达式,如果它等于1则触发触发器,否则它不会触发。
此表达式是对与触发器相关的数据计算的任何表达式的补充。 e.g:
AND 1 = (SELECT val FROM MTSSettings WHERE key = 'fireTrigger')
在简单的清洁效果中,这允许我使用简单的UPDATE
禁用/启用触发器到设置表
答案 3 :(得分:1)
也许您可以制作用于删除和创建它们的存储过程。这对你有好处吗?
答案 4 :(得分:0)
扩展Nick Dandoulakis的回答,您可以删除所有相关触发器,然后在交易完成之前恢复它们:
BEGIN;
SELECT name, sql FROM sqlite_master WHERE type = 'trigger' AND tbl_name = 'mytable';
-- store all results
-- for each name: DROP TRIGGER $name;
-- do normal work
-- for each sql: execute the SQL verbatim
COMMIT;
答案 5 :(得分:0)
扩展其他答案,这就是我的做法。请注意,这将禁用数据库中所有表的所有触发器,但spatialite
SQLITE_FILE=/tmp/my.sqlite
# Define output sql files as variables
CREATE_TRIGGER_SQL=/tmp/create_triggers.sql
DROP_TRIGGER_SQL=/tmp/drop_triggers.sql
## Dump CREATE TRIGGER statements to a file ##
# To wrap statements in a transaction
echo -e "BEGIN;\n\n" > "${CREATE_TRIGGER_SQL}"
# `SELECT sql` does not output semicolons, so we must concatenate them
sqlite3 -bail "${SQLITE_FILE}" "SELECT sql || ';' FROM sqlite_master WHERE type = 'trigger' AND (name NOT LIKE 'gid_%' AND name NOT LIKE 'ggi_%' AND name NOT LIKE 'ggu_%' AND name NOT LIKE 'gii_%' AND name NOT LIKE 'giu_%' AND name NOT LIKE 'vwgcau_%' AND name NOT LIKE 'vtgcau_%' AND name NOT LIKE 'gcau_%' AND name NOT LIKE 'geometry_columns_%' AND name NOT LIKE 'gcfi_%' AND name NOT LIKE 'gctm_%' AND name NOT LIKE 'vtgcfi_%' AND name NOT LIKE 'vwgcfi_%' AND name NOT LIKE 'vtgcs_%' AND name NOT LIKE 'vwgc_%' AND name NOT LIKE 'vtgc_%' AND name NOT LIKE 'gcs_%');" >> "${CREATE_TRIGGER_SQL}"
echo -e "\n\nCOMMIT;" >> "${CREATE_TRIGGER_SQL}"
## Dump DROP TRIGGER statements to a file ##
echo -e "BEGIN;\n\n" > "${DROP_TRIGGER_SQL}"
sqlite3 -bail "${SQLITE_FILE}" "SELECT 'DROP TRIGGER ' || name || ';' FROM sqlite_master WHERE type = 'trigger' AND (name NOT LIKE 'gid_%' AND name NOT LIKE 'ggi_%' AND name NOT LIKE 'ggu_%' AND name NOT LIKE 'gii_%' AND name NOT LIKE 'giu_%' AND name NOT LIKE 'vwgcau_%' AND name NOT LIKE 'vtgcau_%' AND name NOT LIKE 'gcau_%' AND name NOT LIKE 'geometry_columns_%' AND name NOT LIKE 'gcfi_%' AND name NOT LIKE 'gctm_%' AND name NOT LIKE 'vtgcfi_%' AND name NOT LIKE 'vwgcfi_%' AND name NOT LIKE 'vtgcs_%' AND name NOT LIKE 'vwgc_%' AND name NOT LIKE 'vtgc_%' AND name NOT LIKE 'gcs_%');" >> "${DROP_TRIGGER_SQL}"
echo -e "\n\nCOMMIT;" >> "${DROP_TRIGGER_SQL}"
## Execute like ##
sqlite3 -bail /"${SQLITE_FILE}" < "${DROP_TRIGGER_SQL}"
# do things
sqlite3 -bail /"${SQLITE_FILE}" < "${CREATE_TRIGGER_SQL}"
答案 6 :(得分:0)
在数据库中设置一个标志,并在触发条件时使用它。
假设您要在插入后在“客户”表上创建触发器。您已经创建了带有TINYINT“ triggers_on”字段的表“ trigger_settings”-这是您的标志。然后,如果您要关闭过滤器,则可以将字段设置为0,而要重新打开过滤器,则可以将字段设置为1。
然后,您使用WHEN条件创建过滤器,该条件检查“ triggers_on”字段。
例如:
CREATE TRIGGER IF NOT EXISTS log_client_data_after_insert
AFTER INSERT
ON [clients]
WHEN (SELECT triggers_on FROM trigger_settings)=1
BEGIN
your_statement
END;