【MySQL數據庫】存儲過程與自定義函數(含: SQL變量、分支語句、循環語句 和 游標、異常處理 等內容)

存儲過程:一組預編譯的SQL語句和流程控制語句,被命名并存儲在數據庫中。存儲過程可以用來封裝復雜的數據庫操作邏輯,并在需要時進行調用。

類似的操作還有:自定義函數、.sql文件導入。

我們先從熟悉的函數開始說起:

自定義函數

User-Defined Functions(UDF)允許創建 可以在SQL查詢中調用的函數,以便在執行特定操作或邏輯。

創建函數:

create function 函數名(參數名 數據類型,...) -- 參數列表
returns 返回值類型
[deterministic]
begin-- 函數體return 返回值;
end;

關鍵字:deterministic 漢譯為 ‘確定的’ 。在MySQL8.0版本以上,創建函數必須在該位置添加關鍵字,否則會報錯:

如果加上關鍵字deterministic的話:

另外需要注意的是:在指明函數返回值類型時,使用的關鍵字是?returns,在函數體內部返回值時使用的是?return?。注意區別,不要寫錯。

刪除函數:

將自定義函數刪除,語法:

drop function [if exists] myfuc;

調用函數:

使用自定義函數的方法與使用內置函數的方式一樣,執行select語句:

select myfuc();

變量

變量的聲明:關鍵字declare

declare variable datatype [default val];-- eg.
declare age int default 18;

變量的賦值:關鍵字set

set variable = val;-- eg.
set age = age + 10;

注意事項:

第一、函數的參數是已經聲明好的變量,無需再次聲明,可以直接使用

第二、聲明變量的語句必須在函數體的最上方,其次才可以是其它語句

第三、函數體外的SQL語句也可以設置變量語法為:【set @variable = val】

在函數體內執行sql語句為變量賦值

-- function_head
begindeclare val int default 0;select count(*) into val from emp;return val;end;

在該示例中,就將查詢的結果直接賦給變量val。?

結構語句

分支結構

SQL語句中一共有兩種分支結構【if/case】,但這兩種分支結構的語法用法卻與我們熟知的語言的寫法不同,但很好理解。下面我們就具體看一下:

第一種分支語句:if then...else if then...else...end if;

if condition1 then-- coding1
else if condition2 then-- coding2
else if condition3 then-- coding3
else--codingn
end if;

與我們常見的C/C++的代碼作用域以花括號作為界符不同,SQL語言使用 end顯式指定該作用域結束。上面定義函數時begin......end;就已經體現了。在if里面作為begin的等價關鍵字為:then。編譯器一旦識別then就知道進入if的內部作用域了。再次識別到其它的else if或者end if,就會跳出本作用域進入下一個作用域。

第二種分支語句:case? ?when then...when then... else... end case;

casewhen condition1 then-- exp1...;when condition2 then-- exp2...;else-- expn...;
end case;

case語句與我們熟悉的語法也不一樣,不過也很好理解:遇到case直接進入分支,然后判斷條件,滿足即then執行作用域內的邏輯代碼或表達式。最后有一個else相當于C/C++中的default,都不滿足就給個默認入口。最后以end case結束分支作用域。

循環結構

同樣的,循環結構也有兩種語法:【while/repeat】。

第一種循環語句:while (bool)?do ... end while;

while _condition_ 
do---- coding    --
end while;

當_condition_條件滿足時 do執行循環體,直到條件不滿足,end while結束循環。

第二種循環語句:repeat ... until (bool) end repeat;

repeat---- coding--
until _condition_ 
end repeat;

與while循環不同,while循環時滿足條件才執行。這種循環語句是,當滿足了_condtion_條件時,會結束這個循環。

存儲過程

存儲過程類似于自定義函數的語法,但是有區別的。例如:無返回值、傳入的參數方式不同、可以使用游標等。

基礎語法

無參語法:

-- 創建存儲過程
create procedure 存儲過程名()
begin-- 存儲過程的邏輯代碼-- 可以包含SQL語句、控制結構和變量操作
end;

調用存儲過程:

-- 執行存儲過程
call procedure 存儲過程名();

刪除存儲過程:

-- 刪除存儲過程
drop procedure [if exists] 存儲過程名;

參數詳解

