1. 程式人生 > >MySQL儲存過程、函式

MySQL儲存過程、函式

<pre code_snippet_id="419110" snippet_file_name="blog_20140706_2_9316759" name="code" class="sql">儲存程式優勢:
</pre>(1).儲存過程增強了SQL語言的功能和靈活性。儲存過程可以用流控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。(2).儲存過程允許標準組件是程式設計。儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。(3).儲存過程能實現較快的執行速度。如果某一操作包含大量的Transaction-SQL程式碼或分別被多次執行,那麼儲存過程要比批處理的執行速度快很多。因為儲存過程是預編譯的。在首次執行一個儲存過程時查詢,優化器對其進行分析優化,並且給出最終被儲存在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次執行時都要進行編譯和優化,速度相對要慢一些。(4).儲存過程能過減少網路流量。針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織程儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大增加了網路流量並降低了網路負載。(5).儲存過程可被作為一種安全機制來充分利用。系統管理員通過執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。<pre>
</pre><pre code_snippet_id="419110" snippet_file_name="blog_20140706_2_9316759" name="code" class="sql">下面是一個使用OUT引數的簡單的儲存程式的例子
mysql> delimiter //
 
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
    -> BEGIN
    ->   SELECT COUNT(*) INTO param1 FROM t;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)
 
mysql> delimiter ;
 
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT @a;
+------+
| @a   |
+------+
| 3    |
+------+
1 row in set (0.00 sec)
</pre><pre code_snippet_id="419110" snippet_file_name="blog_20140706_2_9316759" name="code" class="sql"><h2><span style="font-family:Microsoft YaHei">DECLARE語句</span></h2><p></p><p>DECLARE僅被用在BEGIN ... END複合語句裡,並且必須在複合語句的開頭,在任何其它語句之前。 </p><p>游標必須在宣告處理程式之前被宣告,並且變數和條件必須在宣告游標或處理程式之前被宣告。</p><h2><span style="font-family:Microsoft YaHei">儲存過程中的變數</span></h2><div><span style="font-family:Microsoft YaHei">
</span></div><h4><span style="font-family:Microsoft YaHei">DECLARE區域性變數</span></h4><p></p><pre code_snippet_id="419110" snippet_file_name="blog_20140706_6_5838959" name="code" class="sql">DECLARE var_name[,...] type [DEFAULT value]

這個語句被用來宣告區域性變數。要給變數提供一個預設值,請包含一個DEFAULT子句。值可以被指定為一個表示式,不需要為一個常數。如果沒有DEFAULT子句,初始值為NULL。

區域性變數的作用範圍在它被宣告的BEGIN ... END塊內。它可以被用在巢狀的塊中,除了那些用相同名字宣告變數的塊。  

SET變數語句

SET var_name = expr [, var_name = expr] ...

在儲存程式中的SET語句是一般SET語句的擴充套件版本。被參考變數可能是子程式內宣告的變數,或者是全域性伺服器變數。 

SELECT INTO 語句

SELECT col_name[,...] INTO var_name[,...] table_expr

這個SELECT語法把選定的列直接儲存到變數。因此,只有單一的行可以被取回。 

SELECT id,data INTO x,y FROM test.t1 LIMIT 1;

注意,使用者變數名在MySQL 5.1中是對大小寫不敏感的。請參閱9.3節,“使用者變數”


條件和處理程式

Declare條件

DECLARE condition_name CONDITION FOR condition_value
 
condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code
這個語句指定需要特殊處理的條件。它將一個名字和指定的錯誤條件關聯起來。這個名字可以隨後被用在DECLARE HANDLER語句中。 

除了SQLSTATE值,也支援MySQL錯誤程式碼。
</pre><pre code_snippet_id="419110" snippet_file_name="blog_20140706_10_6057110" name="code" class="sql"><p></p><h4><span style="font-family:Microsoft YaHei">Declare處理程式</span></h4><p></p><p></p><pre code_snippet_id="419110" snippet_file_name="blog_20140706_11_866660" name="code" class="sql">DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
 
