如何使用一个SQL语句删除MySQL数据库中的所有触发器?

Mat*_*son 31 mysql triggers

我有一个已克隆的数据库,现在所有日志记录触发器都指向原始模式中的日志表.我需要一次性删除所有这些(有几十个),以便我可以重新创建它们.如何用一个命令完成?

Iri*_*lho 37

SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM  information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema';
Run Code Online (Sandbox Code Playgroud)

复制并粘贴生成的sql

  • 这是迄今为止最好的答案 (3认同)
  • 你在哪里交过朋友?(y) (2认同)

Jus*_*tin 32

这是一个老问题,但由于它是我的搜索中不断涌现的问题,我想我会在这里发布一个解决方案.在我的情况下,我需要创建一个完整的单个文件,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
Run Code Online (Sandbox Code Playgroud)

要在同一命令中实际删除所有触发器(如注释中的@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]
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢它.但你也可以把它直接传回mysql而不是文件:而不是">> dump.sql"你可以只使用"| mysql -u [db user] -p [db password]" (2认同)

Ian*_*non 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
Run Code Online (Sandbox Code Playgroud)

这需要一个凭证文件(.mysql.conf),如下所示:

[client]
database=your_database
user=your_username
password=your_password
Run Code Online (Sandbox Code Playgroud)

推理

尝试从存储过程中删除触发器将失败.我猜这是因为变量只能包含一个字符串并且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();
Run Code Online (Sandbox Code Playgroud)

在MySQL论坛上有两个关于此的线程:

他们都得出了相同的结论,即使使用存储过程也无济于事.


cga*_*olo 5

使用一个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';
Run Code Online (Sandbox Code Playgroud)

上一个查询的结果将产生如下内容:

DROP TRIGGER IF EXISTS `trigger1`;
DROP TRIGGER IF EXISTS `trigger2`;
(...)
Run Code Online (Sandbox Code Playgroud)

您可以使用这些SQL语句最终删除所有触发器.

服务器系统变量group_concat_max_len是GROUP_CONCAT()函数的最大允许结果长度(以字节为单位).因为默认值是1024,所以如果我们有很多触发器,我们需要增加它以避免截断结果.我刚刚使用了服务器系统变量max_allowed_pa​​cket的值,但通常可以使用任何大整数.看到这个其他问题.