MySQL基礎知識(六)——儲存過程
一 .儲存過程
1.定義:
儲存過程是SQL語句和控制語句的預編譯集合,以一個名稱儲存並作為一個單元處理。
2.SQL命令的執行過程:
(1)輸入SQL命令;
(2)MySQL引擎對輸入的SQL命令進行語法分析。
(3)引擎分析MySQL的語法正確後;
(4)編譯成MySQL引擎可以識別的命令。
(5)最後開始執行結果;
(6)並將執行結果返回給客戶端。
省略語法分析和編譯環節,MySQL執行效率就可以提高。
3.儲存過程的優點:
- 增強SQL語句的功能和靈活性;
( 解釋:在儲存過程內可以寫控制語句,那麼就有很強的靈活性完成複雜的判斷以及較為複雜的運算;
儲存過程儲存在資料庫內,可以由應用程式呼叫執行,而且允許使用者宣告變數以及進行流程控制;
儲存過程可以接收引數,可以接收輸入型別的引數,也可以接收輸出型別的引數,並且可以存在多個返回值。)
- 實現較快的執行速度;
( 解釋:儲存過程是預編譯的,只有當第一次呼叫儲存過程時,進行語法分析和編譯的過程,並將編譯結果儲存在記憶體中, 以後再呼叫直接從記憶體中使用編譯後的結果,加快了執行速度;儲存過程的效率要比單一SQL的執行效率高。)
- 減少網路流量;
(解釋:如果通過客戶端單獨傳送SQL語句讓伺服器執行,那麼通過http協議所提交的資料量相對來說較大,
使用儲存過程只需要傳遞儲存過程名字和引數,傳遞給伺服器的資料量相對來說較小。)
4.語法
CREATE [DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
[DEFINER = { user | CURRENT_USER }]省略掉表示預設為當前使用者,sp_name是儲存過程的名字。
(1)引數proc_parameter:
[ IN | OUT | INOUT ] param_name type
- IN,表示該引數的值必須在呼叫儲存過程時指定;
- OUT,表示該引數的值可以被儲存過程改變,並且可以返回;
- INOUT,表示該引數的呼叫時指定,並且可以被改變和返回。
(2)特性
COMMENT ' String ' | {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER}
- COMMENT:註釋
- CONTAINS SQL:包含SQL語句,但不包含讀或寫資料的語句
- NO SQL:不包含SQL語句
- READS SQL DATA: 包含讀資料的語句
- MODIFIES SQL DATA:包含寫資料的語句
- SQL SECURITY {DEFINER | INVOKER}:指名誰有許可權來執行
(3)過程體
- 過程體由合法的SQL語句構成;
- 過程體可以是任意SQL語句;
- 過程體如果為複合結構則使用BEGIN...END語句;
- 複合結構可以包含宣告,迴圈,控制結構。
5.呼叫儲存過程
語法:
- CALL sp_name([parameter[,...]])
- CALL sp_name[()]
6.建立一個無參的儲存過程
# 建立一個不帶引數的儲存過程
CREATE PROCEDURE spl() SELECT VERSION();
# 呼叫儲存過程--方法一
CALL spl();
# 呼叫儲存過程--方法二
CALL spl;
6.建立帶有IN型別引數的儲存過程
# 建立帶有IN型別引數的儲存過程 ,根據userId刪除使用者
# 引數名不能和資料表中名稱相同
CREATE PROCEDURE removeUserById(IN p_id INT UNSIGNED)
BEGIN
DELETE FROM inserttest WHERE id = p_id;
END
# 呼叫儲存過程
CALL removeUserById(15);
7.建立帶有IN和OUT型別的儲存過程
# 刪除指定id的使用者,並且返回剩餘的記錄數
CREATE PROCEDURE removeUserAndReturnUserNum(IN p_id INT UNSIGNED,OUT userNums INT UNSIGNED)
BEGIN
DELETE FROM inserttest WHERE id = p_id;
SELECT COUNT(id) FROM inserttest INTO userNums;
END
# 使用儲存過程,第二個引數為接收引數,所以使用變數來接收
CALL removeUserAndReturnUserNum(18,@nums);
# 檢視返回的結果-->變數
SELECT @nums;
# 這樣是設定使用者變數,只對當前登入的使用者所使用客戶端有有效
SET @i = 7;
8.建立帶有多個OUT型別的儲存過程
# 系統函式,得到插入刪除以及更新到被影響的記錄總數
SELECT ROW_COUNT();
# 根據使用者名稱刪除使用者,並返回刪除的使用者和剩餘的使用者
CREATE PROCEDURE removeUserByNameAndReturnUserNum(IN p_username VARCHAR(20),OUT deleteUsers INT UNSIGNED,OUT userCounts INT UNSIGNED)
BEGIN
DELETE FROM inserttest WHERE username = p_username;
SELECT ROW_COUNT() INTO deleteUsers;
SELECT COUNT(id) FROM inserttest INTO userCounts;
END
# 使用儲存過程,第二個引數為接收引數,所以使用變數來接收
CALL removeUserByNameAndReturnUserNum('111',@deleteUsers,@userCounts);
# 檢視刪除的記錄數
SELECT @deleteUsers;
# 檢視剩餘的記錄數
SELECT @userCounts;
9.修改儲存過程
語法:ALTER PROCEDURE sp_name [characteristic ...] COMMENT 'string' | {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER }
只能修改簡單的特性,不能修改過程體,如果需要修改過程體,只能刪除儲存過程,再重新建立。
10.刪除儲存過程
語法:DROP PROCEDURE [IF EXISTS] sp_name
# 刪除儲存過程
DROP PROCEDURE removeUserByNameAndReturnUserNum;
11.儲存過程與自定義函式的區別
- 儲存過程實現的功能要複雜一些;而函式的針對性更強;
- 實際使用中經常使用儲存過程對錶進行操作;很少使用函式對錶進行操作;
- 儲存過程可以返回多個值;函式只能有一個返回值;
- 儲存過程一般獨立的來執行;而函式可以作為其他SQL語句的組成部分來出現。