預存程序介紹
預存程序是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中。使用者通過指定預存程序的名字並給出參數(如果該預存程序帶有參數)來執行它。預存程序可由應用程式通過一個調用來執行,而且允許使用者聲明變數 。同時,預存程序可以接收和輸出參數、返回執行預存程序的狀態值,也可以嵌套調用。
預存程序的優點
作為預存程序,有以下這些優點:
(1)減少網路通訊量。調用一個行數不多的預存程序與直接調用SQL語句的網路通訊量可能不會有很大的差別,可是如果預存程序包含上百行SQL語句,那麼其效能絕對比一條一條的調用SQL語句要高得多。
(2)執行速度更快。預存程序建立的時候,資料庫已經對其進行了一次解析和最佳化。其次,預存程序一旦執行,在記憶體中就會保留一份這個預存程序,這樣下次再執行同樣的預存程序時,可以從記憶體中直接中讀取。
(3)更強的安全性。預存程序是通過向使用者授予許可權(而不是基於表),它們可以提供對特定資料的訪問,提高代碼安全,比如防止 SQL注入。
(4) 商務邏輯可以封裝預存程序中,這樣不僅容易維護,而且執行效率也高
當然預存程序也有一些缺點,比如:
1 可移植性方面:當從一種資料庫遷移到另外一種資料庫時,不少的預存程序的編寫要進行部分修改。
2 預存程序需要花費一定的學習時間去學習,比如學習其文法等。
預存程序學習筆記
Variables 變數
在複合陳述式中聲明變數的指令是DECLARE。
(1) Example with two DECLARE statements
兩個DECLARE語句的例子
| 代碼如下 |
複製代碼 |
CREATE PROCEDURE p8 () BEGIN DECLARE a INT; DECLARE b INT; SET a = 5; SET b = 5; INSERT INTO t VALUES (a); SELECT s1 * a FROM t WHERE s1 >= b; END; // /* I won't CALL this */ |
在過程中定義的變數並不是真正的定義,你只是在BEGIN/END塊內定義了而已(譯註:也就是形參)。
注意這些變數和會話變數不一樣,不能使用修飾符@你必須清楚的在BEGIN/END塊中聲明變數和它們的類型。
變數一旦聲明,你就能在任何能使用會話變數、文字、列名的地方使用。
(2) Example with no DEFAULT clause and SET statement
沒有預設子句和設定語句的例子
| 代碼如下 |
複製代碼 |
CREATE PROCEDURE p9 () BEGIN DECLARE a INT /* there is no DEFAULT clause */; DECLARE b INT /* there is no DEFAULT clause */; SET a = 5; /* there is a SET statement */ SET b = 5; /* there is a SET statement */ INSERT INTO t VALUES (a); SELECT s1 * a FROM t WHERE s1 >= b; END; // /* I won't CALL this */ |
有很多初始設定變數的方法。如果沒有預設的子句,那麼變數的初始值為NULL。你可以在任何時候使用SET語句給變數賦值。
(3) Example with DEFAULT clause
含有DEFAULT子句的例子
| 代碼如下 |
複製代碼 |
CREATE PROCEDURE p10 () BEGIN DECLARE a, b INT DEFAULT 5; INSERT INTO t VALUES (a); SELECT s1 * a FROM t WHERE s1 >= b; END; // |
我們在這裡做了一些改變,但是結果還是一樣的。在這裡使用了DEFAULT子句來設定初始值,這就不需要把DECLARE和SET語句的實現分開了。
(4) Example of CALL
調用的例子
| 代碼如下 |
複製代碼 |
mysql> CALL p10() // +--------+ | s1 * a | +--------+ | 25 | | 25 | +--------+ 2 rows in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) |
結果顯示了過程能正常工作
(5) Scope
範圍
| 代碼如下 |
複製代碼 |
CREATE PROCEDURE p11 () BEGIN DECLARE x1 CHAR(5) DEFAULT 'outer'; BEGIN DECLARE x1 CHAR(5) DEFAULT 'inner'; SELECT x1; END; SELECT x1; END; //
|