mysql的高級特性-存儲過程

定義: 

  存儲例程是存儲在數據庫服務器中的一組sql語句,經過在查詢中調用一個指定的名稱來執行這些sql語句命令.前端

語法:

DELIMITER // 聲明語句結束符,用於區分; 
    CEATE PROCEDURE demo_in_parameter(IN p_huhy int) 聲明存儲過程 
    BEGIN
        sql語句體;
    END 存儲過程開始和結束符號 
    SET @p_huhy=1 變量賦值 
    DECLARE huhy_int int unsigned default 400; 變量定義

  注意:varchar類型數據必須加限定  varcahr(12)

  存儲過程(stored procedure)、存儲例程(store routine)、存儲函數區別 
  Mysql存儲例程實際包含了存儲過程和存儲函數,它們被統稱爲存儲例程。 
  其中存儲過程主要完成在獲取記錄或插入記錄或更新記錄或刪除記錄,即完成select insert delete update等的工做。而存儲函數只完成查詢的工做,可接受輸入參數並返回一個結果。mysql

  實例介紹:
    mysql> DELIMITER ;; 
    mysql> CREATE PROCEDURE huhy_count(OUT s int) 
    -> BEGIN
    -> SELECT COUNT(*) INTO s FROM user; 
    -> END
    -> ;; 
    mysql> DELIMITER ;

注: 
(1)這裏須要注意的是DELIMITER//和DELIMITER;兩句,DELIMITER是分割符的意思,由於MySQL默認以」;」爲分隔 符,若是咱們沒有聲明分割符,那麼編譯器會把存儲過程當成SQL語句進行處理,則存儲過程的編譯過程會報錯,因此要事先用DELIMITER關鍵字申明當 前段分隔符,這樣MySQL纔會將」;」當作存儲過程當中的代碼,不會執行這些代碼,用完了以後要把分隔符還原。 
(2)存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,這裏有一個輸出參數s,類型是int型,若是有多個參數用」,」分割開。 
(3)過程體的開始與結束使用BEGIN與END進行標識。sql

存儲過程的參數:

  MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT,形式如:

    CREATE PROCEDURE 存儲過程名([[IN |OUT |INOUT ] 參數名 數據類形…])

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

  note:關於參數的使用我會在建立存儲過程的時候再詳細介紹數據庫

局部變量

  定義:局部變量聲明必定要放在存儲過程體的開始 express

    DECLAREvariable_name [,variable_name…] datatype [DEFAULT value];
    其中,datatype爲MySQL的數據類型,如:int, float, date,varchar(length)
    eg:
      DECLARE huhy_int int unsigned default 12;
      DECLARE huhy_numeric number(5,2) DEFAULT 9.01;
      DECLARE huhy_date date DEFAULT '2007-12-31';
      DECLARE huhy_datetime datetime DEFAULT '2008-12-31 23:59:59';
      DECLARE huhy_varchar varchar(255) DEFAULT 'is huhy';

  變量賦值:
    SET 變量名 = 表達式值 [,variable_name = expression …]

用戶變量:後端

