04-儲存過程&函式
阿新 • • 發佈:2020-09-06
儲存過程
概述
過程化 SQL 塊主要有 2 種類型,即命名塊和匿名塊。前面介紹的是匿名塊。匿名塊每次執行時都要進行編譯,它不能被儲存到 DB 中,也不能在其他過程化 SQL 塊中呼叫。過程和函式是命名塊,它們被編譯後儲存在 DB 中,稱為“永續性儲存模組”,可以被反覆呼叫,執行速度較快。
儲存過程是由過程化 SQL 語句書寫的過程,這個過程經過編譯和優化後儲存在 DB 伺服器中,因此稱它為“儲存過程”,使用時只要呼叫即可。
定義
CREATE OR REPLACE PROCEDURE <儲存過程名>([引數1, 引數2, ...]) /* 儲存過程首部 */ BEGIN /* 儲存過程體, 描述該儲存過程的操作, 是一組 SQL 語句 */ END
- 儲存過程包括過程首部和過程體
- 在過程首部,“過程名”是 DB 伺服器合法的物件標識
- 引數列表包含 3 部分:
引數模式 引數名 引數型別
- 舉例:
IN stuName VARCHAR(20)
IN
該引數可作為輸入,呼叫方需要傳入值到該引數中OUT
可作為輸出,也就是過程返回值INOUT
既可以作為輸入,又可以作為輸出
- 舉例:
- 過程體 // 如果只有一句話,
BEGIN...END
可省- 儲存過程體中的每條 SQL 語句的結尾要求必須加
;
- 儲存過程的結尾可以使用
DELIMITER
重新設定
- 儲存過程體中的每條 SQL 語句的結尾要求必須加
操作
- 執行儲存過程:
CALL <過程名>(實參列表);
- 刪除儲存過程:
DROP PROCEDURE <過程名>;
- 檢視儲存過程:
SHOW CREATE PROCEDURE <過程名>;
案例
- [無參] 插入到 admin 表中 5 條記錄
- [帶 IN 模式] 建立過程實現根據 beauty.name 查詢對應的 boy 資訊
CREATE PROCEDURE myPro2(IN beautyName VARCHAR(20)) BEGIN SELECT bo.* FROM boys bo RIGHT JOIN beauty b ON bo.id = b.boyfriend_id WHERE b.name = beautyName; END $
- [帶 IN 模式] 建立過程實現使用者是否登入成功
CREATE PROCEDURE myPro3(IN username VARCHAR(20), IN password VARCHAR(20)) BEGIN DECLARE result INT DEFAULT 0; # 宣告並初始化 SELECT COUNT(*) INTO result # 賦值 FROM admin WHERE admin.username = username AND admin.password = password; SELECT IF(result>0, '成功', '失敗'); # 使用 END $
- [帶 OUT 模式] 根據 beauty.name,返回對應的 boy.boyName
- [帶 OUT 模式] 根據 beauty.name,返回對應的 boy.id 和 boy.boyName
CREATE PROCEDURE myPro5(IN bName VARCHAR(20), OUT id VARCHAR(20), OUT name VARCHAR(20)) BEGIN SELECT bo.id, bo.boyName INTO id, name FROM boys bo INNER JOIN beauty b ON bo.id = b.boyfriend_id WHERE b.name = bName; END $
- [帶 INOUT 模式] 傳入 a 和 b 兩個變數,呼叫過程後,a 和 b 的值翻倍
- 建立過程實現傳入一個日期,格式化成:xx 年 xx 月 xx 日並返回
CREATE PROCEDURE myPro7(IN myDate DATETIME, OUT dateStr VARCHAR(30)) BEGIN SELECT DATE_FORMAT(myDate, '%y 年 %m 月 %d 日') INTO strDate; END $
- 建立過程實現傳入 beauty.name,返回:'beauty.name and boys.name' 格式的字串
CREATE PROCEDURE myPro8(IN beautyName VARCHAR(20), OUT result VARCHAR(20)) BEGIN SELECT CONCAT(beautyName, ' and ', IFNULL(boyName, 'NULL')) INTO result FROM boys bo RIGHT JOIN beauty b ON bo.id = b.boyfriend_id WHERE b.name = beautyName; END $
- 建立過程實現根據傳入的條目數和起始索引,查詢 beauty 表的記錄
CREATE PROCEDURE myPro8(IN startIndex INT, IN size INT) BEGIN SELECT * FROM beauty LIMIT startIndex, size; END $
函式
函式也稱為”自定義函式“,因為是使用者自己使用過程化 SQL 設計定義的。函式和儲存過程類似,都是永續性儲存模組。函式的定義和儲存過程也類似,不同之處是函式必須指定返回的型別。
- 儲存過程:可以有 0 個返回,也可以有多個返回,適合做批量插入,批量更新
- 函式:有且只有 1 個返回,適合做處理資料後返回一個結果
定義
CREATE FUNCTION <函式名>([引數名 引數型別 ...]) RETURNS <型別>
BEGIN
/* 函式體 */
return 值;
END $
操作
- 呼叫函式:
SELECT 函式名(引數列表)
- 刪除函式:
DROP FUNCTION <函式名>
- 檢視函式:
SHOW CREATE FUNCTION <函式名>
案例
- [無參有返回值] 返回 beauty 表記錄數
- [有參有返回] 根據員工名,返回他的工資
CREATE FUNCTION func2(empName VARCHAR(20)) RETURNS DOUBLE BEGIN SET @sal=0; # 定義使用者變數 SELECT salary INTO @sal FROM employees WHERE last_name = empName; RETURN @sal; END $
- 根據部門名返回該部門的平均工資
CREATE FUNCTION func3(deptName VARCHAR(20)) RETURNS DOUBLE BEGIN DECLARE avgSal DOUBLE; SELECT AVG(salary) INTO avgSal FROM employees e RIGHT JOIN departments d ON e.department_id = d.department_id WHERE d.department_name = deptName; RETURN avgSal; END $
- 建立函式,傳入兩個 float,返回二者之和
CREATE FUNCTION func4(num1 FLOAT, num2 FLOAT) RETURNS FLOAT BEGIN DECLARE sum FLOAT DEFAULT 0; SET sum = num1 + num2; RETURN sum; END $