mysql存儲過程和自定義函數

  • 存儲過程簡介

SQL語句須要先編輯後執行,而存儲過程是一組爲了完成特定功能的SQL語句集,經編譯後存儲過程在數據庫中,用戶經過制定存儲過程的名字並傳給參數來調用它。前端

存儲過程是可編程的函數,在數據庫中建立並保持,能夠由SQL和控制結構組成。檔想要在不一樣的應用平臺上執行相同的函數,或者封裝特定功能時,存儲過程是很是有用的,數據庫中的存儲過程能夠看錯是對編程面向對象方法的模擬,它容許控制數據的訪問方式。mysql

存儲過程的優勢:sql

1.加強SQL語言的功能和靈活性:存儲過程能夠用編程語句編寫,有很強的靈活性,能夠完成複雜的判斷和較複雜得運算。數據庫

2.標準組建式編程:存儲過程被建立後,能夠在程序中被屢次調用,而沒必要從新編寫該存儲過程的SQL語句。並且數據庫專業人員能夠隨時對數據庫存儲過程進行修改,對應用程序源代碼毫無影響。編程

3.較快的執行速度:若是某一操做包含大量的transaction-SQL代碼或分別被屢次執行,那麼存儲過程要比批處理的執行速度快不少。由於存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析優化,並且給出最終被存儲在系統表中的執行變化。2、批處理的transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對慢一些。後端

4.減小網絡流量:安全

針對同一數據庫對象若是這一操做所涉及的transaction-SQL語句被組織進存儲過程,那麼當客戶計算機在調用存儲過程時,網絡中傳送的只是該調用語句,從而大大減小網絡流量並下降了網絡負載。網絡

5.做爲一種安全機制來充分利用:經過對執行某一存儲過程的權限進行限制,能可以實現對相應數據的訪問權限的限制,避免了飛受權用戶對數據的訪問,保證了數據的安全。函數

***********************************************************************oop

自定義函數

1.函數必須指定返回值,並且參數默認IN類型

2.存儲過程沒有返回值,參數能夠是IN、OUT、IN OUT類型,有的人可能會理解成out也算是返回值。

3.調用方式:函數select my_fun();過程call my_pro();

mysql存儲過程和函數的區別

1.存儲過程實現的功能要複雜一點,函數實現功能針對性比較強。存儲過程功能強大,能夠執行包括修改表等一系列數據庫操做;用戶定義函數不能用於執行一組修改全局數據庫狀態的操做。

2.對於存儲過程來講能夠返回參數,如記錄集,函數只能返回值或者表對象。函數存儲過程的參數有IN、out、in out 三種,而函數只有in類;

存儲過程聲明時不須要返回類型,而函數聲明時須要描述返回類型,且函數體中必須包含一個有效的return語句。

3.存儲過程可使用非肯定函數,不容許在用戶定義函數主體中內置非肯定函數。

4.存儲過程通常是做爲一個獨立的部分來執行(EXECUTE語句執行),而函數能夠做爲查詢語句的一部分來調用(select調用)。

因爲函數能夠返回一個表對象,所以它能夠在查詢語句中位於from關鍵字的後面。sql語句中不可用存儲過程,而可使用函數。

**************************************************************

MySQL存儲過程的建立

語法
CREATE PROCEDURE 過程名([[IN|OUT|INOUT] 參數名 數據類型[,[IN|OUT|INOUT] 參數名 數據類型…]]) [特性 ...] 過程體
 

DELIMITER //
  CREATE PROCEDURE myproc(OUT s int)
    BEGIN
      SELECT COUNT(*) INTO s FROM students;
    END
    //
DELIMITER ;

IN參數的值必須在調用存儲過程時指定,在存儲過程當中修改該參數的值不能被返回,爲默認值
OUT:該值可在存儲過程內部被改變,並可返回
INOUT:調用時指定,而且可被改變和返回

  • 分隔符
    MySQL默認以";"爲分隔符,若是沒有生命分隔符,則編譯器會吧存儲過程當作SQL語句進行處理,所以編譯過程會報錯,因此要事先用"DELINITER//"聲明當前段分隔符,讓編譯器把兩個"//"之間的內容當作存儲過程的代碼,不會執行這些代碼;"DELINITER;"把分隔符還原。
  • 參數
    存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,若是有多個參數用","分割開。MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT:
  • 過程體
    過程體的開始與結束使用BEGIN與END進行標識。
  • IN參數例子

數據類型

日期和時間類型

字符串類型

#在MySQL客戶端使用用戶變量
SELECT 'Hello World' into @x;
SELECT @x;
SET @y='Goodbye Cruel World';
SELECT @y;
SET @z=1+2+3;
SELECT @z;