handler_type:
    CONTINUE
  | EXIT
  | UNDO
 
condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
  | mysql_error_code

這個語句指定每個可以處理一個或多個條件的處理程式。如果產生一個或多個條件,指定的語句被執行。

對一個CONTINUE處理程式,當前子程式的執行在執行處理程式語句之後繼續。對於EXIT處理程式,當前BEGIN...END複合語句的執行被終止。UNDO 處理程式型別語句還不被支援。

·         SQLWARNING是對所有以01開頭的SQLSTATE程式碼的速記。

·         NOT FOUND是對所有以02開頭的SQLSTATE程式碼的速記。

·         SQLEXCEPTION是對所有沒有被SQLWARNING或NOT FOUND捕獲的SQLSTATE程式碼的速記。

除了SQLSTATE值,MySQL錯誤程式碼也不被支援

mysql> CREATE TABLE test.t (s1 int,primary key (s1));
Query OK, 0 rows affected (0.00 sec)
 
mysql> delimiter //
 
mysql> CREATE PROCEDURE handlerdemo ()
    -> BEGIN
    ->   DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x = 1;
    ->   SET @x = 1;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @x = 2;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @x = 3;
    -> END;
    -> //
Query OK, 0 rows affected (0.00 sec)
 
mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT @x//
    +------+
    | @x   |
    +------+
    | 3    |
    +------+
    1 row in set (0.00 sec)
注意到,@x是3,這表明MySQL被執行到程式的末尾。如果DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; 這一行不在,第二個INSERT因PRIMARY KEY強制而失敗之後,MySQL可能已經採取預設(EXIT)路徑,並且SELECT @x可能已經返回2。

游標

游標必須在宣告處理程式之前被宣告,並且變數和條件必須在宣告游標或處理程式之前被宣告

例如

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
 
  OPEN cur1;
  OPEN cur2;
 
  REPEAT
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF NOT done THEN
       IF b < c THEN
          INSERT INTO test.t3 VALUES (a,b);
       ELSE
          INSERT INTO test.t3 VALUES (a,c);
       END IF;
    END IF;
  UNTIL done END REPEAT;
 
  CLOSE cur1;
  CLOSE cur2;
END

DECLARE cursor_name CURSOR FOR select_statement
這個語句宣告一個游標。也可以在子程式中定義多個游標,但是一個塊中的每一個游標必須有唯一的名字。

SELECT語句不能有INTO子句。
OPEN cursor_name
這個語句開啟先前宣告的游標。
FETCH cursor_name INTO var_name [, var_name] ...
這個語句用指定的開啟游標讀取下一行(如果有下一行的話),並且前進游標指標。 


CLOSE cursor_name
這個語句關閉先前開啟的游標。 

如果未被明確地關閉,游標在它被宣告的複合語句的末尾被關閉。

1、儲存過程selectAll

CREATE PROCEDURE selectAll()
BEGIN
SELECT * FROM imooc_goddess;
END

在資料庫端測試儲存過程

call selectAll();
  • 1

2、儲存過程select_filter()

CREATE  PROCEDURE `select_filter`(IN `sp_name` varchar(20))
    READS SQL DATA
BEGIN
    IF sp_name IS NULL OR sp_name = '' THEN
        SELECT * FROM imooc_goddess;
    ELSE
    IF LENGTH(sp_name)>9 AND SUBSTRING(sp_name,1,1) THEN
        SELECT * FROM imooc_goddess WHERE mobile=sp_name;
        ELSE
            SELECT * FROM imooc_goddess WHERE user_name LIKE CONCAT('%',sp_name,'%');
END if;
END IF;
END

3、儲存過程select_count()

CREATE  PROCEDURE `select_count`(OUT `counts` int)
BEGIN
    SELECT count(*) INTO counts FROM imooc_goddess;
