1. 程式人生 > >MySQL的儲存過程和函式入門 第一篇

MySQL的儲存過程和函式入門 第一篇

最近開發中用到儲存過程和函式,就順便學習一下了。

1.什麼是儲存過程和函式?

  儲存過程和函式是事先經過編譯並存儲在資料庫的一段SQL語句集合,呼叫儲存過程和函式可以減少資料庫和應用伺服器之間的傳輸,對於提高資料處理的效率是有好處的。

2.儲存過程和函式的區別

  • 函式是必須有返回值的,儲存過程沒有返回值。
  • 儲存過程的引數可以使用IN、OUT、INOUT型別,而函式只能是IN型別的

3.操作儲存過程和函式的許可權:

  • 建立儲存過程和函式,必須有create routine許可權。
  • 修改或者刪除需要有alter routine 許可權
  • 執行需要有execute許可權

建立儲存過程和函式語法

   1)儲存過程的語法

        create procedure sp_name([proc_parameter[,...]])

             [characteristic ...] routine_body

    解釋:

     sp_name:儲存過程的名字

     proc_parameter:儲存過程的引數,[ IN\OUT \ INOUT ] param_name(引數) type (型別)

儲存過程的示例:

CREATE DEFINER=`root`@`::1` PROCEDURE `film_not_in_stock`(IN p_film_id INT, IN p_store_id INT, OUT p_film_count INT)
    READS SQL DATA
BEGIN
     SELECT inventory_id
     FROM inventory
     WHERE film_id = p_film_id
     AND store_id = p_store_id
     AND NOT inventory_in_stock(inventory_id);

     SELECT FOUND_ROWS() INTO p_film_count;
END

  2)函式的語法

    create function sp_name ([func_parameter[,...]])

        returns type

        [characteristic...] routine_body

解釋:

sp_name:函式的名字。

func_parameter:函式的引數型別,param_name,不需要加IN。

 

函式示例:

CREATE DEFINER=`root`@`::1` FUNCTION `inventory_in_stock`(p_inventory_id INT) RETURNS tinyint(1)
    READS SQL DATA
BEGIN
    DECLARE v_rentals INT;
    DECLARE v_out     INT;

    #AN ITEM IS IN-STOCK IF THERE ARE EITHER NO ROWS IN THE rental TABLE
    #FOR THE ITEM OR ALL ROWS HAVE return_date POPULATED

    SELECT COUNT(*) INTO v_rentals
    FROM rental
    WHERE inventory_id = p_inventory_id;

    IF v_rentals = 0 THEN
      RETURN TRUE;
    END IF;

    SELECT COUNT(rental_id) INTO v_out
    FROM inventory LEFT JOIN rental USING(inventory_id)
    WHERE inventory.inventory_id = p_inventory_id
    AND rental.return_date IS NULL;

    IF v_out > 0 THEN
      RETURN FALSE;
    ELSE
      RETURN TRUE;
    END IF;
END

儲存過程和函式中characteristic特徵值說明:

  • language sql:說明下面過程的body是使用sql語言編寫。
  • 【NOT】deterministic: deterministic確定的,即每次輸入一樣輸出也一樣的程式。not  deterministic 非確定的,預設是非確定的。
  • contains sql:表示子程式不包含讀或寫資料的語句。
  • no sql:表示子程式不包含sql語句。
  • reads sql data 表示子程式包含讀資料的語句,但不包含寫資料的語句。
  • modifies sql data :表示子程式包含寫資料的語句。
  • sql security 【definer | invoker】:用來指定子程式該用於建立者許可權來執行,還是呼叫者許可權來執行,預設值的definer。
  • comment ‘string’ :儲存過程或者函式的註釋資訊。

刪除儲存過程或者函式示例

刪除過程film_in_stock

drop procedure film_in_stock;

檢視儲存過程或者函式

儲存過程和函式建立後,使用者可能需要檢視儲存過程、函式的狀態、定義等資訊,便於瞭解儲存過程或者函式的基本情況。

1.檢視儲存過程或者函式的狀態

  show procedure status like 'film_in_stock';

 show procedure status like 'film_in_stock';
+--------+---------------+-----------+----------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db     | Name          | Type      | Definer  | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+--------+---------------+-----------+----------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| sakila | film_in_stock | PROCEDURE | [email protected]::1 | 2018-09-26 21:19:23 | 2018-09-26 21:19:23 | DEFINER       |         | utf8mb4              | utf8mb4_0900_ai_ci   | utf8mb4_0900_ai_ci |
+--------+---------------+-----------+----------+---------------------+---------------------+---------------+---------+----------------------+-----------

2.檢視過程過程或者函式的定義

show create procedure film_in_stock;

show create procedure film_in_stock;
+---------------+-------------------------------------------------------------------------------------------+
| Procedure     | sql_mode                                                                                                                         | Create Procedure                                                                                                                                                                                                                                                                                                                                 | character_set_client | collation_connection | Database Collation |

| film_in_stock | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`::1` PROCEDURE `film_in_stock`(IN p_film_id INT, IN p_store_id INT, OUT p_film_count INT)
    READS SQL DATA
BEGIN
     SELECT inventory_id
     FROM inventory
     WHERE film_id = p_film_id
     AND store_id = p_store_id
     AND inventory_in_stock(inventory_id);

     SELECT FOUND_ROWS() INTO p_film_count;
END | utf8mb4              | utf8mb4_0900_ai_ci   | utf8mb4_0900_ai_ci |