create procedure 存儲過程名([in|out|inout] 參數名 參數的數據類型,[in|out|inout] 參數名 參數的數據類型,......
)
begin-- 存儲過程的邏輯代碼-- sql語句、結構語句、變量操作等
end;

類型修飾符

存儲過程的每個參數都有輸入輸出修飾,默認為:in輸入參數

in(默認):輸入參數,存儲過程的輸入值,從外部傳遞給存儲過程,存儲過程內部是只讀的,不能修改它的值。【readonly】

out:輸出參數,存儲過程的返回值,存儲過程可以修改它的值并將其返回

inout:輸入和輸出參數,既可以作為輸入值傳遞給存儲過程,也可以由存儲過程修改并返回。

進階語法

我們現在有一個需求,需要查詢emp表,為每個員工加100元薪資。

現在遇到的難點是:emp表查詢到的結果不是單一結果,只知道sal的字段類型為int,那么如何將結果集的每一條記錄依次取出來呢?

我們需要學習一個新的知識:游標-cursor

!!!注意!!!

在MySQL中,存儲過程允許使用游標來處理結果集,但函數里不行。可能是因為函數的設計用途不同。函數通常被要求是確定性的,或者至少在某些上下文中不允許有副作用,而游標可能涉及到對結果集的操作,可能引起非確定性的結果或者副作用。或者,函數的執行環境限制了一些操作,比如不允許修改數據庫狀態,而游標可能用于逐行處理,但函數需要返回單個值,這樣的結構不支持

游標

在MySQL中,游標Cursor是一種數據庫對象,它能夠讓你對結果集逐行進行處理。在操作數據庫時,普通的SQL語句通常會對整個及進行操作,但在我們上述的場景下,就需要逐行的處理數據,這時有標記就能發揮作用了。

游標的使用步驟:聲明=》打開=》讀取=》關閉=》釋放

-- 聲明游標
-- 定義游標的名稱 并綁定查詢語句
declare cs cursor 
for
select empno from emp;

游標就類似于C++實例化出來的對象:cs為對象名,對象類型為cursor-游標,綁定查詢語句就是傳入構造參數初始化游標的。

-- 打開游標
-- 執行定義好的查詢語句 把結果集存在游標中
open cs;

聯系熟悉的C++幫助理解:open 就是對象的一個成員函數,作用是執行綁定的sql語句獲取結果集的。

-- 讀取數據
-- 借助fetch語句從游標逐行獲取數據
fetch cs into val;

fetch 就是游標的另一個成員函數:換個名字理解:getNextData-獲取下一條數據,內部有一個偏移量,再次執行時,就是取結果集的下一個了。跟文件操作的偏移量聯系一下也不難理解。

-- 關閉游標
-- 結束對結果集的操作后,關閉游標以釋放資源
close cs;

?調用內部成員函數close,相當于調用clear函數

最后還有一個釋放游標,也就是從內存中移除游標的階段。

注意事項:

  • 性能問題:游標會對數據庫性能產生影響,因為它是逐行處理數據的,所以在大數據集上使用時要謹慎。
  • 資源管理:使用完游標后,一定要關閉并釋放它,避免資源浪費。
  • 異常處理:要考慮游標操作中可能出現的異常,像結果集為空或者到達結果集末尾等情況。

異常處理:錯誤處理-句柄

上面我們也說了,游標在使用時可能會出現異常情況。例如:循環次數過多,但數據集項數少于循環次數,那么會產生異常情況。下面給出一段代碼:

create procedure mypro() 
begin declare i int default 0;declare eid int;declare cs cursorforselect empno from emp;open cs;while i<20 dofetch cs into eid;select sal from emp where empno=eid;set i = i+1;end while;close cs;
end;

已知,我們的emp表一共只有14條記錄,那怎么從cs中取二十次數據呢?肯定會出錯的,這個異常一旦出現,我們如何處理呢?SQL就提供了一種異常處理機制:句柄

句柄-處理類型:

????????continue - 繼續執行后續代碼 - 用于可恢復的錯誤(數據遍歷結束)

????????exit - 退出當前代碼塊 - 用于不可恢復的錯誤(如事務沖突)

錯誤-條件類型:

????????not found - 未找到

????????sqlexception - sql異常

????????sqlwarning - sql警報

????????特定錯誤碼 -如1062主鍵沖突

