【進階篇第五彈】《詳解存儲過程》從0掌握MySQL中的存儲過程以及存儲函數

文章目錄

  • 存儲過程
  • 一、基本語法
    • (1)創建存儲過程
    • (2)調用存儲過程
    • (3)查看存儲過程
    • (4)刪除存儲過程
    • (5)設置結束符
    • (6)參數
  • 二、變量
    • (1)系統變量
    • (2)用戶自定義變量
    • (3)局部變量
  • 三、基本語句
    • (1)if判斷
    • (2)case
    • (3)while循環
    • (4)repeat
    • (5)loop循環
  • 四、游標
  • 五、條件處理程序
  • 六、存儲函數

存儲過程

概念:

存儲過程時事先編譯并存儲在數據庫中的一段SQL語句的集合。

調用存儲過程可以簡化應用開發人員的很多工作,減少數據在數據庫和應用服務器之間的傳輸,對于提高數據處理的效率是有好處的。

存儲過程思想上很簡單,就是數據庫SQL語言層面的代碼封裝與重用。

特點:

  1. 封裝,復用。
  2. 可以接收參數,也可以返回數據
  3. 減少網絡交互,效率提升

一、基本語法

(1)創建存儲過程

create procedure 存儲過程名稱([參數列表])
begin-- sql語句
end;

(2)調用存儲過程

call 存儲過程名稱([參數列表])

(3)查看存儲過程

-- 查詢指定數據庫的存儲過程及狀態信息
select * from information_schema.routines where routine_schema = 'xxx';-- 查詢某個存儲過程的定義
show create procedure 存儲過程名稱;
  • information_schema.routines:系統視圖,存儲了數據庫中所有存儲過程和函數的元數據。

  • routine_schema = 'xxx':過濾條件,xxx需替換為目標數據庫名稱,用于指定查詢哪個數據庫的存儲過程。

(4)刪除存儲過程

drop procedure [if exists] 存儲過程名稱;l

(5)設置結束符

sql默認的結束符是分號;

但是存儲過程中的SQL語句每一句結束都是分號;

導致存儲過程無法正確執行。

這時候就需要修改結束的語句

delimiter $$

**但是自此以后,所有的sql語句都會需要$$**結束

CREATE PROCEDURE get_student(IN student_id INT)
BEGIN-- 內部SQL語句仍用;結束SELECT * FROM students WHERE id = student_id;SELECT COUNT(*) FROM scores WHERE student_id = student_id;
END $$  -- 這里用$$表示存儲過程定義結束(與修改后的結束符一致)
#改回分號結束
delimiter ;

(6)參數

類型含義備注
in該類參數作為輸入,也就是需要調用時傳入值默認
out該類參數作為輸出,也就是該參數可以作為返回值
inout既可以作為輸入參數,可以作為輸出參數
  1. in/out:

傳值和返回值;

-- 案例
-- 1.根據傳入參數score,判定當前分數對應的分數等級,并返回。
-- score >= 85分,等級為優秀。
-- score >= 60分 且 score < 85分,等級為優秀。
-- score < 60分,等級為優秀。
create procedure p1(in score int,out result varchar(10))
beginif score >= 85 thenset result := '優秀';elseif score >= 60 thenset result := '及格';elseset result := '不及格';end if;
end;call p4(60,@result);

之后 select @result 就是’及格’了

  1. inout:

即將傳入的值進行加工,改變傳入值

-- 案例
-- 2.將傳入的200分制的分數,進行換算,換算成百分制,然后返回分數 ---> inout
create procedure p2(inout score double)
beginset score := score * 0.5;
end;set @score = 200;
call p5(@score);
select @score; -- 輸出為100

二、變量

(1)系統變量

系統變量是MySQL服務器提供,不是用戶定義的,屬于服務器層面。分為全局變量(global)、會話變量(seesion).

1.查看系統變量

不指定,默認選擇session

show [session|global] variables;				-- 查看所有系統變量
show [session|global] variables like '......';	-- 可以通過like模糊匹配方式查找變量,如'auto%'
select @@[session|global].系統變量名;			 -- 查看指定變量的值

2.設置系統變量

設置系統變量后,重啟服務器會重新變為默認值;

如果 不想消失需要在/etc/my.cnf中配置

