簡體   English   中英

如何使用一條 SQL 語句刪除 MySQL 數據庫中的所有觸發器?

[英]How can I delete all the triggers in a MySQL database using one SQL statement?

我有一個已克隆的數據庫,現在所有日志記錄觸發器都指向原始模式中的日志表。 我需要一次性刪除所有這些(有幾十個),以便我可以重新創建它們。 這怎么能用一個命令來完成?

SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM  information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema';

復制粘貼生成的sql

這是一個老問題,但由於它是我搜索中不斷出現的問題,我想我會在這里發布解決方案。 就我而言,我需要創建一個包含完整mysqldump的單個文件,然后刪除所有觸發器,然后將它們全部重新添加。 在附加DROP TRIGGER轉儲之前,我能夠通過使用以下命令將DROP TRIGGER語句附加到我的轉儲中來做到這一點。

mysql -u [db user] -p[db password] --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -r 's/(.*)/DROP TRIGGER IF EXISTS \1;/' >> dump.sql

要實際刪除同一命令中的所有觸發器(如@Stephen Crosby 在評論中所述),您可以像這樣將其管道回 MySQL:

mysql -u [db user] -p[db password] --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -r 's/(.*)/DROP TRIGGER IF EXISTS \1;/' | mysql -u [db user] -p[db password] [db name]

不幸的是,這在常規 SQL 語句或存儲過程中是不可能的。

解決方案

刪除所有觸發器的最簡單解決方案可能是 bash 腳本:

echo "select concat('drop trigger ', trigger_name, ';')
  from information_schema.triggers where trigger_schema = 'your_database'" |
  mysql --defaults-extra-file=.mysql.conf --disable-column-names | 
  mysql --defaults-extra-file=.mysql.conf

這需要一個憑據文件( .mysql.conf ),如下所示:

[client]
database=your_database
user=your_username
password=your_password

推理

嘗試從存儲過程中刪除觸發器將失敗。 我猜這是因為變量只能保存一個字符串,而drop trigger需要一個觸發器名稱(不是包含觸發器名稱的字符串):

create procedure drop_a_trigger()
begin
  declare var1 varchar(1024);
  set var1 = "my_second_trigger";

  drop trigger my_first_trigger;       // OK
  drop trigger address_update_before;  // ERROR 1360 (HY000): Trigger does not exist

end //
delimiter ;

call drop_a_trigger();

MySQL 論壇上有兩個關於此的主題:

他們都得出相同的結論,即即使使用存儲過程也無濟於事。

使用一條 SQL 語句刪除 MySQL 數據庫中的所有觸發器是不可能的。

但是使用以下 SQL 代碼,您可以構建所有“DROP TRIGGER”語句的列表(<your_schema>替換為您的架構名稱,例如您的數據庫名稱):

-- set `group_concat_max_len`
SET @@session.group_concat_max_len = @@global.max_allowed_packet;

-- select all the triggers and build the `DROP TRIGGER` SQL
-- replace <your_schema> with your schema name (e.g. your database name)
SELECT GROUP_CONCAT(sql_string SEPARATOR '\n')
FROM (
    SELECT CONCAT('DROP TRIGGER IF EXISTS `', TRIGGER_NAME, '`;') AS sql_string,'1'
    FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = '<your_schema>'
    ) AS sql_strings
GROUP BY '1';

上一個查詢的結果將產生如下結果:

DROP TRIGGER IF EXISTS `trigger1`;
DROP TRIGGER IF EXISTS `trigger2`;
(...)

並且您可以使用這些 SQL 語句最終刪除所有觸發器。

服務器系統變量group_concat_max_len是 GROUP_CONCAT() 函數允許的最大結果長度(以字節為單位)。 因為默認是1024,如果我們有很多觸發器,我們需要增加它以避免截斷結果。 我只是使用了服務器系統變量max_allowed_pa​​cket的值,但通常任何大整數都可以。 看到這個其他問題

SELECT Trigger_Name
FROM `information_schema`.`TRIGGERS`
WHERE TRIGGER_SCHEMA = 'your_schema';

將結果復制到剪貼板

Trigger_name轉換為DROP TRIGGER <trigger_name>; 對於使用 ^ 和 S 標記的每個觸發器,使用 reg.expressions 開始和結束行

作為 sql 腳本運行

不確定是否存在用於此目的的單個命令。

但這是我前一段時間做的

  1. 編寫腳本以獲取數據庫中的觸發器列表。
  2. 在 dropTrigger.sql 文件中創建連接列表
  3. 運行 dropTrigger.SQL 文件

要獲取觸發器列表,您可以在信息架構中使用SHOW triggerTriggers 表

MAC 使用 MAMP:

需要對我們接受的答案進行一些小的調整。 首先,我們需要在 MAMP 中以 mysql 為目標。 其次, sed -r不適用於 Mac,請改用sed -E 假設標准 MAMP 設置,沒有更改 root 用戶默認值,只需將 [db name] 替換為您的 db,然后復制並粘貼到終端並按 Enter。

/Applications/MAMP/Library/bin/mysql -u root -proot --skip-column-names [db name] -e 'SHOW TRIGGERS;' | cut -f1 | sed -E 's/(.*)/DROP TRIGGER IF EXISTS \1;/' | /Applications/MAMP/Library/bin/mysql -u root -proot [db name]

(如果您已更新您的 root 密碼,只需將-p后的“root”替換為您的密碼

如果您想使用查詢刪除它們而無需將數據庫 sqldump 到文件中:

select concat('drop trigger ', trigger_name, ';') from information_schema.triggers where trigger_schema = 'your_schema'; 然后您需要導出結果(我發現 CSV 是最簡單的)並在這些結果中運行查詢。

快速回答是“不”。

但是您可以將邏輯封裝在一個存儲過程中:使用動態 SQL 在循環中獲取所有觸發器並刪除所有觸發器。

之后你可以執行: call delete_all_triggers_api(schema_name);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM