【问题标题】:How do I dynamically DROP stored procedures and functions using prepared statements (MySQL) -- DROP PROCEDURE LIKE如何使用准备好的语句 (MySQL) 动态 DROP 存储过程和函数 - DROP PROCEDURE LIKE
【发布时间】:2016-07-04 08:01:16
【问题描述】:

我一直在尝试在 MySQL 中动态删除表、过程和函数。我这样做是因为我正在为项目动态创建它们,当项目版本发生变化时,我需要清理并重建它。

但是,我可以动态删除表格;我不能动态删除过程函数

这是我正在使用的代码示例:

DELIMITER ;;
DROP PROCEDURE IF EXISTS md_remove_project; ;;
CREATE PROCEDURE         md_remove_project()
begin
    DECLARE TableName text;
    DECLARE ProcName  text;
    DECLARE done      int DEFAULT false;
    DECLARE statement text;

    DECLARE table_cursor CURSOR FOR
        SELECT table_name FROM tmp_md_tables;

    DECLARE proc_cursor CURSOR FOR
        SELECT routine_name FROM tmp_md_procedures;

    DECLARE func_cursor CURSOR FOR
        SELECT routine_name FROM tmp_md_functions;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;       

    # Drop all the 'md' tables..............................................
    # This Works...
    DROP TABLE IF EXISTS   tmp_md_tables;
    CREATE TEMPORARY TABLE tmp_md_tables
    SELECT
        table_name
    FROM
        information_schema.tables
    WHERE
        table_name LIKE 'md_%';

    OPEN table_cursor;
    table_loop: LOOP
        FETCH table_cursor INTO TableName;
        IF done THEN
            LEAVE table_loop;
        END IF;

        SET @statement = CONCAT('DROP TABLE IF EXISTS ', TableName, ';');
        PREPARE STATEMENT FROM @statement;
        EXECUTE STATEMENT;
        DEALLOCATE PREPARE STATEMENT;        
    END LOOP;
    CLOSE table_cursor;
    DROP TABLE IF EXISTS tmp_md_tables;
    #-----------------------------------------------------------------------
    # Drop all the 'md' procedures............................................
    DROP TABLE IF EXISTS   tmp_md_procedures;
    CREATE TEMPORARY TABLE tmp_md_procedures
    SELECT
        routine_name
    FROM
        information_schema.routines
    WHERE
        routine_type = 'PROCEDURE'
        and
        routine_name LIKE 'md_%';

    SET done = false;
    OPEN proc_cursor;
    proc_loop: LOOP
        FETCH proc_cursor INTO ProcName;

        IF ProcName = 'md_remove_project' THEN
            ITERATE proc_loop;
        END IF;

        IF done THEN
            leave proc_loop;
        END IF;

        SET @statement = CONCAT('DROP PROCEDURE IF EXISTS ', ProcName, ';');
        PREPARE STATEMENT FROM @statement;
        EXECUTE STATEMENT;
        DEALLOCATE PREPARE STATEMENT;
    END LOOP;
    CLOSE proc_cursor;
    DROP TABLE IF EXISTS tmp_md_procedures;
END;
;;
DELIMITER ;

#CALL md_remove_project;

所以我用名为 md_% 的过程创建了一个表,然后循环遍历该表。对于每个routine_name,我准备一个语句来删除该过程。然后我收到以下消息:

错误代码:1295。准备好的语句协议尚不支持此命令

是否有其他解决方案可以删除诸如“md_%”之类的程序???

谢谢。

【问题讨论】:

    标签: mysql stored-procedures mysql-workbench sql-drop


    【解决方案1】:

    使用mysqli_... 函数时,无需尝试更改分隔符。只有在使用 MySQL(命令行)客户端时才需要更改分隔符命令。该命令实际上是一个 MySQL 客户端命令(客户端从不将其发送到服务器)。

    服务器足够聪明,可以识别CREATE PROCEDURE 命令并知道它以END; 结尾

    因此,您可以简单地执行两个查询:首先是 DROP PROCEDURE IF EXISTS ...,然后是 CREATE PROCEDURE ... END; 查询。

    如果您必须在一次调用中执行这些操作,您可以使用mysqli::multi_query,但我建议您不要这样做(因为可能存在严重的安全隐患)。

    【讨论】:

    • 我正在构建一个访问数据库的可视化项目。我正在从原始数据库动态创建一个新数据库。随着可视化项目(前端)的变化,新的表和过程被添加到新的数据库中,而一些表和过程不再需要(因此需要被删除)。我的主要问题是:SET @statement = CONCAT('DROP PROCEDURE IF EXISTS ', ProcName, ';'); PREPARE STATEMENT FROM @statement; EXECUTE STATEMENT; DEALLOCATE PREPARE STATEMENT; 的替代方法是什么
    猜你喜欢
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    相关资源
    最近更新 更多