note:
  用戶變量名通常以@開頭
  濫用用戶變量會致使程序難以理解及管理

  1>在存儲過程間傳遞全局範圍的用戶變量
    mysql> CREATE PROCEDURE yang_1() SET @huhy_procedure='good';
    mysql> CREATE PROCEDURE yang_2() SELECT CONCAT('huhy is ',@huhy_procedure);
    mysql> CALL yang_1( );
    mysql> CALL yang_2( );
      +-----------------------------------------------+
      | CONCAT('huhy is ',@huhy_procedure |
      +-----------------------------------------------+
      | huhy is good                                       |
      +-----------------------------------------------+
  2>在存儲過程當中使用用戶變量
    mysql > CREATE PROCEDURE GreetWorld( ) SELECT CONCAT(@greeting,' World');
    mysql > SET @greeting='Hello';
    mysql > CALL GreetWorld( );
      +----------------------------+
      | CONCAT(@greeting,' World') |
      +----------------------------+
      | Hello World                  |
      +----------------------------+
  3>在MySQL客戶端使用用戶變量
    mysql > SELECT 'Hello World' into @x;
    mysql > SELECT @x;
      +-------------+
      | @x |
      +-------------+
      | Hello World |
      +-------------+ 服務器

註釋:

  MySQL存儲過程可以使用兩種風格的註釋 mybatis

  雙模槓:–- 該風格通常用於單行註釋
  c風格: 通常用於多行註釋 /********************* 建立表 *****************************/函數

 

MySQL存儲過程的調用

  用call和你過程名以及一個括號,括號裏面根據須要,加入參數,參數包括輸入參數、輸出參數、輸入輸出參數。具體的調用方法能夠參看上面的例子。性能

MySQL存儲過程的查詢

  咱們像知道一個數據庫下面有那些表,咱們通常採用showtables;進行查看。那麼咱們要查看某個數據庫下面的存儲過程,是否也能夠採用呢?答案是,咱們能夠查看某個數據庫下面的存儲過程,可是是令一鍾方式。 咱們能夠用 selectname from mysql.proc where db=’數據庫名’; 或者 selectroutine_name from information_schema.routines where routine_schema=’數據庫名’; 或者 showprocedure status where db=’數據庫名’; 進行查詢。 若是咱們想知道,某個存儲過程的詳細,那咱們又該怎麼作呢?是否是也能夠像操做表同樣用describe 表名進行查看呢? 答案是:咱們能夠查看存儲過程的詳細,可是須要用另外一種方法: 

SHOWCREATE PROCEDURE 數據庫.存儲過程名;
就能夠查看當前存儲過程的詳細。

MySQL存儲過程的修改

  ALTER PROCEDURE
  更改用CREATE PROCEDURE 創建的預先指定的存儲過程,其不會影響相關存儲過程或存儲功能。

 

MySQL存儲過程的刪除


  刪除一個存儲過程比較簡單,和刪除表同樣:
  DROP PROCEDURE
  從MySQL的表格中刪除一個或多個存儲過程。

 

MySQL存儲過程的基本函數

字符串類        
        CHARSET(str) //返回字串字符集
        CONCAT (string2 [,... ]) //鏈接字串
        INSTR (string ,substring ) //返回substring首次在string中出現的位置,不存在返回0
        LCASE (string2 ) //轉換成小寫
        LEFT (string2 ,length ) //從string2中的左邊起取length個字符
        LENGTH (string ) //string長度
        LOAD_FILE (file_name ) //從文件讀取內容
        LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定開始位置
        LPAD (string2 ,length ,pad ) //重複用pad加在string開頭,直到字串長度爲length
        LTRIM (string2 ) //去除前端空格
        REPEAT (string2 ,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 
                1.  mysql> select substring('abcd',0,2);  
                2.  +-----------------------+  
                3.  | substring('abcd',0,2) |  
                4.  +-----------------------+  
                5.  |                       |  
                6.  +-----------------------+  
                7.  1 row in set (0.00 sec)  
                8.   
                9.  mysql> select substring('abcd',1,2);  
                10.+-----------------------+  
                11.| substring('abcd',1,2) |  
                12.+-----------------------+  
                13.|     ab                |  
                14.+-----------------------+  
                15.1 row in set (0.02 sec)  
        TRIM([[BOTH|LEADING|TRAILING][padding] FROM]string2) //去除指定位置的指定字符
        UCASE (string2 ) //轉換成大寫
        RIGHT(string2,length) //取string2最後length個字符
        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爲小數位數]
                注:返回類型並不是均爲整數,如:
                (1)默認變爲整形值
                1.  mysql> select round(1.23);  
                2.  +-------------+  
                3.  | round(1.23) |  
                4.  +-------------+  
                5.  |           1 |  
                6.  +-------------+  
                7.  1 row in set (0.00 sec)  
                8.   
                9.  mysql> select round(1.56);  
                10.+-------------+  
                11.| round(1.56) |  
                12.+-------------+  
                13.|           2 |  
                14.+-------------+  
                15.1 row in set (0.00 sec) 


                (2)能夠設定小數位數,返回浮點型數據
                1.  mysql> select round(1.567,2);  
                2.  +----------------+  
                3.  | round(1.567,2) |  
                4.  +----------------+  
                5.  |           1.57 |  
                6.  +----------------+  
                7.  1 row in set (0.00 sec) 
        SIGN (number2 ) //
    日期時間類
        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) //開平方

mybatis操做mysql存儲過程:

  假設操做環境已經搭建完成。下面就來對其進行測試:

  接口以下:

    

  xml配置以下:

    

  測試以下:

    


總結:

  以上就是mybatis對存儲過程的簡單操做:關於存儲過程以下:  

1> 查詢表數據總共多少
    CREATE DEFINER=`huhy`@`%` PROCEDURE `huhy_count`(OUT `sum` int)
    BEGIN
        select count(*) INTO sum from user;
    END

    note: varchar類型數據必須加限定 eg varcahr(11),
    
2> 表名做爲存儲參數傳入存儲過程

DROP PROCEDURE IF EXISTS `pagePro`;
CREATE DEFINER = `root`@`localhost` PROCEDURE `pagePro`(in pageNo int,in pageSize int,in tableName varchar(50))
BEGIN
    DECLARE startIndex INT;
    set startIndex = pageSize * (pageNo-1);
    set @s = concat("select * from ",tableName," LIMIT ",startIndex,",",pageSize);
    prepare stmt from @s;
    execute stmt;
    DEALLOCATE prepare stmt;
END;

    mysql 是不支持表名,列名作參數的.只能採用動態拼接的方法來生成sql語句.

note:傳入三個參數,pageNo 是頁號,pageSize是一頁顯示的記錄數量,tableName是表名.
  eg:call pagePro(2,3,'student');

  你們要注意:存儲過程的一些特性,好比原生的存儲過程不容許傳表名,列名,等,還有存儲過程的語法,注意項。有興趣的能夠去試一下。合理的利用存儲過程會極大的提升代碼的性能。但並非存儲過程越多越好,你們合理掌握瓶頸問題。

相關文章
相關標籤/搜索