END

資料庫上的自定義函式

1、自定義函式returnDate()

CREATE DEFINER=`root`@`localhost` FUNCTION `returnDate`() RETURNS varchar(30) CHARSET utf8
RETURN DATE_FORMAT(NOW(),'%Y年%m月%d日:%H時:%i分:%s秒')

在 Navicat 查詢裡呼叫

select returnDate();
  • 1

在 java 專案上呼叫

CallableStatement cs = conn.prepareCall("{?= call returnDate()}");
  • 1

2、自定義函式returnFloat()

CREATE DEFINER=`root`@`localhost` FUNCTION `returnFloat`(num1 SMALLINT UNSIGNED,num2 SMALLINT UNSIGNED) RETURNS float(10,2) unsigned
RETURN (num1+num2)/2

1.2、資料準備

  1. CREATETABLE
  2.     t_user  
  3.     (  
  4.         USER_ID INTNOTNULL AUTO_INCREMENT,  
  5.         USER_NAME CHAR(30) NOTNULL,  
  6.         USER_PASSWORD CHAR(10) NOTNULL,  
  7.         USER_EMAIL CHAR(30) NOTNULL,  
  8.         PRIMARYKEY (USER_ID),  //主鍵
  9.         INDEX IDX_NAME (USER_NAME)  //索引
  10.     )  
  11.     ENGINE=InnoDB DEFAULT CHARSET=utf8;  

1.3 IN、OUT、INOUT引數

(1)、帶IN的儲存過程

  1. //建立儲存過程.cmd 中執行  
  2. CREATEPROCEDURE  SP_SEARCH(IN p_name CHAR(20))  
  3. BEGIN
  4. IF p_name isnullor p_name=''THEN
  5. SELECT * FROM t_user;  
  6. ELSE
  7. SELECT * FROM t_user WHERE USER_NAME LIKE p_name;  
  8. END IF;  
  9. END

 呼叫:

  1. //呼叫並輸出結果  
  2. CALL SP_SEARCH('林炳文')  

 (2)、帶OUT的儲存過程

  1. //帶OUT返回的  
  2. CREATEPROCEDURE  SP_SEARCH2(IN p_name CHAR(20),OUT p_int INT)  
  3. BEGIN
  4. IF p_name isnullor p_name=''THEN
  5. SELECT * FROM t_user;  
  6. ELSE
  7. SELECT * FROM t_user WHERE USER_NAME LIKE p_name;  
  8. END IF;  
  9. SELECT FOUND_ROWS() INTO p_int;  
  10. END
呼叫輸出:統計帶林開頭的人數
  1. //呼叫並輸出結果  
  2. CALL SP_SEARCH2('林%',@p_num);  
  3. SELECT @p_num;  

 (3)、帶INOUT的儲存過程

  1. //帶INOUT的儲存過程  
  2. CREATEPROCEDURE sp_inout(INOUT p_num INT)  
  3. BEGIN
  4. SET p_num=p_num*10;  
  5. END
  6. //呼叫並輸出結果  
  7. SET @p_num=2;  
  8. call sp_inout(@p_num);  
  9. SELECT @p_num;  
儲存過程得元素介紹:

      儲存過程體中可以使用各種sql語句和過程式語句的組合,來封裝資料庫應用中複雜的業務邏輯和處理規則,以實現資料庫應用的靈活程式設計。下面主要介紹幾個用於構造儲存過程體的常用語法元素

1、區域性變數
在儲存過程體中可以宣告區域性變數,用來儲存儲存過程體中臨時結果。

  1. DECLARE var_name[,…] type [DEFAULT value]  
  2. Var_name:指定區域性變數的名稱  
  3. Type:用於宣告區域性變數的資料型別  
  4. default子句:用於為區域性變數指定一個預設值。若沒有指定,預設為null.  
如:
  1. Declare cid int(10);  
2、set語句
使用set語句為區域性變數賦值
  1. Set var_name=expr  
  2. Set cid=910; 
