![](/img/trans.png)
[英]How can I delete all rows within a table in a mysql database, which value = 0 for one of the columns?
[英]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_packet的值,但通常任何大整數都可以。 看到這個其他問題。
SELECT Trigger_Name
FROM `information_schema`.`TRIGGERS`
WHERE TRIGGER_SCHEMA = 'your_schema';
將結果復制到剪貼板
將Trigger_name
轉換為DROP TRIGGER <trigger_name>;
對於使用 ^ 和 S 標記的每個觸發器,使用 reg.expressions 開始和結束行
作為 sql 腳本運行
不確定是否存在用於此目的的單個命令。
但這是我前一段時間做的
要獲取觸發器列表,您可以在信息架構中使用SHOW trigger或Triggers 表
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.