【草稿】通過Navicat創建MySQL存儲過程清理指定數據庫表中數據的過程記錄

由於還在開發階段,每次測試完之後需要清理數據庫表,然後待清理的表數量較多,且有些基礎數據表需要保留,有些表(如用戶表)僅保留部分記錄,由於有個發郵件的定時器,還得保證清理數據的順序。所以嘗試使用存儲過程來實現一鍵清理數據的功能,僅以此過程分享給大家

思路:

  1. 首先是創建名爲clearMaterialDatabase的函數,暫時保留一個入參isKeepMaterial來控制是否保留材料信息。
  2. 通過MySQL中自帶的信息數據庫INFORMATION_SCHEMA可以獲取指定數據庫的基本信息,包括表名、權限和數據類型等。在通過CONCAT()函數拼接指定數據庫中各個表表名稱,比如CONCAT('DELETE FROM',' wz_input'),結果就成了一個刪除語句DELETE FROM wz_input,將這些語句組成一個結果集
  3. 通過遍歷這個結果集,執行指定的SQL語句,來達到批量刪除的目的。對於需要特殊處理的表,在用流程控制語句IF ELSEIF來處理,利用預處理API(EXECUTE stmt)執行相應的SQL語句

存儲過程源碼:

CREATE DEFINER=`root`@`localhost` PROCEDURE `clearMaterialDatabase`(IN `isKeepMaterial` VARCHAR(255))
BEGIN
  #Routine body goes here...
  #定義控制流程
  DECLARE i INT;
  
  #定義拼接的sql語句
  DECLARE strClear VARCHAR(256);
  DECLARE done INT DEFAULT 0;

  #定義遊標
  DECLARE curOne CURSOR FOR SELECT CONCAT('TRUNCATE TABLE ',TABLE_NAME,';') as ClearTable 
  FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'material_wz1702';
  
  #綁定控制變量到遊標,遊標循環結束自動轉爲True
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  
  #打開遊標
  OPEN curOne;
  
  #進入循環
  FETCH curOne INTO strClear;
   repeat_label: REPEAT
        FETCH curOne INTO strClear;
        #SELECT strClear;
          
         #開始控制流程IF-ELSEIF
        #是否保留材料信息
        IF (isKeepMaterial AND ((strClear LIKE '%tc_material;')OR(strClear LIKE '%tc_material_detail;')OR(strClear LIKE '%tc_material_subject;'))) THEN
          ITERATE repeat_label;
          
        #默認保留管理員賬號
        ELSEIF(strClear LIKE '%sys_user;') THEN
          SET @mysql = "DELETE from sys_user WHERE login_name not like 'admin'";
          PREPARE stmt from @mysql;
          EXECUTE stmt;
          DEALLOCATE PREPARE stmt;
          ITERATE  repeat_label;
          
        #默認保留數據字典/默認保留菜單字典/默認保留主頁配置/默認保留角色信息/默認保留合同模板/最後清理郵件記錄,防止清理過程中重複發送
        ELSEIF((strClear LIKE '%sys_dict;') OR (strClear LIKE '%sys_menu;') OR (strClear LIKE '%sys_config;')OR(strClear LIKE '%sys_role;')OR(strClear LIKE '%wz_contract_template')OR(strClear LIKE '%wz_bid_mail;')) THEN
          ITERATE repeat_label;
          
        #默認保留到項目層級
        ELSEIF(strClear LIKE '%sys_office;') THEN
          SET @mysql = "DELETE FROM sys_office WHERE id > ( SELECT id FROM ( SELECT id FROM sys_office  WHERE NAME = '項目級' AND del_flag = 0 ) targetId )";
          PREPARE stmt from @mysql;
          EXECUTE stmt;
          DEALLOCATE PREPARE stmt;
          ITERATE  repeat_label;
        
        #結束控制流程
        END IF;
        
        #動態執行SQL語句
        SET @mysql = strClear;
        PREPARE stmt from @mysql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        UNTIL done = 1 END REPEAT;
        
    #關閉遊標
    CLOSE curOne;
    
    #最後清理郵件記錄
     SET @mysql = "TRUNCATE TABLE wz_bid_mail;";
     PREPARE stmt from @mysql;
     EXECUTE stmt;
     DEALLOCATE PREPARE stmt;

END

過程準備:

1.MySQL預處理語句使用示例:

例一:通過文本字符拼接一個預處理語句
#創建一個函數求(X^2+Y^2)的平方根:
#?表示與參數進行綁定,?不需要用引號引用,相當於在prepare的時候就把sql寫死
PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS result';
SET @X = 3;
SET @Y = 4;
EXECUTE stmt1 USING @X @Y;

輸出:

result
5
例二:將文本語句當做一個變量
#創建一個函數求(X^2+Y^2)的平方根:
SET@sqlText = 'SELECT SQRT(POW(?,2)) + POW((?,2)) AS result ';
#將sqlText作爲一個包含語句文本的變量放入預備語句stmt2中,表明prepare之前可以用@param變量的形式注入sql語句
PREPARE stmt2 FROM @sqlText;
SET @X = 6;
SET @Y = 8;
EXECUTE stmt2 USING @X,@Y;

輸出:

result
10

注:

  • 該文本必須展現一個單一的SQL語句,而不是多個語句
  • ‘?'字符不應加引號,即使您想要把它們與字符串值結合在一起,也不要加引號。參數製作符只能被用於數據值應該出現的地方,不用於SQL關鍵詞和標識符等
  • 參數值只能有用戶變量提供,USING子句必須準確地指明用戶變量。用戶變量的數目與語句中的參數製造符的數量一樣多。
  • 以下SQL語句可以被用在預製語句中:CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE和多數的SHOW語句。目前不支持其它語句。

本章參考文檔:理解Mysql prepare預處理語句

2.基於Navicat 12.0創建MySQL存儲過程的例子:

  • 首先進入函數嚮導:Navicat 12.0功能區->函數->新建函數->過程
    如何需要設置存儲過程的參數,可以在這快速設置,如這裏傳入兩個入參X和Y,類型爲INT,出參R,類型爲INT,所以嚮導如圖所示:(注:這裏只是提供圖形化的參數設置,也可以跳過直接在存儲過程中添加)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章