set [session|global] 系統變量名 =;
set @@[session|global].系統變量名;

(2)用戶自定義變量

? 用戶自定義變量是用戶根據需要自己定義的變量,用戶變量不用提前聲明,在用的時候直接用’@變量名‘使用就可以。其作用域為當前連接。

  • 賦值
set @變量名 =;
set @變量名 :=;select @變量名 :=;
select 字段名 into @變量名 from 表名;
  • 使用
select @變量名;

注意:

用戶定義的變量無需對齊進行聲明或初始化,只不過獲取到的值為NULL。

(3)局部變量

局部變量是根據需要定義在局部生效的變量,訪問之前,需要用declare聲明。可用作存儲過程內的局本變量和輸入參數,局部變量的范圍是在其內聲明的begin…end塊。

  • 聲明
declare 變量名 變量類型[default...];

變量類型就是數據庫字段類型:int、bigint、char、varchar、date、time等

  • 賦值
set 變量名 =;
set 變量名 :=;
select 字段名 into 變量名 from 表名...;
-- 例子
create procedure p1()
begindeclare stu_count int default 0;
end;

三、基本語句

(1)if判斷

1.語法

if 條件1 then.....
elseif 條件2 then  -- 可選.....
else			   -- 可選.....
end if;

2.練習

-- 根據定義的分數score變量,判斷當前分數對應的分數等級。
-- 1.score >= 85分,等級為優秀。
-- 2.score >= 60分 且 score < 85分,等級為優秀。
-- 3.score < 60分,等級為優秀create procedure p1()
begindeclare score int default 58;declare result varchar(10);if score >= 85 thenset result := '優秀';elseif score >= 60 thenset result := '及格';elseset result := '不及格';end if;select resultl;
end;

(2)case

1.語法

  • 語法一
case case_valuewhen when_value then 語句1;[when when_value then 語句2;][else 語句3];
end case;

when條件都不符合,就會進入else。

  • 語法二
casewhen 條件判斷 then 語句1;[when 條件判斷 then 語句2;][else 語句3];
end case;

2.練習

-- 根據傳入的月份,判定月份所屬的季節(要求采用case結構)。
-- 1.1-3月份,為第一季度
-- 2.4-6月份,為第二季度
-- 3.7-9月份,為第三季度
-- 4.10-12月份,為第四季度create procedure p1(in month int)
begindeclare result varchar(10);casewhen month >= 1 and month <= 3 thenset result := '第一季度';when month >= 4 and month <= 6 thenset result := '第二季度';when month >= 7 and month <= 9 thenset result := '第三季度';when month >= 10 and month <= 12 thenset result := '第四季度';elseset result := '非法參數';end case;select concat('您輸入的月份為:',month,'所屬季度為:',result);end

(3)while循環

1.語法

while循環是有條件的循環控制語句。滿足條件后,再執行循環體中的SQL語句。

-- 先判斷條件,如果條件為true,則執行邏輯,否則,不執行邏輯
while 條件 doSQL邏輯....
end while;

2.練習

-- 計算1累加到n的值,n為傳入的參數值。
create procedure p1(in n int)
begindeclare total int default 0;while n>0 doset total := total + n;set n := n - 1;end whileselect total;
end;

(4)repeat

1.語法

repeat是有條件的循環控制語句,當滿足條件的時候退出循環。

-- 先執行一次邏輯,然后判斷邏輯是否滿足,如果滿足,則退出。如果不滿足,則繼續下一次循環
repeatSQL邏輯....until 條件
end repeat;

2.練習

-- 計算1累加到n
create procedure p2(in n int)
begindeclare total int default 0;repeatset total := n + total;set n := n - 1;until n <= 0end repeat;select total;
end;

(5)loop循環

1.語法

loop實現簡單的循環,如果不在SQL邏輯中增加退出循環的條件,可以用其實現簡單的死循環。

loop可以配合以下兩個語句使用:

  • leave:配合循環使用,退出循環。(跳出循環必用)

  • iterate:必須用在循環中,作用是跳過當前循環剩下的語句,直接進入下一次循環。

[begin_label:] loopSQL邏輯
end loop [end_label]
-- label有如下幾種:
leave label; -- 退出指定標記的循環體
iterate label -- 直接進入下一次循環

