1. 程式人生 > >mysql儲存過程解決線上的一個問題

mysql儲存過程解決線上的一個問題

        最近線上有個問題是要給擁有A許可權的所有角色新增A許可權下的一個子許可權A1,因為需要查詢A許可權的所有角色,並批量

新增子許可權A1,所以簡單的sql不能處理此問題,有兩種方法:1. 寫指令碼解決 2. 用儲存過程解決。

        指令碼相對簡單些,在此不做記錄,主要講一下儲存過程解決辦法。

        #### 擁有**許可權的角色新增 **報表許可權
       DELIMITER //
       DROP PROCEDURE IF EXISTS batch_add_access_for_yingyun //
       CREATE PROCEDURE batch_add_access_for_yingyun()
       BEGIN
             DECLARE role_id INT; #定義變數 角色id
             DECLARE str VARCHAR (300); #為了給個該儲存函式執行成功後給個提示
             DECLARE s INT DEFAULT 0; #這個用於處理遊標到達最後一行的情況
             DECLARE yingyun_module_id INT DEFAULT (SELECT `module_id` FROM `module_info` WHERE `module_name` = '營運');
             DECLARE **_module_id INT DEFAULT (SELECT `module_id` FROM `module_info` WHERE `module_name` = '**報表');

             #宣告遊標cursor_name(cursor_name是個多行結果集)
             DECLARE role_ids CURSOR FOR SELECT `role_id` FROM `role_relation_map` WHERE `module_id` = yingyun_module_id;
             #設定一個終止標記
             DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s = 1;
             SET str = '--';
             #開啟遊標
             OPEN role_ids;
             #獲取遊標當前指標的記錄,讀取一行資料並傳給變數role_id
             FETCH role_ids INTO role_id;
             SELECT role_id;
             WHILE s <> 1 DO
                     SET str = CONCAT(str, s);
                     INSERT INTO `role_relation_map` (`role_id`,`module_id`)
                            SELECT role_id, **_module_id FROM DUAL WHERE NOT EXISTS 
                                 (SELECT `role_relation_id` FROM `role_relation_map` 
                                         WHERE `role_id` = role_id AND `module_id` = **_module_id);
                     #讀取下一行資料
                     FETCH role_ids INTO role_id;
              END WHILE;
              #關閉遊標
              CLOSE role_ids;
              SELECT str;
       END//
       DELIMITER ;

       CALL batch_add_access_for_yingyun();

       以上就是整個儲存過程的描述。

       有以下幾個知識點需要總結吧:

              1.儲存過程結果體中的變數定義

                 ①DECLARE用來宣告區域性變數,且DECLARE僅被用在BEGIN ... END複合語句裡,並且必須在複合語句的開頭,在任何其它語句之前;可以被用在巢狀的塊中,除了那些用相同名字宣告變數的塊。

            ②如果要給變數提供一個預設值,使用DEFAULT子句(值可以是常數,也可以指定為一個表示式);如果沒有DEFAULT子句,初始值為NULL。

             2.遊標的定義和迴圈遍歷呼叫

             3.mysql插入前判斷資料是否存在

            4.儲存過程的整體使用

       如果好的意見或建議,請不吝賜教~