3、select … into 語句
把選定列的值直接儲存到區域性變數中,語法格式
  1. Select col_name[,…] into var_name[,…] table_expr  
  2. Col_name:用於指定列名  
  3. Var_name:用於指定要賦值的變數名  
  4. Table_expr:表示select語句中的from字句及後面的語法部分  
說明:儲存過程體中的select…into語句返回的結果集只能有一行資料。

4、定義處理程式
是事先定義程式執行過程中可能遇到的問題。並且可以在處理程式中定義解決這些問題的辦法。這種方式可以提前預測可能出現的問題,並提出解決方法。

  1. DECLARE handler_type HANDLER FOR condition_value[,…] sp_statement  
  2. handler_type:CONTINUE | EXIT | UNDO  
  3. Condition_value:Sqlwarning | not found | sqlexception

5、流程控制語句

(1)條件判斷語句
If語句

  1. If search_condition then statement_list  
  2. 相關推薦

    修改MySQL儲存過程函式事件觸發器檢視的DEFINER

    #修改儲存過程、函式、事件、觸發器、檢視的 DEFINER select definer from mysql.proc; update mysql.proc set definer='[email protected]%'; select DEFINER fro

    淺談 sqlserver 和 mysql儲存過程函式的區別

    其實我不太喜歡搞資料庫,平常也就是用用select、insert。這次公司要把資料庫從sqlserver遷到mysql,我也試著改了幾個儲存過程,在此總結。首先吐槽一句,sqlserver和 mysql差別還真大! 區別一:儲存過程入參 USE [LearningRep

    MySQL儲存過程函式

    <pre code_snippet_id="419110" snippet_file_name="blog_20140706_2_9316759" name="code" class="sql">儲存程式優勢:</pre>(1).儲存過程增強了SQ

    Mysql的檢視儲存過程函式索引全解析

    檢視是查詢命令結果構成的一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的資料集,併為其命名】,使用者使用時只需使用【名稱】即可獲取結果集合,並可以當作表來查詢使用。 1建立檢視 --格式:CREATE VIEW 檢視名稱 AS  SQL語句 CREATE VIEW v1 AS S

    mysql-檢視觸發器事務儲存過程函式

    目錄 檢視 觸發器 事務 儲存過程 流程控制 一、檢視 檢視是由查詢結果構成的一張虛擬表,和真實的表一樣,帶有名稱的列和行資料 強調:檢視是永久儲存的,但是檢視儲存的不是資料,只是一條sql語句 檢視的特點: 檢視的列可以來自不同的表,是表的抽象和邏輯意義上建立的新關係。 

    mysql資料庫學習11-儲存過程函式觸發器

    儲存的程式 ========================================   * 資料庫中儲存的程式,對資料進行運算處理      * 儲存過程   * 函式   * 觸發器    會話變數

    初學mysql(十)-資料庫之儲存過程函式與遊標-自定義函式和流程控制(下)

    上一篇部落格講了儲存過程、函式、以及遊標,這一篇部落格接著上一篇部落格來說。首先說說mysql資料庫中的流程控制及自定義函式的使用。 自定義函式: 根據所需要的功能,使用流程控制來完成所需要的功能,完成功能的程式碼就稱為自定義函式。要想完成自定義函式就必須學會流程控制的使

    修改MySql儲存過程函式事件觸發器檢視的 DEFINER

    #修改儲存過程、函式、事件、觸發器、檢視的 DEFINER select definer from mysql.proc; update mysql.proc set definer='[email protected]'; or update mysql.pro

    我的Python成長之路--Day48--mysql高階(檢視觸發器事物儲存過程函式流程控制資料備份與恢復)

    目錄 1、檢視 2、觸發器 3、事物 自定義函式 1、檢視 1.1、什麼是檢視 檢視是一張表或者多張表的查詢結果構成的一張虛擬表

    MySQL儲存過程函式的區別與優缺點

    為什麼要使用儲存過程和函式 資料庫物件儲存過程和函式,是用來實現一組關於表操作的SQL語句程式碼當做一個整體來執行。一個完整的操作會包含多條SQL語句,在執行過程中需要根據前面的SQL語句來執行結果有選擇的執行後面的SQL語句。 儲存過程和函式可以簡單的理解為一條或多條SQL語句的集合

    mysql儲存過程函式(一)

      儲存過程和函式是事先經過編譯並存儲在資料庫的一段sql語句集合,呼叫儲存過程和函式可以簡化應用程式開發人員的很多工作,減少資料在資料庫和應用伺服器之間的傳輸,對提高資料執行效率是有好處的。   儲存過程和函式的區別在於函式必須有返回值,而儲存過程卻沒有,儲存過程的引數可以使用IN,OUT,INOUT型別

    mysql 儲存過程函式中游標的使用

    在儲存過程和函式中,可以使用游標對結果集進行迴圈的處理。 游標的使用包括游標的生命、OPEN、fetch、和close,其語法如下: 1、宣告游標:  declare 游標名 cursor for select_statement(查詢語句) 2、open游標: &nb

    檢視觸發器事務儲存過程函式,流程控制

    檢視 檢視是一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的資料集,併為其命名】,使用者使用時只需使用【名稱】即可獲取結果集,可以將該結果集當做表來使用。 使用檢視我們可以把查詢過程中的臨時表摘出來,用檢視去實現,這樣以後再想操作該臨時表的資料時就無需重寫複雜的sql了,直接去檢視中查詢即可,

    mysql 儲存過程函式

      什麼是儲存過程和函式     儲存過程和函式是事先經過編譯儲存在資料庫中的一段 SQL語句的集合,呼叫儲存過程和函式可以簡化應用開發人員的很多工作,減少資料在資料庫和應用伺服器中的傳輸,對於提高資料處理的效率是有好處的。    

    Oracle 儲存過程函式的建立和呼叫

    一、Oracle 建立和呼叫儲存過程 1、基本語法 create or replace procedure update_emp_sal (Name in out type, Name in out type, ... ) is begin end update_emp_

    sql語句---儲存過程函式和觸發器

    儲存過程、函式和觸發器的原理: 實際上都是使用Transact-SQL語言編寫的程式。儲存過程和函式需要顯式呼叫才能執行,而觸發器則在滿足指定條件時自動執行。 1、儲存過程 1.1 定義 儲存過程是Transact-SQL語句的預編譯集合,這些語句在一個名稱下儲

    檢視儲存過程函式觸發器事件

    儲存過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中。使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。儲存過程是資料庫中的一個重要物件,任何一個設計良好的資料庫應用程式都應該用到儲存過程。函式l過程不必返回值l函式必須返回值l過程可

    MySQL 儲存過程函式

    概述   一提到儲存過程可能就會引出另一個話題就是儲存過程的優缺點,這裡也不做討論。因為mysql中儲存過程和函式的語法非常接近所以就放在一起,主要區別就是函式必須有返回值(return),並且函式的引數只有IN型別而儲存過程有IN、OUT、INOUT這三種類型。  1.建立儲存過程和函式語法

    mysql 儲存過程遊標及逐行處理的配合使用

    1. 資料準備 +----+------+--------+ | id | name | price1 | +----+------+--------+ | 1 | 大米 | 5 | | 2 | 雞蛋 | 4.5 | | 3 | 蘋果 | 6

    第六篇:檢視觸發器事務儲存過程函式

    一 檢視 檢視是一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的資料集,併為其命名】,使用者使用時只需使用【名稱】即可獲取結果集,可以將該結果集當做表來使用。 使用檢視我們可以把查詢過程中的臨時表摘出來,用檢視去實現,這樣以後再想操作該臨時表的資料時就無需重寫複雜的sql了,直接去檢視中查詢即