Mysqlインデックスの追加(繰り返し実行可能なストアド・プロシージャ)


多くの会社では、再生産上のsqlスクリプトの繰り返し実行を許可するように要求されています(あるsqlがエラーを報告してから実行することを防止します).インデックスが存在するかどうかを判断し、インデックスを追加または削除する操作(インデックスが存在しない場合、インデックスを削除するとエラーが発生する)を行う必要がある場合、単独のsqlではこの要求を完了できない(インデックスを追加および削除する文はIF EXISTSをサポートしていない)ため、ストレージプロセスに参加する必要がある.このような簡単なストレージプロセスは多くの人が書くが、ここで私は穴を踏んだ.はい、テーブル名がパラメータにならないということです..初めて書いたストレージ・プロシージャが、不幸にもハングアップされました.
DROP PROCEDURE IF EXISTS add_index;  
DELIMITER //
CREATE PROCEDURE add_index(IN p_db_name VARCHAR (64),IN p_table_name VARCHAR (64),IN p_index_name VARCHAR (64),IN p_index VARCHAR (64)) BEGIN 
IF NOT EXISTS (SELECT * FROM information_schema.statistics WHERE table_schema = p_db_name AND table_name = p_table_name AND index_name = p_index_name) THEN  
   ALTER TABLE p_table_name ADD INDEX p_index_name ( p_index );
END IF;  
END//  
DELIMITER ;  

ここALTER TABLE p_table_name ADD INDEX p_index_name ( p_index ); ストレージ・プロシージャでテーブル名を直接パラメータとして使用できないため、この文は間違っています.MySQLで提供されているPREPARE構文を使用して、PREPAREの具体的な使用方法については、URLを参照してください.https://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.htmlストレージ・プロシージャを
DROP PROCEDURE IF EXISTS add_index;  
DELIMITER //
CREATE PROCEDURE add_index(IN p_db_name VARCHAR(64),IN p_table_name VARCHAR(64),IN p_index_name VARCHAR(64),IN p_index VARCHAR(64)) BEGIN 
DECLARE StrAdd VARCHAR(250);
DECLARE StrDrop VARCHAR(250);
set @StrAdd=concat('ALTER TABLE ',p_table_name,' ADD INDEX ',p_index_name,'(',p_index,')');
set @StrDrop=concat(' drop index ',p_index_name,' on ',p_table_name);   
IF NOT EXISTS (SELECT 1 FROM information_schema.statistics WHERE table_schema = p_db_name AND table_name = p_table_name AND index_name = p_index_name) THEN  
    PREPARE stmt FROM @StrAdd;  
    EXECUTE stmt ;  
ELSE
    PREPARE stmt FROM @StrDrop;  
    EXECUTE stmt ; 
    PREPARE stmt FROM @StrAdd;  
    EXECUTE stmt ; 
END IF;   
END//  
DELIMITER ;  

パラメータ(p_db_nameライブラリ名、p_table_nameテーブル名、p_index_nameインデックス名、p_indexインデックスフィールド)set@StrDrop=concat('drop index',p_index_name,'on',p_table_name);この文はsql文をつなぎ、PREPARE stmt FROM@StrDrop;このsqlを実行し、最後にDEALLOCATEによってPrepared Statementsを解放するプロセスは、インデックスの有無を先に判断し、ある場合は削除してから追加し、ない場合は直接追加することができます.