存儲過程的起源
- MySQL是最受歡迎的開源RDBMS,被社區和企業廣泛使用。存儲過程是MySQL在5.0.1(開天闢地一版本)中增加的三大新功能之一,另外兩個師兄弟是視圖與觸發器。均屬於相對“高級”一點的數據庫必需功能。
目錄
一、什麼是存儲過程
存儲過程是存儲在數據庫目錄中的一段聲明性SQL語句。 可以通過觸發器、其他存儲過程以及Java,Python,PHP等應用程序直接調用。
先用一個簡單的查詢語句描述一下存儲過程;
如下是一條SELECT
語句從student表(該表測試數據在實際應用模塊)中返回的所有行:
select ID,SNAME,SEX,AGE,CLASS,GRADE,HOBBY from student ORDER BY SNAME
#查詢結果:
當你使用MySQL Workbench(如Navicat)或mysql shell向MySQL Server發出查詢時,MySQL處理查詢並返回結果集。
如果要將此查詢保存在數據庫服務器上以供以後執行,執行此查詢的一種方法是使用存儲過程。
以下 create procedure 語句創建一個新的存儲過程,用於包裝上面的查詢:
DELIMITER $$
CREATE PROCEDURE GetStudents()
BEGIN
SELECT
ID,SNAME,SEX,AGE,CLASS,GRADE,HOBBY
FROM
student
ORDER BY SNAME;
END$$
DELIMITER ;
存儲過程是存儲在MySQL服務器內部的聲明性SQL語句的一部分。
在此示例中,我們剛剛創建了一個名稱爲的存儲過程GetStudents()。
保存存儲過程後,可以使用以下CALL語句調用存儲過程:
CALL GetStudents();
#查詢結果:
如圖,該語句返回與查詢相同的結果。
- 首次調用存儲過程時,MySQL在數據庫目錄中查找名稱,編譯存儲過程的代碼,將其放置在稱爲緩存的存儲區中,然後執行該存儲過程。
- 如果你在同一會話中再次調用相同的存儲過程,則MySQL將從緩存中執行存儲過程,而無需重新編譯它。
- 存儲過程可以具有參數,因此你可以向其傳遞值並返回結果。
例如,你可以有一個存儲過程,可以按年級和班級返回學生信息數據。在這種情況下,年級和班級是存儲過程的參數。
存儲過程可能包含控制流語句(例如IF、CASE,這些語句LOOP允許你以過程方式實現代碼)。
存儲過程可以調用其他存儲過程或存儲函數,這使你可以調製代碼。
一、MySQL存儲過程的優勢
優點
- 減少網絡流量
存儲過程有助於減少應用程序和MySQL Server之間的網絡流量。因爲應用程序不必發送多個冗長的SQL語句,而僅發送存儲過程的名稱和參數。
- 在數據庫中集中業務邏輯
你可以使用存儲過程來實現可被多個應用程序重用的業務邏輯。存儲過程有助於減少在許多應用程序中重複相同邏輯的工作,並使數據庫更加一致。
- 使數據庫更安全
數據庫管理員可以爲僅訪問特定存儲過程的應用程序授予適當的特權,而無需在基礎表上授予任何特權。
缺點
- 資源使用
如果使用許多存儲過程,則每個連接的內存使用量將大大增加。
此外,由於MySQL的邏輯操作設計不佳,因此在存儲過程中過度使用大量邏輯操作會增加CPU使用率。
- 故障排除
調試存儲過程很困難。不幸的是,MySQL沒有像其他企業數據庫產品(如Oracle和SQL Server)那樣提供任何調試存儲過程的功能。
- 維護成本高
開發和維護存儲過程通常需要並非所有應用程序開發人員都具備的專門技能。這可能會導致應用程序開發和維護方面的問題。
三、實際應用
1. 存儲過程(創建)
存儲過程簡稱過程,procedure,是一種用來處理數據的方式存儲過程是一種沒有返回值的函數
#創建過程語法
Create procedure 過程名字(【參數列表】)
Begin
-- 過程體
End
#創建存儲過程示例
DELIMITER $$
CREATE PROCEDURE GetStudents()
BEGIN
SELECT
ID,SNAME,SEX,AGE,CLASS,GRADE,HOBBY
FROM
student
ORDER BY SNAME;
END$$
DELIMITER ;
2. 存儲過程(查看)
函數的查看方式完全適用於過程,關鍵字換成procedure查看所有過程:
#查詢所有存儲過程
Show procedure status
#模糊匹配
Show procedure status [like 'pattern']
#示例:顯示如下圖
Show procedure status like 'Get%'
# 查看該存儲過程的創建語句
Show create procedure 過程名;
3. 存儲過程(調用)
CALL GetStudents();
4. 存儲過程(修改&刪除)
過程不能直接修改,只能先刪除再新增
Drop procedure 過程名;
5. 存儲過程(參數類型)
函數的參數需要數據類型指定,過程比函數更嚴格
過程有自己的類型限定,三種類型:
- in:數據只是從外部傳入內部使用(值傳遞)可以是數值也可以是變量
- out:只允許過程內部使用(不用外部數據),給外部使用的(引用傳遞,外部的數據會被先清空纔會進入內部),只能是變量
- inout:外部可以在內部使用,內部修改也可以給外部使用,典型的引用傳遞;只能傳變量
基本語法:
Create procedure 過程名(過程類型 形參名字 數據類型 ,…)
-- 過程參數
DELIMITER $$
create procedure demo(in int_1 int,out int_2 int,inout int_3 int)
BEGIN
-- 先查看三個變量
SELECT int_1,int_2,int_3;
END$$
DELIMITER ;
調用:out和inout類型的參數必須傳入 變量,而不能是數值
正確調用:
1.設置變量
2.傳入變量
存儲過程對於變量的操作(返回)是滯後的,是在存儲過程調用結束的時候,次啊會重新將顳部修改的值賦值給外部傳入的全局變量。
-- 過程參數
DELIMITER $$
create procedure pro2(in int_1 int,out int_2 int,inout int_3 int)
BEGIN
-- 先查看三個變量
SELECT int_1,int_2,int_3;
-- 修改局部變量
SET @int_1 = 1;
SET @int_2 = 2;
SET @int_3 = 3;
-- 先查看三個局部變量
SELECT int_1,int_2,int_3;
-- 先查看三個全局變量
SELECT @int_1,@int_2,@int_3;
-- 修改全局變量
SET @int_1 = 'aaa';
SET @int_2 = 'bbb';
SET @int_3 = 'ccc';
-- 先查看三個全局變量
SELECT @int_1,@int_2,@int_3;
END$$
DELIMITER ;
測試:傳入數據1、2、3,說明局部變量與全局變量無關
最後,在存儲過程調用結果結束之後,系統會將局部變量重複返回給全局變量(out和inout)
在存儲過程調用結束之後:out類型和inout類型會將過程內部對應的局部變量的值重新返回給對用的傳入的全局變量。
6. 存儲過程(具體參數解析)
完整創建語法如下:
--------------創建存儲過程-----------------
CREATE PROC [ EDURE ] procedure_name [ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
創建存儲過程的具體參數解析,如下
1. procedure_name :存儲過程的名稱,在前面加#爲局部臨時存儲過程,加##爲全局臨時存儲過程。
2. number:是可選的整數,用來對同名的過程分組,以便用一條 DROP PROCEDURE 語句即可將同組的過程一起除去。例如,名爲 orders 的應用程序使用的過程可以命名爲 orderproc;1、orderproc;2 等。DROP PROCEDURE orderproc 語句將除去整個組。如果名稱中包含定界標識符,則數字不應包含在標識符中,只應在 procedure_name 前後使用適當的定界符。
3. @parameter:存儲過程的參數。可以有一個或多個。用戶必須在執行過程時提供每個所聲明參數的值(除非定義了該參數的默認值)。存儲過程最多可以有 2100 個參數。
使用 @ 符號作爲第一個字符來指定參數名稱。參數名稱必須符合標識符的規則。每個過程的參數僅用於該過程本身;相同的參數名稱可以用在其它過程中。默認情況下,參數只能代替常量,而不能用於代替表名、列名或其它數據庫對象的名稱。有關更多信息,請參見 EXECUTE。
4.data_type:參數的數據類型。所有數據類型(包括 text、ntext 和 image)均可以用作存儲過程的參數。不過,cursor 數據類型只能用於 OUTPUT 參數。如果指定的數據類型爲 cursor,也必須同時指定 VARYING 和 OUTPUT 關鍵字。有關 SQL Server 提供的數據類型及其語法的更多信息,請參見數據類型。
說明 對於可以是 cursor 數據類型的輸出參數,沒有最大數目的限制。
5.VARYING:指定作爲輸出參數支持的結果集(由存儲過程動態構造,內容可以變化)。僅適用於遊標參數。
6.default: 參數的默認值。如果定義了默認值,不必指定該參數的值即可執行過程。默認值必須是常量或 NULL。如果過程將對該參數使用 LIKE 關鍵字,那麼默認值中可以包含通配符(%、_、[] 和 [^])。
7.OUTPUT:表明參數是返回參數。該選項的值可以返回給 EXEC[UTE]。使用 OUTPUT 參數可將信息返回給調用過程。Text、ntext 和 image 參數可用作 OUTPUT 參數。使用 OUTPUT 關鍵字的輸出參數可以是遊標佔位符。
8.RECOMPILE: 表明 SQL Server 不會緩存該過程的計劃,該過程將在運行時重新編譯。在使用非典型值或臨時值而不希望覆蓋緩存在內存中的執行計劃時,請使用 RECOMPILE 選項。
9.ENCRYPTION: 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 語句文本的條目。使用 ENCRYPTION 可防止將過程作爲 SQL Server 複製的一部分發布。 說明在升級過程中,SQL Server 利用存儲在 syscomments 中的加密註釋來重新創建加密過程。
10.FOR REPLICATION:指定不能在訂閱服務器上執行爲複製創建的存儲過程。.使用 FOR REPLICATION 選項創建的存儲過程可用作存儲過程篩選,且只能在複製過程中執行。本選項不能和 WITH RECOMPILE 選項一起使用。
11.AS:指定過程要執行的操作。
12.sql_statement:過程中要包含的任意數目和類型的 Transact-SQL 語句。但有一些限制。