我有一个已克隆的数据库,现在所有日志记录触发器都指向原始模式中的日志表。我需要一次性删除所有这些(有几十个),以便我可以重新创建它们。如何用一个命令完成?
答案 0 :(得分:32)
SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema';
复制并粘贴生成的sql
答案 1 :(得分:27)
这是一个老问题,但由于它是我的搜索中不断涌现的问题,我想我会在这里发布一个解决方案。在我的情况下,我需要创建一个具有完整mysqldump
的单个文件,然后删除任何触发器,然后重新添加它们。我能够通过使用以下命令将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]
答案 2 :(得分:7)
不幸的是,这在常规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论坛上有两个主题:
他们都得出了相同的结论,即使使用存储过程也无济于事。
答案 3 :(得分:5)
使用一个SQL语句无法删除MySQL数据库中的所有触发器。
但是使用以下SQL代码,您可以构建所有&#39; DROP TRIGGER&#39;声明(将&lt; your_schema&gt; 替换为您的架构名称,例如您的数据库名称):
-- 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的值,但通常可以使用任何大整数。请参阅this other question。
答案 4 :(得分:3)
SELECT Trigger_Name
FROM `information_schema`.`TRIGGERS`
WHERE TRIGGER_SCHEMA = 'your_schema';
将结果复制到剪贴板
使用^和S标记为每个触发器转换Trigger_name
到DROP TRIGGER <trigger_name>;
,使用reg.expressions开始和结束
以sql脚本运行
答案 5 :(得分:0)
不确定是否存在用于此目的的单个命令。
但这是我在一段时间后做的事情
要获取触发器列表,您可以使用SHOW trigger或Triggers table in Information schema
答案 6 :(得分:0)
MAC使用MAMP:
需要对我们接受的答案进行一些小的调整。首先,我们需要在MAMP中定位mysql。其次,sed -r
不适用于Mac,请改用sed -E
。假设标准MAMP设置,没有更改root用户默认值,只需将[db name]替换为db,然后复制并粘贴到Terminal并按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
之后用密码换出&#34; root&#34;
答案 7 :(得分:0)
如果您想使用查询删除它们而无需将数据库sqldump到文件中:
select concat('drop trigger ', trigger_name, ';')
from information_schema.triggers where trigger_schema = 'your_schema';
然后,您需要导出结果(我发现CSV最简单)并在这些结果中运行查询。
答案 8 :(得分:-4)
快速回答是“不”。
但您可以将逻辑封装在一个存储过程中:使用动态SQL获取所有触发器并在循环中删除所有触发器。
之后你可以执行:call delete_all_triggers_api(schema_name);