MySQL存儲過程和函數


一、基本介紹

存儲過程和函數是事先經過編譯並存儲在數據庫中的一段SQL語句的集合,減少數據在數據庫和應用服務之間的傳輸,對於提高數據處理的效率是有好處的。

存儲過程和函數的區別在於 函數必須有返回值,而存儲過程沒有,存儲過程的參數可以使用IN、OUT、INOUT類型,而函數的參數只能是IN類型的。如果有函數從其他類型的數據庫遷移到MySQL,可能需要將函數改造成存儲過程。

存儲過程和函數允許包含DDL語句,也允許使用事務,還可以調用其他的存儲過程和函數,但不允許執行 Load Data Infile 語句;

 

二、相關操作

創建存儲過程或函數需要 CREATE ROUTINE 權限,修改或刪除存儲過程或函數需要 ALTER ROUTINE 權限,執行存儲過程或函數需要 EXECUTE 權限。

創建、修改存儲過程或函數

Create procedure sp_name([proc_parameter[,…])

      [characteristic…] routine_body

 

Create function sp_name([func_parameter[,…])

      Returns type

      [characteristic…] routine_body

      Return xxx

 

調用語法:call  sp_name([parameter[,…])

參數說明:

        pro_parameter

    [ IN | OUT | INOUT ]  param_name  type

        func_parameter

    param_name  type

        存儲過程和函數中不允許執行 LOAD DATA INFILE 語句。

        Delimiter $$ 修改命令結束符

        Characteristic特征值:

    Language sql 說明下面body是使用sql編寫,系統默認

    Sql security{ definer | invoker } 可以指定子程序該用創建子程序者的許可來執行還是使用調用者的權限執行。默認是definer

    Comment ‘string’ 存儲過程或函數的注釋信息

    { Contains sql | no sql | reads sql data | modifies sql data} 供子程序使用數據的內在信息,目前只提供給服務器,並沒有根據這些特征值來約束過程實際使用數據的情況,默認是contains sql;

    1.   Contains sql 表示子程序不包含讀或寫數據的語句。
    2.   No sql 表示子程序不包含sql語句。
    3.   Reads sql data 表示子程序包含讀數據的語句,但不包含寫數據的語句。
    4.   Modifies sql data 表示子程序包含寫數據的語句。

  實例:

  

  返回值用 @xxx

  

  

  

刪除存儲過程或函數:

  一次只能刪除一個存儲過程或函數,需 ALTER ROUTINE 權限

  Drop procedure name;

 

查看存儲過程或者函數:

        查看存儲過程或函數的狀態:

  Show { procedure | function } status [like ‘pattern’];

  

        查看存儲過程或函數的定義:

  Show create { procedure | function } name;

  

        通過查看information_schema.Routines了解存儲過程和函數的信息

  Select * from Routines where routine_name = “name”;

  

三、變量的使用

變量不區分大小寫

變量的定義

  Declare 定義一個局部變量,作用域在 BEGIN … END 塊中,可以用在嵌套的塊中。必須寫在復合語句的開頭,並且在任何其他語句的前面。可一次聲明多個相同類型的變量。如需要,可以使用default賦默認值。

  Declare var_name[,…]  type  [default value];

變量的賦值

  變量可以直接賦值,或者通過查詢賦值。直接賦值使用set,可以賦常量或者賦表達式。

  Set var_name = expr  [,var_name = expr] …

  Select col_name [,…]  INTO var_name [,…]  from xxx….;   #查詢結果必須只有一行

  Set @a = xxx;  相當於全局變量

 

定義條件和處理:

處理過程中遇到問題時相應的處理步驟。

 條件定義

  Declare condition_name  CONDITION FOR condition_value

條件處理(游標中有實例)

  Declare handler_type  HANDLER  FOR  condition_value   [,…]   sp_statement

  說明:

  Handler_type 目前支持 continueexit ,continue繼續執行下面的語句,exit表示終止。

  Condition_value 值可以通過declare定義的 condition_name,可以是SQLSTATE 的值或者mysql-error-code的值或SQLWARINGNOT FOUNDSQLEXECEPTION,這3個值是3種定義好的錯誤類別。

  1. SQLWARING 是對所有以01開頭的SQLSTATE代碼速記
  2. NOT FOUND 是對所有以02開頭的SQLSTATE 代碼速記
  3. SQLEXCEPTION 是對所有沒有被SQLWARING 或 NOT FOUND 捕獲的SQLSTATE 代碼速記

  

四、游標的使用

對結果集進行循環的處理,包括光標的聲明、open、fetch 和 close。

1條sql,對應N條結果集的資源,取出資源接口/句柄,就是游標,沿着游標,可以一次取出1行。好處是,每一行的處理權利在我們手中。

游標通俗來講相當於你買東西別人一件件的給你,而不是一下子全給你。

執行沒有數據錯誤:

修改存儲過程:

BEGIN

DECLARE row_id int;
DECLARE row_dt varchar(50);
DECLARE row_catalog int;
DECLARE row_total int;
DECLARE i int default 1;
DECLARE getArticle CURSOR FOR select id,dt,catalog from tblarticle where catalog = 75;
select count(*) INTO row_total from tblarticle where catalog=75;

OPEN getArticle;

WHILE i<=row_total DO
    FETCH getArticle into row_id, row_dt, row_catalog;

    SELECT row_id, row_dt, row_catalog;
    set i = i+1;
END WHILE;
CLOSE getArticle;

END
BEGIN

DECLARE row_id int;
DECLARE row_dt varchar(50);
DECLARE row_catalog int;
DECLARE row_total int;
DECLARE i int DEFAULT 1;
DECLARE getArticle CURSOR FOR select id,dt,catalog from tblarticle where catalog = 75;
DECLARE EXIT HANDLER FOR NOT FOUND set i = 0;

OPEN getArticle;

REPEAT
    FETCH getArticle into row_id, row_dt, row_catalog;
    SELECT row_id, row_dt, row_catalog;
UNTIL i = 0 END REPEAT;

CLOSE getArticle;

END

Declare continue/exit handler for not found close 游標名;

Continue 和 exit 的區別:

游標循環讀取的正確邏輯:

 

五、流程控制

If 、case、loop、leave、iterate、repeat、while語句

If語句

  IF search_condition THEN statement_list

       [ELSEIF search_condition THEN statement_list]…

       [ELSE statement_list]

  END IF ;

 

While語句

  WHILE search_condition Do

       Statement_list

  END WHILE [end_label] ;

   

  

  

  

        case語句

  

repeat語句(類似do…while

  

  

While repeat 的區別:

  While 是滿足條件才執行循環,repeat是滿足條件退出循環;

  While在首次循環執行之前就判斷條件,所以循環最少執行0次,而repeat是在首次執行循環之后才判斷條件,類似do…while,所以循壞最少執行1次;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM