MySQL 8 - 删除特定数据库中的所有存储过程

MySQL 8 - Remove All Stored Procedures in a Specific Database

在 MySQL 8 中,数据库 table `mysql`.`proc` 不存在。以前我使用此 table 到 delete/remove/clear 所有存储过程并从源版本代码重新创建它们。这非常有效地确保开发存储过程在投入生产之前保存到源版本控制。

在 8 之前的 MySQL 版本中,此 SQL 查询有效。

DELETE FROM `mysql`.`proc` WHERE `type` = 'PROCEDURE' AND `db` = 'test';

是否有其他方法可以在一个语句中实现查询结果?


答案是你不能。但是你可以生成所有的drop语句并执行它们。

我现在使用以下 SQL 同时为存储过程、存储函数、事件和触发器创建所有 drop 语句。我使用函数“DATABASE()”以便于重用。您可以用数据库名称字符串“dbName”替换“DATABASE()”,它将在 phpMyAdmin 中工作。

SELECT CONCAT("DROP ",`item`.`ROUTINE_TYPE`," IF EXISTS `",DATABASE(),"`.`",`item`.`ROUTINE_NAME`,"`;") as `stmt`
FROM `information_schema`.`ROUTINES` AS `item` 
WHERE `item`.`ROUTINE_SCHEMA` = DATABASE()
    UNION
SELECT CONCAT("DROP EVENT IF EXISTS `",DATABASE(),"`.`",`item`.`EVENT_NAME`,"`;") AS `stmt`
FROM `information_schema`.`EVENTS` AS `item` 
WHERE `item`.`EVENT_SCHEMA` = DATABASE()
    UNION
SELECT CONCAT("DROP TRIGGER IF EXISTS `",DATABASE(),"`.`",`item`.`TRIGGER_NAME`,"`;") AS `stmt`
FROM `information_schema`.`TRIGGERS` AS `item` 
WHERE `item`.`TRIGGER_SCHEMA` = DATABASE();

尝试

   delete from mysql.proc WHERE db LIKE <yourDbName>;

在 MySQL 8.0 中,可通过 Routines table of the INFORMATION_SCHEMA 访问存储过程(例程)的详细信息。以下几点值得注意:

The ROUTINES table provides information about stored routines (stored procedures and stored functions). The ROUTINES table does not include built-in SQL functions or user-defined functions (UDFs).

现在,例程table中的以下两列需要在这里使用:

ROUTINE_SCHEMA - The name of the schema (database) to which the routine belongs.

ROUTINE_TYPE - PROCEDURE for stored procedures, FUNCTION for stored functions.

在使用 SHOW CREATE TABLE information_schema.routines 进一步调查后,发现它是 TEMPORARY TABLE

因此,为了删除 test 数据库的所有存储过程(而不是存储函数),我们可以使用以下查询:

DELETE FROM information_schema.routines 
WHERE routine_type = 'PROCEDURE' AND 
      routine_schema = 'test'

我建议使用 MySQL Shell - 以下示例使用 Python 模式:

mysqlsh> \py

mysql-py> i_s = session.get_schema("information_schema")

mysql-py> functions = i_s.ROUTINES \
       ->                .select("sys.quote_identifier(ROUTINE_SCHEMA) AS RoutineSchema", "sys.quote_identifier(ROUTINE_NAME) AS RoutineName") \
       ->                .where("ROUTINE_SCHEMA = 'db1' AND ROUTINE_TYPE = 'FUNCTION'").execute().fetch_all()

mysql-py> functions
[
    [
        "`db1`",
        "`func1`"
    ], 
    [
        "`db1`",
        "`func2`"
    ], 
    [
        "`db1`",
        "`func``3`"
    ]
]

mysql-py> for function in functions:
       ->     print(sql_fmt.format(*function))
       ->     session.sql(sql_fmt.format(*function)).execute()
       ->
DROP FUNCTION `db1`.`func1`
DROP FUNCTION `db1`.`func2`
DROP FUNCTION `db1`.`func``3`
Query OK, 0 rows affected (0.0684 sec)

有关更多讨论,另请参阅 https://mysql.wisborg.dk/2018/12/02/mysql-8-drop-several-stored-events-procedures-or-functions/

我认为你的问题的答案是,这不能在一个声明中完成。

使用以下语句生成 DROP 语句列表可能会有所帮助:

SET group_concat_max_len = 4294967295;

SELECT group_concat('DROP PROCEDURE IF EXISTS ', r.routine_name, ';\n' ORDER BY r.routine_name SEPARATOR '') AS DROP_STATEMENTS 
FROM information_schema.routines r 
WHERE r.routine_schema = database() AND r.routine_type = 'PROCEDURE';