?????作者名稱:DaenCode
??作者簡介:啥技術(shù)都喜歡搗鼓搗鼓,喜歡分享技術(shù)、經(jīng)驗、生活。
??人生感悟:嘗盡人生百味,方知世間冷暖。
??所屬專欄:重溫MySQL
??前言
MySQL存儲過程作為一種服務(wù)器端的數(shù)據(jù)庫編程方式
,提供了高效、可重用的方法來執(zhí)行相對復(fù)雜的數(shù)據(jù)庫操作。本篇文章主要針對初學(xué)者,展開對MySQL存儲過程的講解,幫助MySQL初學(xué)者能夠更好的學(xué)習(xí)。
??存儲過程介紹
定義:
存儲過程是一組
預(yù)定義的SQL語句集合
,被存儲在數(shù)據(jù)庫中,以便復(fù)用和調(diào)用。它們可以接收參數(shù)、執(zhí)行邏輯判斷、進行循環(huán)和異常處理,并返回結(jié)果。存儲過程在數(shù)據(jù)庫服務(wù)器上執(zhí)行,減少了網(wǎng)絡(luò)傳輸?shù)拈_銷,提升了性能。
MySQL存儲過程支持常見的編程結(jié)構(gòu)
,如條件語句(IF-ELSE、CASE)、循環(huán)(WHILE、LOOP)和異常處理(TRY-CATCH)。除了基本的SQL語句,還可以通過使用變量、游標和臨時表等特性,實現(xiàn)更復(fù)雜的操作和邏輯。
優(yōu)勢:
提高性能:存儲過程
在數(shù)據(jù)庫服務(wù)器上執(zhí)行,減少了與客戶端的數(shù)據(jù)傳輸,降低了網(wǎng)絡(luò)開銷
,從而提高了性能。此外,存儲過程可以被編譯和優(yōu)化,減少了重復(fù)代碼的冗余,進一步提升了查詢執(zhí)行效率。
簡化復(fù)雜的查詢:對于復(fù)雜的查詢或需要按特定順序執(zhí)行的多個查詢,存儲過程提供了一種簡潔、可重用的解決方案。通過將邏輯封裝在存儲過程中,可以減少應(yīng)用程序中的SQL代碼量,使數(shù)據(jù)庫邏輯更清晰、易于維護
。
增強安全性:存儲過程可以設(shè)置為只能由特定用戶或角色調(diào)用
,從而增強了對數(shù)據(jù)庫的安全性。
減輕客戶端負擔(dān):將復(fù)雜的業(yè)務(wù)邏輯放在存儲過程中,可以減輕客戶端的負擔(dān)
??蛻舳酥恍枵{(diào)用相應(yīng)的存儲過程,而無需編寫冗長的SQL語句和處理復(fù)雜的結(jié)果集,簡化了應(yīng)用程序的開發(fā)和維護。
劣勢:
可移植性較差:
存儲過程在不同的數(shù)據(jù)庫系統(tǒng)之間的語法和特性可能存在差異
,這導(dǎo)致了存儲過程的可移植性較差。如果需要將應(yīng)用程序遷移到另一個數(shù)據(jù)庫系統(tǒng),可能需要對存儲過程進行調(diào)整和修改。
難以調(diào)試和維護:存儲過程的調(diào)試和維護相對復(fù)雜。由于存儲過程在數(shù)據(jù)庫服務(wù)器上執(zhí)行,無法像客戶端應(yīng)用程序那樣方便地進行調(diào)試
。此外,存儲過程的邏輯可能分散在多個存儲過程中
,增加了維護的難度。
??存儲過程基本語法
創(chuàng)建:相當于Java中定義方法
CREATE [DEFINER = {user | CURRENT_USER}] PROCEDURE procedure_name ([parameter_list])
[characteristic ...]
BEGIN
DECLARE variable_name data_type; -- 聲明變量
-- 存儲過程的邏輯代碼
END;
DEFINER:可選項,
創(chuàng)建存儲過程的用戶
??梢灾付ň唧w的用戶名,或使用CURRENT_USER表示當前用戶。
procedure_name:指定存儲過程的名稱
,遵循標識符命名規(guī)則。
parameter_list:可選項,用于指定存儲過程的參數(shù)列表
。參數(shù)由參數(shù)類型和參數(shù)名稱組成,多個參數(shù)之間使用逗號分隔。參數(shù)類型可以是IN、OUT 或 INOUT
,分別表示輸入?yún)?shù)
、輸出參數(shù)
和既是輸入?yún)?shù)又是輸出參數(shù)
(賦值)。
characteristic:可選項,用于指定存儲過程的特性
。常用特性包括:
- LANGUAGE SQL:表示存儲過程使用 SQL 語言編寫。
- [NOT] DETERMINISTIC:指示存儲過程是否是確定性的,即相同輸入是否總是產(chǎn)生相同的結(jié)果。
- CONTAINS SQL:表示存儲過程包含 SQL 語句。
- NO SQL:表示存儲過程不包含 SQL 語句。
- READS SQL DATA:表示存儲過程只讀取數(shù)據(jù),不修改數(shù)據(jù)。
- MODIFIES SQL DATA:表示存儲過程修改數(shù)據(jù)。
BEGIN和END:定義存儲過程的
邏輯代碼塊的開始和結(jié)束位置
。
DECLARE:用于聲明變量
。在存儲過程的邏輯代碼塊中,可以使用DECLARE語句來聲明變量,指定變量名稱和數(shù)據(jù)類型。
調(diào)用:相當于Java中調(diào)用方法
CALL procedure_name([argument_list]);
CALL:關(guān)鍵字用于調(diào)用存儲過程。
procedure_name:要調(diào)用的存儲過程的名稱
。
argument_list:可選項,用于傳遞給存儲過程的參數(shù)列表
。參數(shù)與存儲過程定義時指定的參數(shù)列表對應(yīng),多個參數(shù)之間使用逗號分隔。如果存儲過程沒有參數(shù),可以省略該部分。
??存儲過程實戰(zhàn)
以下例子,均按下表進行操作
SQL語句:
--創(chuàng)建表
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(255),
age INT,
salary DECIMAL(10, 2)
);
--表中插入數(shù)據(jù)
INSERT INTO employees (id, name, age, salary)
VALUES
(1, '張三', 25, 5000),
(2, '李四', 30, 6000),
(3, '王五', 35, 7000),
(4, '趙六', 40, 8000),
(5, '錢七', 45, 9000);
無參數(shù)列表存儲過程
此存儲過程名為getAllEmployees。它將從employees表中檢索所有的員工記錄并返回結(jié)果集。
CREATE PROCEDURE getAllEmployees()
BEGIN
SELECT * FROM employees;
END;
調(diào)用存儲過程進行檢驗
CALL getAllEmployees();
檢驗結(jié)果:
帶參數(shù)列表存儲過程
此存儲過程名為getEmployeeById,它接受一個輸入?yún)?shù)empId,通過這個參數(shù)來查詢與給定id相匹配的員工記錄。
CREATE PROCEDURE getEmployeeById(IN empId INT)
BEGIN
SELECT * FROM employees WHERE id = empId;
END;
調(diào)用存儲過程進行檢驗
CALL getEmployeeById(2);
檢驗結(jié)果
帶流程控制語句IF ELSE存儲過程
此存儲過程名為getEmployeeSalaryGrade,它接受一個輸入?yún)?shù)empId,根據(jù)員工的薪水確定員工的薪資等級。根據(jù)不同的薪水范圍,將員工的薪資等級分為"低級"、“中級"和"高級”。
CREATE PROCEDURE getEmployeeSalaryGrade(IN empId INT)
BEGIN
DECLARE empSalary DECIMAL(10, 2);
DECLARE empGrade VARCHAR(10);
SELECT salary INTO empSalary FROM employees WHERE id = empId;
IF empSalary < 5000 THEN
SET empGrade = '低級';
ELSEIF empSalary >= 5000 AND empSalary < 8000 THEN
SET empGrade = '中級';
ELSE
SET empGrade = '高級';
END IF;
SELECT empGrade AS grade;
END;
調(diào)用存儲過程進行檢驗
call getEmployeeSalaryGrade(3)
檢驗結(jié)果
帶條件控制語句CASE存儲過程
此存儲過程名為categorizeEmployee,它根據(jù)員工的姓名確定員工的職位。
CREATE PROCEDURE categorizeEmployee()
BEGIN
SELECT id, name,
CASE
WHEN name = '張三' THEN '管理人員'
WHEN name = '李四' THEN '管理人員'
ELSE '普通員工'
END AS category
FROM employees;
END;
調(diào)用存儲過程進行檢驗
call categorizeEmployee()
檢驗結(jié)果
帶循環(huán)語句WHILE存儲過程
此存儲過程名為 IncreaseSalary,它會遍歷 employees 表中的每個員工,并將他們的薪水增加 10%。
CREATE PROCEDURE IncreaseSalary()
BEGIN
DECLARE emp_count INT;
DECLARE i INT DEFAULT 0;
DECLARE emp_id INT;
DECLARE emp_salary DECIMAL(10, 2);
-- 獲取員工數(shù)量
SELECT COUNT(*) INTO emp_count FROM employees;
-- 循環(huán)遍歷并更新薪水
WHILE i < emp_count DO
SET i = i + 1;
-- 獲取當前員工的id和薪水
SELECT id, salary INTO emp_id, emp_salary FROM employees WHERE id = i;
-- 對薪水進行增加
UPDATE employees SET salary = emp_salary * 1.1 WHERE id = emp_id;
END WHILE;
END;
調(diào)用存儲過程進行檢驗
CALL IncreaseSalary();
檢驗結(jié)果原來薪水
當前薪水
帶循環(huán)語句REPEAT UNTIL存儲過程
此存儲過程名為 DisplayEmployeesWithRepeatUntil,它會使用 REPEAT…UNTIL 循環(huán)遍歷 employees 表中的每個員工,并輸出他們的信息。
DELIMITER $$
CREATE PROCEDURE DisplayEmployeesWithRepeatUntil()
BEGIN
--聲明變量
DECLARE emp_count INT;--員工數(shù)量
DECLARE i INT DEFAULT 1;
DECLARE emp_id INT;
DECLARE emp_name VARCHAR(50);
DECLARE emp_age INT;
DECLARE emp_salary DECIMAL(10, 2);
-- 獲取員工數(shù)量
SELECT COUNT(*) INTO emp_count FROM employees;
-- 循環(huán)遍歷并輸出員工信息
REPEAT
-- 獲取當前員工信息
SELECT id, name, age, salary INTO emp_id, emp_name, emp_age, emp_salary FROM employees WHERE id = i;
-- 輸出員工信息
SELECT CONCAT('ID: ', emp_id, ', Name: ', emp_name, ', Age: ', emp_age, ', Salary: ', emp_salary) AS employee_info;
SET i = i + 1;
UNTIL i > emp_count END REPEAT;
END$$
DELIMITER ;
調(diào)用存儲過程進行檢驗
CALL DisplayEmployeesWithRepeatUntil();
檢驗結(jié)果
帶循環(huán)語句LOOP存儲過程
此存儲過程名為 DisplayEmployeesWithLoop,它會使用LOOP循環(huán)遍歷 employees 表中的每個員工,并輸出他們的信息。
CREATE PROCEDURE DisplayEmployeesWithLoop()
BEGIN
DECLARE emp_count INT;
DECLARE i INT DEFAULT 1;
DECLARE emp_id INT;
DECLARE emp_name VARCHAR(50);
DECLARE emp_age INT;
DECLARE emp_salary DECIMAL(10, 2);
-- 獲取員工數(shù)量
SELECT COUNT(*) INTO emp_count FROM employees;
-- 循環(huán)遍歷并輸出員工信息
emp_loop: LOOP
-- 獲取當前員工信息
SELECT id, name, age, salary INTO emp_id, emp_name, emp_age, emp_salary FROM employees WHERE id = i;
-- 輸出員工信息
SELECT CONCAT('ID: ', emp_id, ', Name: ', emp_name, ', Age: ', emp_age, ', Salary: ', emp_salary) AS employee_info;
SET i = i + 1;
IF i > emp_count THEN
LEAVE emp_loop;
END IF;
END LOOP;
END;
調(diào)用存儲過程檢驗
CALL DisplayEmployeesWithLoop();
檢驗結(jié)果
查詢存儲過程
--查詢所有數(shù)據(jù)庫
SHOW PROCEDURE STATUS;
--查詢指定數(shù)據(jù)庫test。以上所有例子都基于test數(shù)據(jù)庫
SHOW PROCEDURE STATUS WHERE db='test'
結(jié)果
查詢存儲過程定義源碼
SHOW CREATE PROCEDURE 存儲過程名;
SHOW CREATE PROCEDURE categorizeEmployee;
結(jié)果
刪除存儲過程
DROP PROCEDURE 存儲過程名;
??寫在最后
最后感謝大家對于此博文的閱讀,如對存儲過程有補充或者疑問之處,請大家在評論區(qū)留言。感謝大家的指正與點評。文章來源:http://www.zghlxwxcb.cn/news/detail-607815.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-607815.html
到了這里,關(guān)于【MySQL】探索MySQL存儲過程的魔力,初學(xué)者的數(shù)據(jù)庫編程秘笈(內(nèi)含實戰(zhàn)SQL腳本)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!