手把手教你mysql(十四)存儲過程

一: 前言

CREATE DATABASE  IF NOT EXISTS `db_book2` DEFAULT CHARACTER SET GBK;

 

USE `db_book2`;

 

DROP TABLE IF EXISTS `t_book`;

 

CREATE TABLE `t_book` (

  `id` INT(11) PRIMARY KEY AUTO_INCREMENT,

  `bookName` VARCHAR(20) DEFAULT NULL,

  `price` DECIMAL(6,2) DEFAULT NULL,

  `author` VARCHAR(20) DEFAULT NULL,

  `bookTypeId` INT(11) DEFAULT NULL

) ENGINE=INNODB  DEFAULT CHARSET=GBK;

 

INSERT  INTO `t_book`  VALUES (NULL,'Java編程思想','100.00','埃史爾',1),(NULL,'Struts2權威指南','80.00','李剛',1),(NULL,'三劍客','70.00','大仲馬',2),(NULL,'生理學(第二版)','24.00','劉先國',3);

 

DROP TABLE IF EXISTS `t_booktype`;

 

CREATE TABLE `t_booktype` (

  `id` INT(11)   PRIMARY KEY  AUTO_INCREMENT,

  `bookTypeName` VARCHAR(20) DEFAULT NULL

) ENGINE=INNODB DEFAULT CHARSET=GBK;

 

INSERT  INTO `t_booktype`(`id`,`bookTypeName`) VALUES (1,'計算機類'),(2,'文學類'),(3,'教育類');

 

這是爲大家準備的練習數據,大家複製粘貼到mysql裏就行了,如果遇到亂碼問題,請參考我的另一篇文章http://blog.csdn.net/a672489861/article/details/16330821

 

 

二:存儲過程和函數的引入

存儲過程和函數是在數據庫中定義一些SQL 語句的集合,然後直接調用這些存儲過程和函數來執行已經定義好的SQL 語句。存儲過程和函數可以避免開發人員重複的編寫相同的SQL 語句。而且,存儲過程和函數是在MySQL服務器中存儲和執行的,可以減少客戶端和服務器端的數據傳輸。

 

三:創建存儲過程和函數

3.1 創建存儲過程

CREATE PROCEDURE sp_name([proc_parameter[,...]])

[characteristic...] routine_body

 

sp_name 參數是存儲過程的名稱;

proc_parameter 表示存儲過程的參數列表;

characteristic 參數指定存儲過程的特性;

routine_body 參數是SQL 代碼的內容,可以用BEGIN...END 來標誌SQL 代碼的開始和結束。

 

proc_parameter 中的每個參數由3 部分組成。這3 部分分別是輸入輸出類型、參數名稱和參數類型。

[ IN | OUT | INOUT ] param_name type

其中,IN 表示輸入參數;OUT 表示輸出參數;INOUT 表示既可以是輸入,也可以是輸出;

param_name 參數是存儲過程的參數名稱;

type 參數指定存儲過程的參數類型,該類型可以是MySQL 數據庫的任意數據類型;

 

Characteristic 參數有多個取值。其取值說明如下:

LANGUAGE SQL:說明routine_body 部分是由SQL 語言的語句組成,這也是數據庫系統默認的語言。

[ NOT ] DETERMINISTIC :指明存儲過程的執行結果是否是確定的。

DETERMINISTIC 表示結果是確定的。每次執行存儲過程時,相同的輸入會得到相同的輸出。

NOT DETERMINISTIC 表示結果是非確定的,相同的輸入

可能得到不同的輸出。默認情況下,結果是非確定的。

{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } :指明子程序使用SQL 語句的限制;

CONTAINS SQL 表示子程序包含SQL 語句,但不包含讀或寫數據的語句;

NO SQL 表示子程序中不包含SQL語句;

READS SQL DATA 表示子程序中包含讀數據的語句;

MODIFIES SQL DATA 表示子程序中包含寫數據的語句。默認情況下,系統會指定爲CONTAINS SQL;

SQL SECURITY { DEFINER | INVOKER };指明誰有權限來執行。

DEFINER 表示只有定義者自己才能夠執行;

INVOKER 表示調用者可以執行。默認情況下,系統指定的權限是DEFINER。

COMMENT ‘string’ :註釋信息;

 

例:mysql>DELIMITER $$

CREATE PROCEDURE pro_book(IN b INT)

READS SQL DATA

BEGIN

SELECT COUNT(*) FROM t_book WHERE booktypeid=b;

END;

$$

DELIMITER ;

Mysql>CALL pro_book(1);

大家可以把存儲過程想像爲封裝好的類,然後調用的時候傳入參數即可。



3.2 創建存儲函數

CREATE FUNCTION sp_name ( [func_parameter[,...]] )

RETURNS type

[ characteristic... ] routine_body

 

sp_name 參數是存儲函數的名稱

