資料庫系統學習筆記--函式和儲存過程
目錄
函式
函式的意義就在於完成特定的功能,寫一份函式,可以在多個語句中多次使用,簡化程式設計工作。
資料庫系統中的函式大致也可以分為內建函式和自定義函式(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語句集,經編譯後儲存在資料庫中,使用者通過指定儲存過程的名字並給定引數(如果該儲存過程帶有引數)來呼叫執行它,由於可以像通用程式語言那樣使用各種控制語句,因此使用儲存過程可以實現比較複雜的業務邏輯。
儲存過程的優點:
- 執行效率高:為儲存過程是預編譯的,在建立好儲存過程後,第一次執行一個儲存過程時,優化器對其進行分析優化,並且給出最終被儲存在系統表中的執行計劃,所以相對於執行多條SQL語句,儲存過程執行效率也更高。
- 標準組件式程式設計:儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句,增強了程式碼複用性。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。
- 減少網路流量:針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的SQL語句被寫成儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大減少網路流量並降低了網路負載。
- 安全可控性:通過對執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。
自定義函式和儲存過程的區別
前面討論的函式和儲存過程非常類似,但它們之間還是有以下區別:
- 儲存過程實現的過程複雜一些,而函式的針對性更強,或者說函式一般用於完成某個特定的運算,而儲存過程往往包含了更為複雜的業務邏輯,作為較為獨立的業務功能。
- 儲存過程可以有多個返回值,而自定義函式只有一個返回值。
- 儲存過程一般獨立的執行,自定義函式往往包含在SQL語句中使用。