mysql存儲過程小解

mysql 存儲過程
1.建立語法
 delimiter $$                 --$$表示改變默認的分隔符,表明如下爲存儲過程,否則會以SQL的方式執行
 drop procedure if exists pro_name$$ --建立存儲過程以前判斷是否存在,存在則先刪除
 create procedure pro_name(
 in paramIn type(length),                 --IN:輸入參數,不寫則默認爲IN,而且在存儲過程不能改變值
 out paramOut type(length),                 --Out:輸出參數
 inout paranInOut type(length)                 --InOut 輸入輸出參數
 )
 begin
 ...SQL...
 end $$
 delimiter;                 --恢復mysql的默認分隔符
2.mysql變量類型
  <1>局部變量
    存儲過程當中用declare聲明的變量。如 Declare name varchar(100) default 'dawa';
    default值能夠不設置,默認爲對象類型的系統默認值。
  <2>用戶變量
    以"@"符號開頭,如 set @name = 'dawa'或者在存儲過程當中select @name := ...
    用戶變量只對當前當前用戶使用的客戶端有效。
  <3>會話變量
    以"@@"符號開頭,如 set @@session.name = 'dawa' 或set session name = 'dawa';
    會話變量僅對鏈接的客戶端有效。
  <4>全局變量
    以"@@"符號開頭,如 set @@global.name = 'dawa' 或者set global name = 'dawa';
    對全部客戶端生效,只有super權限才能夠設置global變量
   declare專門用於聲明局部變量,set用於設置變量值。注set設置值有兩種方式 set param = value 或 set param := value;
3.經常使用語法
  <1>if...then...elseif...then...else...end if;
     示例:
        DELIMITER $$     
    DROP PROCEDURE IF EXISTS HelloWorld$$   
    CREATE PROCEDURE HelloWorld (
      param INT,
      OUT paramout INT,
      INOUT paramInOut INT
    ) 
    BEGIN
      IF param MOD 3 = 0 THEN 
        SET paramout := param DIV 3;
         SET paramInOut := param MOD 3;
      ELSEIF param MOD 2 = 0 THEN 
          SET paramout := param DIV 2;
          SET paramInOut := param MOD 2;
      ELSE
          SET paramout := param DIV 5;
          SET paramInOut := param MOD 5;
      END IF;

      SELECT paramout,paramInOut ;
    END $$   
    DELIMITER ;
  <2>循環:
    a.LOOP...END LOOP
    示例:
        DELIMITER $$     
        DROP PROCEDURE IF EXISTS HelloWorld$$   
        CREATE PROCEDURE HelloWorld (param INT, OUT paramout INT) 
        BEGIN
          DECLARE counter INT (10) ;
          SET counter := param ;
          SET paramout = 0 ;
          my_loop :
          LOOP
            SET paramout := paramout + counter ;
            SET counter := counter - 1 ;
            IF counter <= 0 
            THEN LEAVE my_loop ;
            END IF ;
          END LOOP my_loop ;
        END $$
        DELIMITER ;
    b.WHILE...DO...END WHILE
    示例:
        DELIMITER $$     
        DROP PROCEDURE IF EXISTS HelloWorld$$   
        CREATE PROCEDURE HelloWorld (param INT, OUT paramout INT) 
        BEGIN
          DECLARE counter INT (10) ;
          SET counter := param ;
          SET paramout = 0 ;
          WHILE
            counter >= 0 DO 
            SET paramout := paramout + counter ;
            SET counter := counter - 1 ;
          END WHILE ;
        END $$
        DELIMITER ;
    c.REPEAT...UNTIL...END REPAEAT
    示例:
        DELIMITER $$     
        DROP PROCEDURE IF EXISTS HelloWorld$$   
        CREATE PROCEDURE HelloWorld (param INT, OUT paramout INT) 
        BEGIN
          DECLARE counter INT (10) ;
          SET counter := param ;
          SET paramout = 0 ;
          REPEAT
            SET paramout := paramout + counter ;
            SET counter := counter - 1 ;
            UNTIL counter <= 0 
          END REPEAT ;

        END $$
        DELIMITER ;
  <3>遊標Cursor:用於查詢數據批處理,cursor使用方法
    declare cursor_name cursor  for select...from table;
    open cursor_name;
        my_loop:LOOP
            fetch cursor into variable;
            if..then
            leave my_loop;
            end if;
        end LOOP;
    close cursor_name;
    示例:
        DELIMITER $$

        USE `cssdj_shixi` $$

        DROP PROCEDURE IF EXISTS `test` $$

        CREATE DEFINER = `root` @`localhost` PROCEDURE `test` (OUT paramout VARCHAR (100)) 
        BEGIN
          DECLARE counter INT DEFAULT 0 ;
          DECLARE done INT DEFAULT 0;
          DECLARE notice CURSOR FOR SELECT operaName FROM g_prac_notice ;
          DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := 1;
          DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
          START TRANSACTION;
          OPEN notice ;
            notice_loop :LOOP
                FETCH notice INTO paramout ;
                SET counter := counter + 1 ;
                IF done = 1 OR counter = 1 THEN
                    LEAVE notice_loop;
                END IF;
            END LOOP notice_loop ;
          CLOSE notice ;
          COMMIT;
          SELECT paramout,done,counter;
        END $$

        DELIMITER ;
    
4.異常處理
  <1>語法:
    DECLARE 
     CONTINUE                       -- 繼續
    |EXIT                 -- 退出
    |UNDO                -- 撤回,暫不支持
    HANDLER
    FOR
     mysql_error_code               -- mysql對應的錯誤代碼
    |SQLSTATE[VALUE] sqlstate_value -- SQLState標準錯誤代碼
    |condition_name                 -- 自定義異常
    |SQLWARNING                     -- SQLSTATE中以"01"開頭的異常,默認繼續執行
    |NOT FOUND             -- SQLSTATE中以"01"開頭的異常,默認繼續執行
    |SQLEXCEPTION            -- SQLSTATE中不是以"00","01","02"開頭的其餘異常
    statement            -- 執行語句:如 set done = 1;

      condition_name:mysql_error_code及sqlstate_value值閱讀性比較差
    示例:
        #原來的
        DECLARE CONTINUE HANDLER FOR 1216 statement;
        #改變的
        DECLARE foreign_key_error CONDITION FOR 1216 ;
        DECLARE CONTINUE HANDLER FOR foreign_key_error statement;

 <2>示例:
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := 1;
     DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
相關文章
相關標籤/搜索