func_parameter 表示存儲函數的參數列表

RETURNS type 指定返回值的類型

characteristic 參數指定存儲過程的特性,該參數的取值與存儲過程中的取值是一樣的;routine_body 參數是SQL 代碼的內容,可以用BEGIN...END 來標誌SQL 代碼的開始和結束;

func_parameter 可以由多個參數組成,其中每個參數由參數名稱和參數類型組成,其形式如下:

param_name type

其中,param_name 參數是存儲函數的參數名稱

type 參數指定存儲函數的參數類型,該類型可以是MySQL 數據庫的任意數據類型。

存儲過程參數不同的是,存儲過程是:輸入輸出類型、參數名稱和參數類型。

存儲函數參數是:參數名稱和參數類型

 

例: mysql>DELIMITER $$

CREATE FUNCTION fun_book(bookId INT)

RETURNS VARCHAR(20)

BEGIN

RETURN(SELECT bookName FROM t_book WHERE id=bookId);

END;

$$

DELIMITER ;

Mysql>SELECT fun_book(1);

因爲存儲函數有返回值,所以用SELECT,不能用CALL.



四: 調用存儲過程和函數

4.1 調用存儲過程

CALL sp_name( [parameter[,...]] )

Mysql>CALL pro_book(1);

4.2     調用存儲函數

fun_name( [parameter[,...]] )

Mysql>SELECT fun_book(1);

 

五: 查看存儲過程和函數

5.1     SHOW STATUS 語句查看存儲過程和函數的狀態

SHOW { PROCEDURE | FUNCTION } STATUS [ LIKE ‘pattern’ ] ;

Mysql>

SHOW PROCEDURE STATUS  LIKE 'pro_book';

 

5.2     SHOW CREATE 語句查看存儲過程的函數的定義

SHOW CREATE { PROCEDURE | FUNCTION } sp_name ;

Mysql>SHOW CREATE FUNCTION fun_book;

 

5.3 從information_schema.Routines 表中查看存儲過程和函數的信息

Mysql>USE information_scherma;

Mysql>SELECT * from Routines;



 

六: 修改存儲過程和函數

ALTER { PROCEDURE | FUNCTION } sp_name [ characteristic ... ]

characteristic :

{ CONTAINS SQL } NO SQL | READS SQL DATA | MODIFIES SQL DATA }

| SQL SECURITY { DEFINER | INVOKER }

| COMMENT ‘string’

其中,sp_name 參數表示存儲過程或函數的名稱,characteristic 參數指定函數的特性

CONTAINS SQL 表示子程序包含SQL 語句,但不包含讀或寫數據的語句

NO SQL 表示子程序中不包含SQL 語句

READS SQL DATA表示子程序中包含數據的語句

 MODIFIES SQL DATA 表示子程序中包含寫數據的語句

SQL SECURITY{ DEFINER | INVODER } 指明誰有權限來執行。

DEFINER 表示只有定義者自己才能夠執行;

INVODER 表示調用者可以執行。

COMMENT ‘string’ 是註釋信息。

 

例: mysql>ALTER PROCEDURE `pro_book` COMMENT '測試';

修改完後我們來查看一下是否修改成功

Mysql>SHOW PROCEDURE STATUS LIKE `pro_book`;



其實不怎麼推薦用Alter來修改因爲Alter只能修改其特性,不能修改代碼。直接刪除然後新建存儲過程或者函數

 

七: 刪除存儲過程和函數

DROP {PROCEDURE | FUNCTION } sp_name ;

例: mysql>DROP PROCEDURE `pro_book`;

Mysql>DROP FUNCTION `fun_book`;



八: 存儲過程和存儲函數的詳細區別

 存儲過程是用戶定義的一系列sql語句的集合,涉及特定表或其它對象的任務,用戶可以調用存儲過程,而函數通常是數據庫已定義的方法,它接收參數並返回某種類型的值並且不涉及特定用戶表。

    存儲過程和函數存在以下幾個區別:

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

    2)對於存儲過程來說可以返回參數,如記錄集,而函數只能返回值或者表對象。函數只能返回一個變量;而存儲過程可以返回多個。存儲過程的參數可以有IN,OUT,INOUT三種類型,而函數只能有IN類~~存儲過程聲明時不需要返回類型,而函數聲明時需要描述返回類型,且函數體中必須包含一個有效的RETURN語句。

    3)存儲過程,可以使用非確定函數,不允許在用戶定義函數主體中內置非確定函數。

    4)存儲過程一般是作爲一個獨立的部分來執行( CALL 語句執行),而函數可以作爲查詢語句的一個部分來調用(SELECT調用)。 SQL語句中不可用存儲過程,而可以使用函數

 

 

九: 總結

今天爲大家帶來了有關存儲過程的知識,大家自己消化練習下,下節爲大家帶來遊標,變量,流程控制的相關知識,謝謝大家!奮鬥


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章