2.練習

了解如何跳出循環、了解如何跳過當前循環進入下一次循環

(1)了解如何跳出循環leave

-- 1.計算從1累加到n的值,n為傳入的參數值
create procedure p3(in n int)
begindeclare total int default 0;sum:loopif n<0 thenleave sum;end if;set total := total + n;set n := n-1;end loop sum;select total;
end;

(2)了解如何跳過當前循環進入下一次循環(iterate)

-- 2.計算從1到n之間的偶數累加的值,n為傳入的參數值
create procedure p4(in n int)
begindeclare total int default 0;sum:loopif n<0 thenleave sum;end if;if n%2=1 thenset n := n-1;iterate sum;end if;set total := total + n;set n := n-1;end loop sum;select total;
end;

四、游標

(1)基本說明

游標(cursor)是用來存儲查詢結果集數據類型,在存儲過程和函數中可以使用游標對結果集進行循環的處理。游標的使用包括游標的聲明openfetchclose

游標需要聲明在普通變量之后,否則會報錯

-- 聲明游標
declare 游標名稱 cursor for 查詢語句;
-- 打開游標
open 游標名稱;
-- 獲取游標記錄
fetch 游標名稱 into 變量[,變量...];
-- 關閉游標
close 游標名稱;

(2)案例

根據傳入的參數uage,來查詢用戶表tb_user中,所有的用戶年齡小于等于uage的用戶的姓名(name)和專業(profession),并將用戶的姓名和專業插入到所創建的一張新表(id,name,profession)中。

-- 邏輯
-- 1.聲明游標,存儲查詢結果集
-- 2.準備:創建表結構
-- 3.開啟游標(open)
-- 4.獲取游標中的記錄(fetch)
-- 5.插入數據到新表中
-- 6.關閉游標(close)
create procedure p6(in max_age int)
begin-- 聲明變量接收數據declare uname varchar(50) default null;declare uprofession varchar(50) default null;-- 1.聲明游標,存儲查詢結果集declare u_cursor cursor for select name,profession from tb_user where age<max_age;-- 2.準備:創建表結構drop table if exists tb_user_pro;create table if not exists tb_user_pro(id int primary key auto_increment,name varchar(50),profession varchar(50));-- 3.開啟游標open u_cursor;while true do-- 4.獲取游標中的記錄fetch u_cursor into uname,uprofession;-- 5.插入數據到新表insert into tb_user_pro(name,age) values (uname,uage);end while;-- 6.關閉游標close u_cursor;
end;

以上可以很容易看出,while的條件是true,一直為真,會導致fetch取到空數據從而報錯,為了解決這個問題,我們有了條件處理程序;

-- 定義條件處理程序
declare exit handler for SQLSTATE '02000' close u_cursor; 
-- exit放入while中即可

五、條件處理程序

條件處理程序(Handler)可以用來定義在流程控制結構執行過程中遇到問題時相應的處理步驟。

declare handler_action handler for conditon_value [,conditon_value]... satement;handler_acion:continue -- 繼續執行當前程序exit -- 終止執行當前程序
conditon_value:sqlstate 狀態碼 -- 如:sqlstate 2000sqlwarning 	-- 所有01開頭的sqlstate代碼的簡寫not found		-- 所有02開頭的sqlstate代碼的簡寫sqlexception	-- 所有沒有被sqlwarning和notfound捕獲的sqlstate代碼的簡寫
#狀態碼為02000
declare exit handler for SQLSTATE '02000' close u_cursor;#當狀態為02開頭語句時
declare exit handler for not found colse u_cursor;

六、存儲函數

(1)基本說明

存儲函數是有返回值的存儲過程,存儲函數的參數只能是in類型的。

能夠使用存儲函數的地方都可以用存儲過程替代

create function 存儲函數名稱([參數列表])
returns  返回類型
[characteristic...] -- 特性名稱
begin-- SQL語句return...;
end;-- characteristic說明:
deterministic  -- 相同輸入參數總是產生相同的結果
not sql		-- 不包含sql語句
reads sql data	-- 包含讀取數據的語句,但不包含寫入數據的語句

如果不加特性characteristic,會報錯,如下圖:

在這里插入圖片描述
(2)案例