根據笛卡爾積的形式,從兩個類型集合中任取一個都可以組成一個異常處理類型。

    -- 聲明處理句柄declare continue handler for not found set done=1;declare exit handler for sqlexceptionbeginrollback; -- 回滾事務set errmsg="錯誤信息";end;declare continue handler for sqlwarning set done=2;

感謝大家!

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

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

相關文章

ASP3605抗輻照加固同步降壓調節器——商業航天電源芯片解決方案新選擇

ASP3605企業宇航級型號ASP3605S2U通過SEU≥75 MeVcm/mg與SEL≥75 MeVcm/mg抗輻射測試。其輸入電壓4V至15V&#xff0c;輸出電流5A&#xff0c;支持多相級聯與冗余設計&#xff0c;適用于衛星、航天器電源系統。 面向航天場景的核心功能設計 1. 抗輻射與可靠性保障 單粒子效應…

使用fastapi部署stable diffusion模型

使用vscode運行stable diffusion模型&#xff0c;每次加載模型都需要10分鐘&#xff0c;為算法及prompt調試帶來了極大麻煩。使用jupyter解決自然是一個比較好的方案&#xff0c;但如果jupyter由于種種原因不能使用時&#xff0c;fastapi無疑成為了一個很好的選擇。 參考github…

2025-03-16 學習記錄--C/C++-PTA 習題4-4 特殊a串數列求和

合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、題目描述 ?? 習題4-4 特殊a串數列求和 給定兩個均不超過9的正整數a和n&#xff0c;要求編寫程序求aaaaaa?aa?a&#x…

ffmpeg庫視頻硬編碼使用流程

?一、硬件編碼核心流程? ?硬件設備初始化 // 創建CUDA硬件設備上下文? AVBufferRef *hw_device_ctx NULL; av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 0);// 綁定硬件設備到編碼器上下文? codec_ctx->hw_device_ctx av_buffer_…

【設計模式】3W 學習法全面解析 7 大結構型模式:Java 實戰 + 開源框架應用

3W 學習法總結結構型模式&#xff08;附 Java 代碼實戰及開源框架應用&#xff09; 結構型模式 主要關注 類與對象的組合&#xff0c;確保不同組件之間能夠高效協作&#xff0c;提高系統的靈活性和可維護性。本文采用 3W 學習法&#xff08;What、Why、How&#xff09;&#x…

在大數據開發中ETL是指什么?

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在數字經濟時代&#xff0c;數據已成為企業最核心的資產。然而&#xff0c;分散在業務系統、日志文件…

前端面試項目拷打

Axios相關 1.在Axios二次封裝時&#xff0c;具體封裝了哪些內容&#xff0c;如何處理請求攔截和響應攔截&#xff1f; axios二次封裝的目的&#xff1a;為了統一處理請求和響應攔截器、錯誤處理、請求超時、請求頭配置等&#xff0c;提高代碼可維護性和復用性。 首先創建axios…

「JavaScript深入」Server-Sent Events (SSE):輕量級實時通信技術

Server-Sent Events&#xff08;SSE&#xff09; SSE 的特點1. 單向通信2. 簡單易用&#xff0c;瀏覽器原生支持3. 持久連接4. 純文本傳輸5. 自動重連機制6. 輕量級協議 SSE 的實現服務器端實現&#xff08;Node.js 示例&#xff09;1. HTTP 響應頭設置2. 數據推送模式3. 服務器…

藍橋杯2023年第十四屆省賽真題-階乘的和

藍橋杯2023年第十四屆省賽真題-階乘的和 時間限制: 2s 內存限制: 320MB 提交: 3519 解決: 697 題目描述 給定 n 個數 Ai&#xff0c;問能滿足 m! 為∑ni1(Ai!) 的因數的最大的 m 是多少。其中 m! 表示 m 的階乘&#xff0c;即 1 2 3 m。 輸入格式 輸入的第一行包含一個整…

影刀RPA拓展-Python變量類型轉換

1. Python變量類型轉換概述 1.1 類型轉換的必要性 Python作為一種動態類型語言&#xff0c;在編程過程中經常需要進行變量類型轉換。這主要是因為不同數據類型在存儲結構、運算規則和使用場景上存在差異&#xff0c;而在實際開發中&#xff0c;我們常常需要對不同類型的數據進…

