简体   繁体   中英

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

I've been trying to dynamically drop tables, procedures, and functions in MySQL. I'm doing this because I am dynamically creating them for a project, when the project version changes I need to clean up and rebuild it.

I can dynamically drop tables , however; I cannot dynamically drop procedures and functions .

Here is an example of the code I am using:

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;

So I create a table with the procedures named md_%, then I loop through the table. For each routine_name, I prepare a statement to drop the procedure. Then I get the following message:

Error Code: 1295. This command is not supported in the prepared statement protocol yet

Are there any other solutions to drop procedures like 'md_%' ???

Thank You.

When using mysqli_... functions, there is no need to attempt to change the delimiter. The change delimiter command is only needed when using the MySQL (command line) Client. The command is, in fact, a MySQL client command (the client never sends it to the server).

The server is smart enough to recognize the CREATE PROCEDURE command and knowns it ends with END;

As a result, you can simply do two queries: first the DROP PROCEDURE IF EXISTS ... followed by the CREATE PROCEDURE ... END; query.

If you must do them in a single call, you could use mysqli::multi_query but I would recommend against it (because of possible serious security implications).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM