1. 程式人生 > >資料庫系統學習筆記--函式和儲存過程

資料庫系統學習筆記--函式和儲存過程

目錄

 

函式

自定義函式

基本語法

控制語句

儲存過程

自定義函式和儲存過程的區別


函式

函式的意義就在於完成特定的功能,寫一份函式,可以在多個語句中多次使用,簡化程式設計工作。

資料庫系統中的函式大致也可以分為內建函式和自定義函式(UDF),內建函式比如count,sum等等,自定義函式比較靈活。

本文demo所用的資料庫版本:MySQL8.0.13,樣本資料來自《資料庫系統概念》這本書的官網:http://db-book.com/

參考:https://www.cnblogs.com/caoruiy/p/4485273.html

自定義函式

基本語法

--建立UDF:
    CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name type,...])
    RETURNS {STRING|INTEGER|REAL}
    BEGIN  
      runtime_body --如果函式體有多條語句,放在BEGIN..END中,單條語句不需要BEGIN...END
    END

--刪除UDF:
  DROP FUNCTION function_name

--呼叫UDF:
  SELECT function_name(parameter_value,...)

note:UDF可以有多個引數或者沒有引數,但是必須有且僅有一個返回值。

Demo

建立函式:給定系的名稱,返回該系的教師人數。

  1 DELIMITER //  --修改預設結束符分號
  2 DROP FUNCTION IF EXISTS dept_count;  --如果函式存在先進行刪除
  3 CREATE FUNCTION dept_count(dept_name VARCHAR(20))
  4   RETURNS INTEGER  --宣告返回型別
  5 BEGIN
  6   DECLARE tmp_count,d_count INTEGER DEFAULT 0; --這些變數的作用範圍是在BEGIN...END程式中,而且定義區域性變數語句必須在BEGIN...END的第一行定義
  7   SELECT count(*) INTO tmp_count from instructor where instructor.dept_name = dept_name;
  8   SET d_count = tmp_count; --這裡tmp_count是多餘的,只是演示一下SET的用法
  9   RETURN d_count;
 10 END//
 11 DELIMITER ;  --恢復預設結束符分號

使用dept_count函式

mysql> select dept_count('Biology');
+-----------------------+
| dept_count('Biology') |
+-----------------------+
|                     2 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select distinct dept_name, dept_count(dept_name) from instructor;
+------------+-----------------------+
| dept_name  | dept_count(dept_name) |
+------------+-----------------------+
| Biology    |                     2 |
| Comp. Sci. |                     4 |
| Elec. Eng. |                     1 |
| Finance    |                     3 |
| History    |                     2 |
| Music      |                     1 |
| Physics    |                     2 |
+------------+-----------------------+
mysql> select distinct dept_name, dept_count(dept_name) from instructor where dept_count(dept_name) > 2;
+------------+-----------------------+
| dept_name  | dept_count(dept_name) |
+------------+-----------------------+
| Comp. Sci. |                     4 |
| Finance    |                     3 |
+------------+-----------------------+

控制語句

資料庫系統也支援和通用程式語言類似的各種控制語句,MySQL中可以使用IF語句、CASE語句、LOOP語句、LEAVE語句、ITERATE語句、REPEAT語句和WHILE語句來進行流程控制,在自定義函式中也可以使用這些語句。

IF語句

IF search_condition THEN statement_list --statement_list就是不同條件下的執行語句
[ELSEIF search_condition THEN statement_list] ... 
[ELSE statement_list] 
END IF
  1 DELIMITER //
  2 DROP FUNCTION IF EXISTS dept_count;
  3 CREATE FUNCTION dept_count(dept_name VARCHAR(20))
  4   RETURNS INTEGER
  5 BEGIN
  6   DECLARE tmp_count, d_count INTEGER DEFAULT 0;
  7   SELECT count(*) INTO tmp_count from instructor where instructor.dept_name = dept_nam    e;
  8   IF tmp_count = 0 THEN SET d_count = 100;
  9   ELSE SET d_count = tmp_count;
 10   END IF;
 11   RETURN d_count;
 12 END//
 13 DELIMITER ;
mysql> select dept_count('Math'); --樣本資料中沒有Math這個系
+--------------------+
| dept_count('Math') |
+--------------------+
|                100 |
+--------------------+

CASE語句

CASE語句和IF語句也用來處理一些條件判斷,和IF語句類似。

CASE case_value 
WHEN when_value THEN statement_list 
[WHEN when_value THEN statement_list] ... 
[ELSE statement_list] 
END CASE 

LOOP語句

LOOP語句可以實現迴圈條件執行。LOOP語句如果不用LEAVE等語句來控制退出條件,就會死迴圈執行下去,類似於通用程式語言中不帶控制條件的for迴圈語句。

[begin_label:] LOOP 
statement_list 
END LOOP [end_label] 
  1 DELIMITER //
  2 DROP FUNCTION IF EXISTS loop_100;
  3 CREATE FUNCTION loop_100()
  4   RETURNS INTEGER
  5 BEGIN
  6   DECLARE result INTEGER DEFAULT 0;
  7   loop_100: LOOP
  8     SET result=result + 1;
  9     IF result=100 THEN LEAVE loop_100; --滿足條件,用LEAVE跳出迴圈
 10     END IF;
 11   END LOOP loop_100;
 12   RETURN result;
 13 END//
 14 DELIMITER ;
mysql> select loop_100();
+------------+
| loop_100() |
+------------+
|        100 |
+------------+
1 row in set (0.00 sec)

LEAVE語句

LEAVE語句主要用於跳出迴圈控制,在LOOP語句的demo中已經演示。

LEAVE label 

ITERATE語句

ITERATE語句也是用來跳出迴圈的語句。但是,ITERATE語句是跳出本次迴圈,然後直接進入下一次迴圈,類似於通用程式語言中的continue語句。

TERATE語句只可以出現在LOOP、REPEAT、WHILE語句內。

ITERATE label 

REPEAT語句

REPEAT語句是有條件控制的迴圈語句。當滿足特定條件時,就會跳出迴圈語句,類似於設定了退出條件的for迴圈語句。REPEAT語句的基本語法形式如下:

[begin_label:] REPEAT 
statement_list 
UNTIL search_condition 
END REPEAT [end_label]

WHILE語句

WHILE語句也是有條件控制的迴圈語句。但WHILE語句和REPEAT語句是不一樣的。

WHILE語句是當滿足條件時,執行迴圈內的語句。

[begin_label:] WHILE search_condition DO 
statement_list 
END WHILE [end_label] 
  1 DELIMITER //
  2 DROP FUNCTION IF EXISTS while_100;
  3 CREATE FUNCTION while_100()
  4   RETURNS INTEGER
  5 BEGIN
  6   DECLARE result INTEGER DEFAULT 0;
  7   WHILE result < 100 DO
  8     SET result=result + 1;
  9   END WHILE;
 10   RETURN result;
 11 END//
 12 DELIMITER ;
mysql> select while_100();
+-------------+
| while_100() |
+-------------+
|         100 |
+-------------+
1 row in set (0.00 sec)

儲存過程

        SQL語句需要先編譯然後執行,而儲存過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中,使用者通過指定儲存過程的名字並給定引數(如果該儲存過程帶有引數)來呼叫執行它,由於可以像通用程式語言那樣使用各種控制語句,因此使用儲存過程可以實現比較複雜的業務邏輯。

儲存過程的優點:

  1. 執行效率高:為儲存過程是預編譯的,在建立好儲存過程後,第一次執行一個儲存過程時,優化器對其進行分析優化,並且給出最終被儲存在系統表中的執行計劃,所以相對於執行多條SQL語句,儲存過程執行效率也更高。
  2. 標準組件式程式設計:儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句,增強了程式碼複用性。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。
  3. 減少網路流量:針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的SQL語句被寫成儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大減少網路流量並降低了網路負載。
  4. 安全可控性:通過對執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。

自定義函式和儲存過程的區別

前面討論的函式和儲存過程非常類似,但它們之間還是有以下區別:

  1. 儲存過程實現的過程複雜一些,而函式的針對性更強,或者說函式一般用於完成某個特定的運算,而儲存過程往往包含了更為複雜的業務邏輯,作為較為獨立的業務功能。
  2. 儲存過程可以有多個返回值,而自定義函式只有一個返回值。
  3. 儲存過程一般獨立的執行,自定義函式往往包含在SQL語句中使用。