Python pyqt+flask做一個簡單實用的自動排班系統

這是一個基于Flask和PyQt的排班系統&#xff0c;可以將Web界面嵌入到桌面應用程序中。 系統界面&#xff1a; 功能特點&#xff1a; - 讀取員工信息和現有排班表 - 自動生成排班表 - 美觀的Web界面 - 獨立的桌面應用程序 整體架構&#xff1a; 系統采用前后端分離的架構…

Pycharm接入DeepSeek,提升自動化腳本的寫作效率

一.效果展示&#xff1a; 二.實施步驟&#xff1a; 1.DeepSeek官網創建API key&#xff1a; 創建成功后&#xff0c;會生成一個API key&#xff1a; 2. PyCharm工具&#xff0c;打開文件->設置->插件&#xff0c;搜索“Continue”&#xff0c;點擊安裝 3.安裝完成后&…

Java:Arrays類:操作數組的工具類

文章目錄 Arrays類常見方法SetAll(); 代碼排序如果數組中存儲的是自定義對象 Arrays類 常見方法 SetAll(); 注意&#xff1a; 不能用新的數組接是因為修改的是原數組&#xff0c;所以完了要輸出原數組發現會產生變化參數是數組下標變成灰色是因為還能簡化&#xff08;Lambda…

2025-gazebo配置on vmware,wsl

ros2安裝 # 安裝ros2, 推薦魚香ros一鍵式安裝 wget http://fishros.com/install -O fishros && . fishros安裝版本&#xff1a;ubuntu24.04 ros2 jazzy gazebo Getting Started with Gazebo? — Gazebo ionic documentation ros與gz的版本對應關系&#xff1a; ?…

格力地產更名“珠免集團“ 全面轉型免稅賽道

大灣區經濟網品牌觀察訊&#xff0c;3月18日&#xff0c;格力地產股份有限公司公告宣布&#xff0c;擬將公司名稱變更為"珠海珠免集團股份有限公司"&#xff0c;證券簡稱同步變更為"珠免集團"。此次更名并非簡單的品牌煥新&#xff0c;而是標志著這家曾以房…

網絡編程--服務器雙客戶端聊天

寫一個服務器和客戶端 運行服務器和2個客戶端&#xff0c;實現聊天功能 客戶端1和客戶端2進行聊天&#xff0c;客戶端1將聊天數據發送給服務器&#xff0c;服務器將聊天數據轉發給客戶端2 要求&#xff1a; 服務器使用 select 模型實現 &#xff0c;客戶端1使用 poll 模型實現…

k8s主要控制器簡述(一)ReplicaSet與Deployment

目錄 一、ReplicaSet 關鍵特性 示例 解釋 支持的 Operator 二、Deployment 1. 聲明式更新 示例 2. 滾動更新 示例 3. 回滾 示例 4. ReplicaSet 管理 示例 5. 自動恢復 示例 6. 擴展和縮容 示例 示例 一、ReplicaSet ReplicaSet 是 Kubernetes 中的一個核心控…

python中redis操作整理

下載redis命令 pip install redis 連接redis import redis # host是redis主機&#xff0c;需要redis服務端和客戶端都起著 redis默認端口是6379 pool redis.ConnectionPool(hostlocalhost, port6379,decode_responsesTrue) r redis.Redis(connection_poolpool)操作字符串 …

自然語言處理入門4——RNN

一般來說&#xff0c;提到自然語言處理&#xff0c;我們都會涉及到循環神經網絡&#xff08;RNN&#xff09;&#xff0c;這是因為自然語言可以被看作是一個時間序列&#xff0c;這個時間序列中的元素是一個個的token。傳統的前饋神經網絡結構簡單&#xff0c;但是不能很好的處…

數據結構之鏈表(雙鏈表)

目錄 一、雙向帶頭循環鏈表 概念 二、哨兵位的頭節點 優點&#xff1a; 頭節點的初始化 三、帶頭雙向鏈表的實現 1.雙鏈表的銷毀 2.雙鏈表的打印 3.雙鏈表的尾插和頭插 尾插&#xff1a; 頭插&#xff1a; 4.雙鏈表的尾刪和頭刪 尾刪&#xff1a; 頭刪&#xff1a; …