如何处理SQLite的缺失功能:禁用触发器?

时间:2010-02-12 10:03:10

标签: sqlite triggers missing-features

如何处理SQLite缺少的功能:disable triggers

我没有存储特定表的触发器名称。

例如,如何删除所有触发器?
你会做什么?

7 个答案:

答案 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;