10

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

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

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

4

7 回答 7

8

我编写了一个非常简单的扩展函数来将布尔值设置为真或假。

以及检索此值的函数 (GetAllTriggersOn())。

使用此功能,我可以定义所有触发器,例如:

CREATE TRIGGER tr_table1_update AFTER UPDATE ON TABLE1 WHEN GetAllTriggersOn()
BEGIN
    -- ...
END
于 2010-06-23T13:18:23.623 回答
8

所以现在是 2015 年,SQLite 中仍然没有“禁用触发器”。对于移动应用程序,这可能会出现问题——特别是如果它是一个需要离线功能和本地数据的公司应用程序。

即使您没有将每个插入包装在单独的事务中,也可以通过触发器执行来减慢初始数据加载的速度。

我使用 SQLite SQL 相当简单地解决了这个问题。我有一个不参与初始化加载的设置表。它包含键/值对的“列表”。我有一个名为“fireTrigger”的键,其位值为 0 或 1。我拥有的每个触发器都有一个选择值的表达式,如果它等于 1,它会触发触发器,否则不会。

该表达式是对与触发器相关的数据进行评估的任何表达式的补充。例如:

AND 1 = (SELECT val FROM MTSSettings WHERE key = 'fireTrigger')

在简单的干净效果中,这使我可以通过简单UPDATE的设置表来禁用/启用触发器

于 2015-07-22T14:03:21.553 回答
7

SQLite 将模式(元)信息存储在内置sqlite_master表中。

要获取可用触发器的列表,请使用以下查询:

SELECT name FROM sqlite_master
WHERE type = 'trigger' -- AND tbl_name = 'a_table_name'
于 2010-02-12T11:06:29.137 回答
2

在您的数据库中设置一个标志并在触发器 WHEN 条件中使用它。

假设您想在插入后在“客户”表上创建触发器。您已经创建了一个带有 TINYINT“triggers_on”字段的表“trigger_settings” - 这是您的标志。然后,如果要关闭过滤器,可以将该字段设置为 0,如果要重新打开过滤器,则可以将该字段设置为 1。

然后,您使用检查“triggers_on”字段的 WHEN 条件创建过滤器。

例如:

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;
于 2020-11-27T09:59:03.113 回答
1

也许您可以制作一个存储过程来删除和创建它们。这对你有好处吗?

于 2010-02-12T10:07:23.273 回答
1

扩展其他答案这就是我的做法。考虑到这将禁用数据库中所有表的所有触发器,除了一些然后由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}"


于 2019-12-08T17:16:35.173 回答
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;
于 2017-06-16T15:22:07.110 回答