SQLiteの不足している機能を処理する方法:disable triggers
?
特定のテーブルのトリガーの名前を保存していません。
たとえば、すべてのトリガーを削除するにはどうすればよいですか?
あなたならどうしますか?
SQLiteの不足している機能を処理する方法:disable triggers
?
特定のテーブルのトリガーの名前を保存していません。
たとえば、すべてのトリガーを削除するにはどうすればよいですか?
あなたならどうしますか?
ブール値をtrueまたはfalseに設定するための非常に単純な拡張関数を作成しました。
そして、この値を取得する関数(GetAllTriggersOn())。
この関数を使用すると、次のようにすべてのトリガーを定義できます。
CREATE TRIGGER tr_table1_update AFTER UPDATE ON TABLE1 WHEN GetAllTriggersOn()
BEGIN
-- ...
END
したがって、ここでは2015年であり、SQLiteには「トリガーの無効化」はまだありません。モバイルアプリケーションの場合、これは問題になる可能性があります。特に、オフライン機能とローカルデータを必要とする企業アプリの場合はそうです。
個々のトランザクションで各挿入をラップしない場合でも、トリガーの実行によって初期データのロードが遅くなる可能性があります。
私はSQLiteSQLを使用してこの問題をかなり簡単に解決しました。initロードに参加しない設定テーブルがあります。キー/値ペアの「リスト」を保持します。ビット値が0または1の「fireTrigger」というキーが1つあります。すべてのトリガーには、値を選択する式があり、1に等しい場合はトリガーを起動し、そうでない場合は起動しません。
この式は、トリガーに関連するデータで評価される式に追加されます。例えば:
AND 1 = (SELECT val FROM MTSSettings WHERE key = 'fireTrigger')
シンプルなクリーン効果では、これによりUPDATE
、設定テーブルに簡単にトリガーを無効/有効にすることができます
SQLiteは、スキーマ(メタ)情報を組み込みsqlite_master
テーブルに格納します。
使用可能なトリガーのリストを取得するには、以下のクエリを使用します。
SELECT name FROM sqlite_master
WHERE type = 'trigger' -- AND tbl_name = 'a_table_name'
データベースにフラグを設定し、それをトリガーWHEN条件で使用します。
挿入後に「clients」テーブルにトリガーを作成するとします。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;
たぶん、それらをドロップして作成するためのストアドプロシージャを作成できます。それはあなたにとって良いことですか?
他の答えを拡張することは、これが私がそれをしている方法です。これにより、データベース内のすべてのテーブルのすべてのトリガーが無効になることを考慮してください。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}"
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;