簡體   English   中英

如何使用預准備語句(MySQL)動態DROP存儲過程和函數 - DROP PROCEDURE LIKE

[英]How do I dynamically DROP stored procedures and functions using prepared statements (MySQL) — DROP PROCEDURE LIKE

我一直在嘗試動態地刪除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_%的過程創建一個表,然后循環遍歷表。 對於每個例程名,我准備一條語句以刪除該過程。 然后我得到以下消息:

錯誤代碼:1295。尚未在准備好的語句協議中支持此命令

還有其他解決方案來刪除“ md_%”之類的過程嗎?

謝謝。

使用mysqli_...函數時,無需嘗試更改分隔符。 僅當使用MySQL(命令行)客戶端時,才需要change delimiter命令。 事實上,該命令是MySQL客戶端命令(客戶端從不將其發送到服務器)。

服務器足夠聰明,可以識別CREATE PROCEDURE命令,並且知道它以END;結尾END;

結果,您可以簡單地執行兩個查詢:首先是DROP PROCEDURE IF EXISTS ...然后是CREATE PROCEDURE ... END; 查詢。

如果必須在單個調用中執行它們,則可以使用mysqli::multi_query但我建議不mysqli::multi_query (因為這可能會嚴重影響安全性)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM