一: 前言
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語句中不可用存儲過程,而可以使用函數
九: 總結
今天爲大家帶來了有關存儲過程的知識,大家自己消化練習下,下節爲大家帶來遊標,變量,流程控制的相關知識,謝謝大家!