#在存儲過程當中使用用戶變量
CREATE PROCEDURE GreetWorld() SELECT CONCAT(@greeting,' World');
SET @greeting='Hello';
CALL GreetWorld();

#在存儲過程間傳遞全局範圍的用戶變量
CREATE PROCEDURE p1() SET @last_proc='p1';
CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc);
CALL p1();
CALL p2();
  • 註釋
    MySQL存儲過程可以使用兩種風格的註釋:
    雙槓:--,該風格通常用於單行註釋
    C風格: 通常用於多行註釋

  • mysql存儲過程的調用
    用call和你過程名以及一個括號,括號裏面根據須要,加入參數,參數包括輸入參數、輸出參數、輸入輸出參數。

  • MySQL存儲過程的查詢

  • #查詢存儲過程
    SELECT name FROM mysql.proc WHERE db='數據庫名';
    SELECT routine_name FROM information_schema.routines WHERE routine_schema='數據庫名';
    SHOW PROCEDURE STATUS WHERE db='數據庫名';
    
    #查看存儲過程詳細信息
    SHOW CREATE PROCEDURE 數據庫.存儲過程名;

    MySQL存儲過程的修改
    ALTER PROCEDURE 更改用CREATE PROCEDURE 創建的預先指定的存儲過程,其不會影響相關存儲過程或存儲功能。
    MySQL存儲過程的刪除
    DROP PROCEDURE [過程1[,過程2…]]
    從MySQL的表格中刪除一個或多個存儲過程。
    ***********************************************************************

  • 變量做用域

內部變量在其做用域範圍內享有更高的優先權,當執行到end時,內部變量消失,再也不可見了,在存儲過程外再也找不到這個內部變量,可是能夠經過out參數或者將其值指派給回話變量來保存其值。

#變量做用域
DELIMITER //
CREATE PROCEDURE proc()
BEGIN
  DECLARE x1 VARCHAR(5) DEFAULT 'outer';
    BEGIN
      DECLARE x1 VARCHAR(5) DEFAULT 'inner';
      SELECT x1;
    END;
  SELECT x1;
END;
//
DELIMITER ;
#調用
CALL proc();
  • 局部變量

定義局部變量,那麼變量名加上‘@’。

  • set和select其實能夠相互轉化,下面兩句是相同的
set @var=(select cnm FROM tbnm);  
select @var=cnm FROM tbnm;

***************************************************************************

條件語句

#條件語句IF-THEN-ELSE
DROP PROCEDURE IF EXISTS proc3;
DELIMITER //
CREATE PROCEDURE proc3(IN parameter int)
  BEGIN
    DECLARE var int;
    SET var=parameter+1;
    IF var=0 THEN
      INSERT INTO t VALUES (17);
    END IF ;
    IF parameter=0 THEN
      UPDATE t SET s1=s1+1;
    ELSE
      UPDATE t SET s1=s1+2;
    END IF ;
  END ;
  //
DELIMITER ;

 循環語句

while-do...end-while

DELIMITER //
  CREATE PROCEDURE proc5()
    BEGIN
      DECLARE var INT;
      SET var=0;
      WHILE var<6 DO
        INSERT INTO t VALUES (var);
        SET var=var+1;
      END WHILE ;
    END;
  //
DELIMITER ;

repeat...end repeat

此語句的特色是執行操做後檢查結果
DELIMITER //
  CREATE PROCEDURE proc6 ()
    BEGIN
      DECLARE v INT;
      SET v=0;
      REPEAT
        INSERT INTO t VALUES(v);
        SET v=v+1;
        UNTIL v>=5
      END REPEAT;
    END;
  //
DELIMITER ;

loop...end loop

DELIMITER //
  CREATE PROCEDURE proc7 ()
    BEGIN
      DECLARE v INT;
      SET v=0;
      LOOP_LABLE:LOOP
        INSERT INTO t VALUES(v);
        SET v=v+1;
        IF v >=5 THEN
          LEAVE LOOP_LABLE;
        END IF;
      END LOOP;
    END;
  //