-- 計算從1累加到n的值,n為傳入的參數值
create function fun1(n int)
returns int deterministic
begindeclare total int default 0;while n>0 doset total := total+n;set n := n-1;end while;return total;end;select fun1(100);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97077.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97077.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97077.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HarmonyOS布局實戰:用聲明式UI構建自適應電商卡片

首先誠邀大家參加學習鴻蒙拿好禮活動&#xff0c;即日起&#xff0c;只要加入班級考取華為開發者基礎/高級證書&#xff0c;并發表一篇技術文章&#xff0c;就有機會獲得官方發放的精美禮品&#xff0c;數量有限&#xff0c;先到先得。冷老師的班級鏈接如下&#xff1a;?華為開…

日語學習-日語知識點小記-構建基礎-JLPT-N3階段(21):文法+單詞第7回3

日語學習-日語知識點小記-構建基礎-JLPT-N3階段&#xff08;&#xff12;1&#xff09;&#xff1a;文法單詞第7回3 1、前言&#xff08;1&#xff09;情況說明&#xff08;2&#xff09;工程師的信仰2、知識點&#xff11;ー 。。。と。。。なる&#xff12;ーVて欲しい ? …

Baumer高防護相機如何通過Tiny-YOLO單類模型實現人體跌倒檢測與跟蹤(C#代碼UI界面版)

《------往期經典推薦------》 AI應用軟件開發實戰專欄【鏈接】 序號項目名稱項目名稱11.工業相機 YOLOv8 實現人物檢測識別&#xff1a;&#xff08;C#代碼&#xff0c;UI界面版&#xff09;2.工業相機 YOLOv8 實現PCB的缺陷檢測&#xff1a;&#xff08;C#代碼&#xff0…

從源碼看瀏覽器彈窗消息機制:SetDefaultView 的創建、消息轉發與本地/在線頁通用實踐

引言在現代瀏覽器的開發中&#xff0c;前端頁面和 C 內核之間的通信是一項核心功能。無論是本地設置頁&#xff08;chrome:// 內置 H5&#xff09;還是在線活動頁&#xff0c;前端都可能需要調用瀏覽器底層 API&#xff0c;實現諸如“設置默認瀏覽器”、“更改壁紙”、“讀取用…

對比視頻處理單元(VPU)、圖形處理器(GPU)與中央處理器(CPU)

如今選擇互聯網點播流媒體與直播視頻的用戶數量已遠超傳統廣播電視&#xff0c;這一轉變催生了對高性能媒體轉碼與OTT流媒體功能專用技術的需求。 我們最新推出的Accelerated Compute云計算解決方案&#xff0c;首次通過NETINT Quadra視頻處理單元&#xff08;VPU&#xff09;…

vue3寫一個簡單的時間軸組件

插件版本&#xff1a;"element-plus": "^2.3.12""vue": "^3.0.0"代碼示例&#xff1a;樣式文件style.less&#xff1a;改變el-tooltip樣式&#xff0c;可以復制代碼到公共樣式文件.el-popper.o-el-tooltip-popper-class {max-width: 3…

Linex系統網絡管理(二)

二、網絡連接查看1. netstat作用查看本地服務的網絡監聽狀態查看客戶端連接到本地服務的連接狀態語法&#xff1a;netstat 選項 &#xff08;-anptu&#xff09;選項作用-n&#xff0c; --numeric顯示數字形式地址而不是去解析主機、端口或用戶名-a, --all顯示所有的監聽或連接…

Unity MQTT通訊

首先明確概念&#xff0c;什么是MQTT&#xff1f; MQTT是一種輕量級、基于發布 / 訂閱&#xff08;Publish/Subscribe&#xff09;模式的物聯網&#xff08;IoT&#xff09;通信協議&#xff0c;在帶寬有限、網絡不穩定的環境下&#xff0c;實現低功耗、低延遲的設備間通信&am…

JavaSE:類和對象2

一、封裝封裝的概念面向對象程序三大特性&#xff1a;封裝、繼承、多態。而類和對象階段&#xff0c;主要研究的就是封裝特性。何為封裝呢&#xff1f;簡單來說 就是套殼屏蔽細節。例如手機&#xff0c;你看不到任何的內部實現細節&#xff0c;只留下一些公開的接口給你使用&am…

RandAR訓練自己的數據集

論文題目:RandAR: Decoder-only Autoregressive Visual Generation in Random Orders(隨機順序下僅解碼器的自回歸視覺生成) 會議:CVPR2025 摘要:我們介紹了RandAR,一種僅解碼器的視覺自回歸(AR)模型,能夠以任意令牌順序生成圖像。與之前依賴于預定義生成順序的純解碼器…

基于PHP服裝租賃管理系統/基于php的服裝管理系統的設計與實現

基于PHP服裝租賃管理系統/基于php的服裝管理系統的設計與實現

高并發內存池(12)-ThreadCache回收內存

高并發內存池&#xff08;12&#xff09;-ThreadCache回收內存 代碼如下&#xff1a; // 釋放對象時&#xff0c;鏈表過長時&#xff0c;回收內存回到中心緩存 void ThreadCache::ListTooLong(FreeList& list, size_t size) {void* start nullptr;void* end nullptr;list…

讀大語言模型09超級智能

1. 超級智能1.1. 如果人工智能超越人類智能&#xff0c;可能會成為人類存在的一個重大威脅1.1.1. 對超級人工智能潛在危險最為擔憂的群體中&#xff0c;恰恰包括那些否認大語言模型具備真正智能的人1.2. 計算機科學已經成為所有科學領域中不可或缺的重要組成部1.3. GPT具備編寫…

阿里云拉取dockers鏡像

假如你已經在云服務器上安裝了docker需要配置下docker鏡像加速代理就行了找到自己的加速網址&#xff1a;然后在云服務器上&#xff0c;修改docker 配置文件&#xff0c;vi /etc/docker/daemon.json沒有這個文件的話&#xff0c;需要創建一個。{"default-address-pools&qu…

python自學筆記14 NumPy 線性代數

在Numpy庫中有專門的linalg 模塊用來做線性代數相關的運算。 本文中線性代數的一般概念不會解釋 拆解矩陣 鳶尾花數據矩陣結構如下&#xff08;150 4&#xff09;&#xff1a;取其中的行向量和列向量&#xff1a; # 導入包 import numpy as np from sklearn.datasets import l…

ubuntu20搭建MQTT

sudo apt update sudo apt install mosquitto mosquitto-clients sudo mosquitto_passwd -c /etc/mosquitto/passwd myuser sudo nano /etc/mosquitto/mosquitto.conf# 允許匿名用戶連接&#xff08;默認為 true&#xff0c;我們先關閉它&#xff09; allow_anonymous false# 指…

云服務器的主要用途都有哪些?

企業可以利用云服務器構建官方網站&#xff0c;企業官網需要穩定的運行環境來展示產品、服務、公司動態等信息&#xff0c;云服務器提供的高可用性和可擴展性&#xff0c;能保障大量用戶同時訪問時網站的穩定運行。移動應用的后端服務可以部署在云服務器上&#xff0c;如社交類…

IntelliJ IDEA Debug 模式功能指南

文章目錄前言&#x1f4a1; 1. 斷點類型與設置&#x1f680; 2. 啟動 Debug 模式?? 3. 調試控制按鈕詳解&#x1f440; 4. 查看與監控變量&#x1f9f0; 5. 高級調試技巧&#x1f48e; 總結前言 作為一名 Java 開發者&#xff0c;熟練掌握調試技巧是提高開發效率的關鍵。Int…

在pycharmIDE中如何快速掌握一個新模塊的使用方法

一、文檔使用懸停文檔&#xff1a;鼠標懸停在模塊/函數上顯示文檔摘要 (?最常用)快速文檔&#xff1a;選中標識符按 CtrlQ (Windows/Linux) 或 F1 (Mac)跳轉定義&#xff1a;Ctrl左鍵單擊 直接跳轉到源碼定義處 (?最權威)參數提示&#xff1a;輸入函數名時自動顯示參數列表&a…

win11自定義停止更新方法

一、打開運行窗口&#xff08;winr&#xff09;輸入regedit打開注冊表編輯器。按照如下路徑尋找。計算機\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings二、在Settings頁面下右擊——>新建——>DWORD(32位)值(D)&#xff0c;并重命名為粉色框中的名字…