1. 程式人生 > >MySQL基礎知識(六)——儲存過程

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語句的組成部分來出現。