DELIMITER ;
  • LABLES標號
    標號能夠用在begin repeat while 或者loop 語句前,語句標號只能在合法的語句前面使用。能夠跳出循環,使運行指令達到複合語句的最後一步。

  • ITERATE迭代
    ITERATE語句也是用來跳出循環的語句。可是,ITERATE語句是跳出本次循環,而後直接進入下一次循環。
    ITERATE語句的基本語法形式以下:

    ITERATE label

    其中,label參數表示循環的標誌。
    ITERATE語句只能夠出如今LOOP、REPEAT、WHILE語句內。
     

    經過引用複合語句的標號,來重新開始複合語句
    
    #ITERATE
    DELIMITER //
      CREATE PROCEDURE proc8()
      BEGIN
        DECLARE v INT;
        SET v=0;
        LOOP_LABLE:LOOP
          IF v=3 THEN
            SET v=v+1;
            ITERATE LOOP_LABLE;
          END IF;
          INSERT INTO t VALUES(v);
          SET v=v+1;
          IF v>=5 THEN
            LEAVE LOOP_LABLE;
          END IF;
        END LOOP;
      END;
      //
    DELIMITER ;

    該示例循環執行count加1的操做,count值爲100時結束循環。若是count的值可以整除3,則跳出本次循環,再也不執行下面的SELECT語句。

    說明:LEAVE語句和ITERATE語句都用來跳出循環語句,但二者的功能是不同的。

    LEAVE語句是跳出整個循環,而後執行循環後面的程序。而ITERATE語句是跳出本次循環,而後進入下一次循環。

    使用這兩個語句時必定要區分清楚。

    ************************************************************************

mysql存儲過程、自定義函數中使用的基本函數

  • 字符串類

charset(str)//返回字串字符集

concat(string1,string2)//返回字符串

instr(string,substring)//返回substring首次在string中出現的位置,不存在返回0

lcase(string)//轉化成小寫

ucase(string)//轉化成大寫

left(string,length)//從string的左邊取length個字符

right(string,length)//取string2最後length個字符

length(string)//string長度
load_file(file_name)//從文件讀取內容
locate(substring,string[,start_position])//同instr,但可指定開始位置
lpad(string,length,pad)//重複用pad加載string開頭,直到字符串長度爲length
ltrim(string)//除去前端空格
repeat(string,count)//重複count次
replace(str,search_str,replace_str)//在str中用replace_str替換search_str
RPAD (string2 ,length ,pad) //在str後用pad補充,直到長度爲length
RTRIM (string2 ) //去除後端空格
strcmp(string1,string2)//逐字符比較兩字串大小,
SUBSTRING (str , position [,length ]) //從str的position開始,取length個字符,
注:mysql中處理字符串時,默認第一個字符下標爲1,即參數position必須大於等於1
trim//去除指定位置的指定字符
SPACE(count) //生成count個空格

  • 數學類
    ABS (number2 ) //絕對值
    BIN (decimal_number ) //十進制轉二進制
    CEILING (number2 ) //向上取整
    CONV(number2,from_base,to_base) //進制轉換
    FLOOR (number2 ) //向下取整
    FORMAT (number,decimal_places ) //保留小數位數
    HEX (DecimalNumber ) //轉十六進制
    注:HEX()中可傳入字符串,則返回其ASC-11碼,如HEX('DEF')返回4142143
    也能夠傳入十進制整數,返回其十六進制編碼,如HEX(25)返回19
    LEAST (number , number2 [,..]) //求最小值
    MOD (numerator ,denominator ) //求餘
    POWER (number ,power ) //求指數
    RAND([seed]) //隨機數
    ROUND (number [,decimals ]) //四捨五入,decimals爲小數位數] 注:返回類型並不是均爲整數
    SIGN (number2 ) // 正數返回1,負數返回-1
  • 日期時間類 addtime(date2,time_interval)//將time_interval加到date2 CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //轉換時區 CURRENT_DATE ( ) //當前日期 CURRENT_TIME ( ) //當前時間 CURRENT_TIMESTAMP ( ) //當前時間戳 DATE (datetime ) //返回datetime的日期部分 DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或時間 DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式顯示datetime DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上減去一個時間 DATEDIFF (date1 ,date2 ) //兩個日期差 DAY (date ) //返回日期的天 DAYNAME (date ) //英文星期 DAYOFWEEK (date ) //星期(1-7) ,1爲星期天 DAYOFYEAR (date ) //一年中的第幾天 EXTRACT (interval_name FROM date ) //從date中提取日期的指定部分 MAKEDATE (year ,day ) //給出年及年中的第幾天,生成日期串 MAKETIME (hour ,minute ,second ) //生成時間串 MONTHNAME (date ) //英文月份名 NOW ( ) //當前時間 SEC_TO_TIME (seconds ) //秒數轉成時間 STR_TO_DATE (string ,format ) //字串轉成時間,以format格式顯示 TIMEDIFF (datetime1 ,datetime2 ) //兩個時間差 TIME_TO_SEC (time ) //時間轉秒數 WEEK (date_time [,start_of_week ]) //第幾周 YEAR (datetime ) //年份 DAYOFMONTH(datetime) //月的第幾天 HOUR(datetime) //小時 LAST_DAY(date) //date的月的最後日期 MICROSECOND(datetime) //微秒 MONTH(datetime) //月 MINUTE(datetime) //分返回符號,正負或0 SQRT(number2) //開平方
相關文章
相關標籤/搜索