《Mysql數據庫基礎之存儲過程》

在平時的開發過程中,經常會對數據表進行插入、刪除、更新、查找等操作。
Mysql命令執行流程:
這裏寫圖片描述
如果我們可以將這個過程簡化一下,省略語法分析和編譯環節,那麼Mysql 的執行效率就會提高,實現這個就需要用到存儲過程

存儲過程

  • 存儲過程是SQL語句和控制語句的預編譯集合,以一個名稱存儲並作爲一個單元處理
  • 存儲過程存儲在數據庫內,可以由應用程序調用執行,而且允許用戶聲明變量,以及進行流程控制
  • 存儲過程可以接收參數,可以接收輸入和輸出類型的參數,並且可以存在多個返回值

從存儲引擎的介紹裏邊就可以看出來,存儲引擎的執行效率要比一般到的SQL語句執行效率要高。比如我們要寫兩個SQL語句,mysql的引擎會對這兩個SQL語句逐一進行語法分析、編譯、執行。使用存儲過程以後,只在第一次進行語法分析和編譯,之後客戶端再調用,直接就調用編譯結果,也就是省略了其中的語法分析和編譯兩個環節,效率要高。

存儲過程優點:

  1. 增強了SQL語句的功能和靈活性。因爲在存儲過程內可以寫控制語句,所以有很強的靈活性,可以完成複雜的判斷以及較複雜的運算
  2. 實現了較快的執行速度。如果某一個操作包含大量的SQL語句,那麼這些語句都會被mysql的引擎進行語法分析及編譯等操作,所以效率相對較低,而存儲過程是預編譯的,當客戶端第一次調用某個存儲過程的時候,mysql的引擎將對它進行語法分析和編譯等操作,然後將編譯結果存儲到內存中,所以,第一次是和SQL相同的,但是以後,客戶端再次調用該存儲過程時,就直接從內存當中來執行,所以效率高、速度快。
  3. 減少網絡流量。如果通過客戶端,每個單獨發送SQL語句讓服務器來執行的話, 那麼通過http協議所提交的數據量相對較大,假設現在需要刪除users表中id爲3的記錄,那麼我們要執行的就是 delete from
    users where id=3
    這裏邊最少30個字符,如果我們將其存儲爲存儲過程delete_user,我們只需要調用這存儲過程,將id傳過去就可以完成,所以這樣提交給服務器的數據量相對較少

創建存儲過程:

CREATE
[DEFINER = {user | CURRENT_USER}]  //值得是創建者,如果省略則默認是當前登錄的用戶
PROCEDURE sp_name([proc_parameter[,.....]])//sp_name是存儲過程的名字,可以有0個或多個參數  參數的前邊可以有三個選項,分別是IN OUT INOUT
[characteristic ...] routine_body

proc_parameter:
[IN | OUT | INOUT] param_name type

IN:表示該參數的值必須在調用存儲過程時指定,在存儲過程中這個值是不能被返回的
OUT:表示該參數的值可以被存儲過程改變,並且可以返回
INOUT:表示該參數在調用時指定,並且可以被改變和返回

過程體:
1,由合法的SQL語句構成
2,可以是“任意”的SQL語句//不能通過存儲過程來創建數據表和數據庫
3,過程體如果爲複合結構則用BEGIN.....END語句
4,符合語句內可以包含聲明,循環,控制結構
創建一個沒有參數的存儲過程:(獲取當前mysql版本功能)
create procedure sp1()
select version();

存儲過程的調用:
CALL sp_name([parameter,[....]])
CALL sp_name[()]//表示沒有參數時,可以不帶小括號

這裏寫圖片描述

帶有IN類型參數的存儲過程
DELIMITER //        修改定界符
CREATE PROCEDURE delUserById(IN id INT UNSIGNED)
BEGIN
delete from shulv_user where id = id;
END
//
DELIMITER ;

這裏寫圖片描述
會發現全部被刪除了,因爲需要注意,參數的名和字段的名字不能寫一樣,因爲數據庫會把他們兩個都當成字段

刪除存儲過程:

DROP PROCEDURE [IF EXISTS] sp_name

創建帶有IN和OUT類型參數的存儲過程

下邊是通過存儲過程來實現刪除shulv_user表中id不固定的記錄並返回剩餘的記錄數
DELIMITER //        修改定界符
CREATE PROCEDURE delUserAndReturn(IN p_id INT UNSIGNED, OUT userNumbers INT UNSIGNED)
BEGIN
delete from shulv_user where id = p_id;
select count(id) from shulv_user into userNumbers;
END
//
DELIMITER ;

執行該存儲過程
call delUserAndReturn(4,@nums);   
@nums  表示接收返回值的變量
select @nums;

在mysql的函數中,我們會通過declare來聲明變量,這個是局部變量,它的作用只在beginand之間有效,而且declare語句必須位於第一行。通過這種加@符的變量,我們稱爲用戶變量,用戶變量是和mysql的客戶端綁定的,它是對當前用戶登錄的mysql客戶端生效

這裏寫圖片描述

創建帶有多個OUT類型參數的存儲過程:

根據id刪除用戶,要返回剩餘的用戶數和刪除的用戶用戶數
這裏說一個函數:ROW_COUNT()得到被影響的記錄數(比如插入、刪除、更新的記錄數)

DELIMITER //
create procedure del(IN p_id INT UNSIGNED, OUT del_num INT UNSIGNED, OUT count_num INT UNSIGNED)
BEGIN
DELETE FROM shulv_user where id = p_id;
SELECT ROW_COUNT() INTO del_num;
SELECT COUNT(id) from shulv_user INTO count_num;
END
//

DELIMITER ;

存儲過程與自定義函數的區別:

  • 存儲過程實現的功能要複雜一些,而函數針對性較強
  • 存儲過程可以返回多個值;而函數只能有一個返回值
  • 存儲過程一般獨立的來執行;而函數可以作爲其它SQL語句的組成部分來出現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章