8-1 課程回顧
8-2 存儲過程簡介
1、MySQL執行流程,通過存儲過程,可以避免重複語法分和編譯,提高執行效率
2、存儲過程:
(1)是SQL語句與控制語句的【預編譯集合】,以【一個名稱存儲】作爲【一個單元處理】
(2)優點:
- 增強了語句的功能和靈活性:可以通過控制語句對流程進行控制和判斷
- 實現較快的執行速度,只在【第一次調用時進行語法分析和編譯】 ,以後直接從內存中得到結果
- 減少網絡流量
8-3 存儲過程語法結構解析
1、存儲過程語法結構分析
CREATE [DEFINER = {user|CURRENT_USER}]//定義時的用戶,若是不寫就默認爲當前用戶
PROCEDURE sp_name ([proc_parameter[,...]]) //可以帶0到多個參數 sp_name存儲過程的名字
[characteristic ...] routine_body
其中參數
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.過程體
(1)過程體由合法的SQL語句構成;
(2)過程體可以是任意SQL語句;對錶格進行增刪,連接,但是不能創建數據表
(3)過程體如果爲複合結構則使用BEGIN...END語句
(4)複合結構可以使用條件、循環等控制語句
8-4 創建不帶參數的存儲過程
1.創建沒有參數的存儲過程
CREATE PROCEDURE sp1() SELECT VERSION();
2.調用存儲過程
CALL sp_name([parameter[,...]]) - 帶參數的存儲過程的調用
CALL sp_name[()] - 不帶參數的存儲過程調用
CALL sp1;
CALL sp1();
8-5 創建帶有IN類型參數的存儲過程
1.創建帶有INT類型參數的存儲過程
DESC users; DELIMITER //
CREATE PROCEDURE removeUserByID(IN id INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id = id;
END
//
錯誤!!!編譯器無法識別兩個id的不同!
DELIMITER ;
CALL removeUserById(3); //參數名稱最好不要和表中的字段相同
SELECT * FROM users; //全刪除了
DELIMITER //
CREATE PROCEDURE removeUserById(IN p_id INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id = p_id;
END
//
DELIMITER ;
SELECT * FROM users;
CALL removeUserById(22);
SELECT * FROM users WHERE id = 22;
2.修改存儲過程
ALTER PROCEDURE sp_name [characteristic]
COMMENT 'string'
|{CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL DATA} |SQL SECURITY{DEFINER|INVOKER}
3.刪除存儲過程
DROP PROCEDURE [IF EXISTS] sp_name;
DROP removeUserById;
8-6 創建帶有IN和OUT類型參數的存儲過程
創建帶有IN OUT類型參數的存儲過程
DELIMITER //
CREATE PROCEDURE removerUserAndReturnUserName(IN showID INT UNSIGNED,OUT showName INT UNSIGNED)
BEGIN
DELETE FROM user WHERE id = showID;
SELECT count(ID) FROM user INTO showName;
END
//
SELECT count(ID) FROM user INTO showName; /** 該語句中的 INTO 含義就是將 SELECT 語句結果的表達式返回到 showName 變量中 */
CALL removerUserAndReturnUserName(10,@nums); /** @nums 所代表的就是用戶變量,可用 SELECT @nums 輸出 */
用 DECLARE 聲明的變量是局部變量,局部變量只能存在於 BEGIN...END 之間,且聲明時必須置於 BEGIN...END 的第一行
而通過 SELECT...INTO.../SET @id = 07 這種方法設置的變量我們稱之爲用戶變量,只能存在於當前用戶所使用的客戶端有效。
CALL rmUserAndRtUserNums(27, @nums);
SELECT @nums; //@nums - 就是用戶變量 DECLARE聲明的變量都是在BEGIN與END之間,是局部變量
SET @i = 7; //通過@或SET設置的變量稱爲用戶變量
8-7 創建帶有多個OUT類型參數的存儲過程
1.明確什麼是OUT類型的參數,有什麼作用?
OUT類型參數,表示在調用存儲過程時,該參數的值可以被存儲過程改變,並且返回一個值。通常是這種類型時,調用時寫入的參數都是變量用“@”符號開頭的變量,在BEGIN和END之中的變量是局部變量,在調用存儲過程時寫入的變量是“用戶變量”,比如有一個存儲過程的名稱叫做“addUser()”,調用時addUser(@sum),sum就是用戶變量。
2.ROW_COUNT()函數就相當於PHP的MySQL函數庫中的mysql_affected_rows()這個函數,兩者的作用都是相同的,都是計算當插入記錄和修改記錄、以及添加和刪除記錄時的個數總和的。
3.例子:
SELECT ROW_COUNT() INTO delete_User ;是指調用ROW_COUNT()這個函數,並且把返回值存儲在delete_User這個局部變量中。
SELECT COUNT(id) FROM users INTO remain_User ;是指在刪除用戶後,調用COUNT()函數對剩下的用戶數做一個統計,在哪張表中要說明清楚,然後把返回值存儲在remain_User這個局部變量中。
【因爲delete_User和remain_User是OUT類型的參數,所以會返回一個值給調用時的用戶變量,用"SELECT @a,@b"可以知道返回的值是多少了】
8-8 存儲過程與自定義函數的區別
- 存儲過程實現的功能相對複雜,函數針對性較強
- 存儲過程可以返回多個值,函數只能有一個返回值
- 存儲過程一般獨立執行,函數可以作爲 sql 語句的組成部分來出現
修改存儲過程
alter procedure sp_name [characteristic ...]
comment 'string'
| {contains sql | no sql | reads sql data | modifies sql data} | sql security {definer | invoker} 存儲過程只能修改簡單的特性,並不能修改過程體
刪除存儲過程
DROP PROCEDURE [IF EXISTS] sp_name;