@select 怎么寫存儲過程_MySQL4:存儲過程和函數

什么是存儲過程

簡單說,存儲過程就是一條或多條SQL語句的集合,可視為批文件,但是起作用不僅限于批處理。本文主要講解如何創建存儲過程和存儲函數以及變量的使用,如何調用、查看、修改、刪除存儲過程和存儲函數等。使用的數據庫和表還是之前寫JDBC用的數據庫和表:

create database school;use school;create table student( studentId int primary key auto_increment not null, studentName varchar(10) not null, studentAge int, studentPhone varchar(15))insert into student values(null,'Betty', '20', '00000000');insert into student values(null,'Jerry', '18', '11111111');insert into student values(null,'Betty', '21', '22222222');insert into student values(null,'Steve', '27', '33333333');insert into student values(null,'James', '22', '44444444');commit;

存儲程序可以分為存儲過程和函數,MySQL中創建存儲過程和函數的語句分別是:CREATE PROCEDURE和CREATE FUNCTION。使用CALL語句來調用存儲過程,只能用輸出變量返回值。函數可以從語句外調用(即通過引用函數名),也能返回標量值。存儲過程也可以調用其他存儲過程。

創建存儲過程

創建存儲過程,需要使用CREATE PROCEDURE語句,語句基本格式如下:

CREATE PROCEDURE sp_name([proc_parameter]) [characteristics ...] routine_body

解釋一下:

1、CREATE PROCEDURE為創建存儲過程的關鍵字

2、sp_name為存儲過程的名字

3、proc_parameter為指定存儲過程的參數列表,列表形式為[IN|OUT|INOUT] param_name type。其中,IN表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出,param_name表示參數名稱,type表示參數類型,該類型可以是MySQL數據庫中的任意類型

4、characteristics指定存儲過程的特性

5、routime_body是SQL代碼的內容,可以用BEGIN...END來表示SQL代碼的開始和結束

編寫存儲過程不是簡單的事情,可能存儲過程中需要復雜的SQL語句,并且要有創建存儲過程的權限;但是使用存儲過程將簡化操作,減少冗余的操作步驟,同時還可以減少操作過程中的事物,提高效率,因此存儲過程是非常有用的。下面看兩個存儲過程,一個查詢student表中的所有字段,一個根據student表的Age字段算一個Age的平均值:

CREATE PROCEDURE proc ()BEGIN SELECT * FROM student;END;CREATE PROCEDURE AvgStudentAge()BEGIN SELECT AVG(studentAge) AS avgAge FROM student;END;

上面都是不帶參數的存儲過程,下面看一個帶參數的存儲過程:

DELIMITER //CREATE PROCEDURE CountStudent(IN sName VARCHAR(10), OUT num INT)BEGIN SELECT COUNT(*) INTO num FROM student WHERE studentName = sName;END //

上述代碼的作用是創建一個獲取student表記錄條數的存儲過程,名稱為CountStudent,根據傳入的學生姓名COUNT(*)后把結果放入參數num中。

注意另外一個細節,上述代碼第一行使用了"DELIMITER //",這句語句的作用是把MySQL的結束符設置為"//",因為MySQL默認的語句結束符號為分號";",為了避免與存儲過程中SQL語句結束符相沖突,需要使用DELIMITER改變存儲過程的結束符,并以"END //"結束存儲過程。存過程定義完畢之后再使用"DELIMITER ;"恢復默認結束符。DELIMITER也可以指定其他符號作為結束符。

創建存儲函數

創建存儲函數需要使用CREATE FUNCATION語句,其基本語法如下:

CREATE FUNCTION func_name([func_parameter]) RETURNS type[characteristic ...] routine_body

解釋一下:

1、CREATE_FUNCTION為用來創建存儲函數的關鍵字

2、func_name表示存儲函數的名稱

3、func_parameter為存儲過程的參數列表,參數列表形式為[IN|OUT|INOUT] param_name type,和存儲過程一樣

4、RETURNS type表示函數返回數據的類型

5、characteristic表示存儲函數的特性,和存儲過程一樣

舉個例子:

CREATE FUNCTION NameByZip() RETURNS CHAR(50)RETURN (select studentPhone from student where studentName = 'JAMES');

提兩點:

1、如果在存儲函數中的RETURN語句返回一個類型不同于函數的RETURNS自居指定的類型的值,返回值將被強制為恰當的類型

2、指定參數為IN、OUT或INOUT只對PROCEDURE是合法的(FUNCTION中總是默認為IN參數)。RETURNS子句只能對FUNCTION做指定,對于函數而言這是強制性的,它用來指定函數的返回類型,而且函數體必須包含一個RETURN value語句

變量的使用

變量可以在子程序中聲明并使用,這些變量的作用范圍是在BEGIN...END程序中,在存儲過程中可以使用DECLARE語句定義變量,語法如下:

DECLARE var_name[,varame]... date_type [DEFAULT value]

解釋一下:

1、var_name為局部變量的名稱

2、DEFAULT value子句給變量提供一個默認值,值除了可以被聲明為一個常數之外,還可以被指定為一個表達式。如果沒有DEFAULT子句,那么初始值為NULL

定義變量后,為變量賦值可以改變變量的默認值,MySQL使用SET為變量賦值:

SET var_name=expr[, var_name=expr] ...;

舉個例子:

DECLARE var1 INT DEFAULT 100;DECLARE var2, var3, var4 INT;SET var2 = 10, var3 = 20;SET var4 = var2 + var3;

當然,我們使用SELECT語句也可以給變量賦值:

DECLARE t_studentName CHAR(20);DECLARE t_studentAge INT;SELECT studentName, studentId INTO t_studentName, t_studentAge FROM student where studentName = 'Bruce';DECLARE t_studentName CHAR(20);DECLARE t_studentAge INT;

游標的使用

查詢語句可能返回多條記錄,如果數據量非常大,需要在存儲過程和存儲函數中使用游標來逐條讀取查詢結果集中的記錄。應用程序可以根據需要滾動或瀏覽器中的程序。

游標必須在處理程序之前被聲明,并且變量和條件還必須在聲明游標或處理程序之前被聲明。MySQL中聲明游標的方法為:

DECLARE cursor_name CURSOR FOR select_statement

解釋一下:

1、cursor_name表示游標的名稱

2、select_statement表示SELECT語句返回的內容,返回一個用于創建游標的結果集

定義了游標,就要打開游標,打開游標的方法為:

OPEN cursor_name{游標名稱}

再就是使用游標了,使用游標的方法為:

FETCH cursor_name INTO var_name [, var_name] ... {參數名稱}

最后游標使用完了,要關閉:

CLOSE cursor_name{游標名稱}

舉個例子:

DECLARE t_studentName CHAR(20);DECLARE t_studentAge INT;DECLARE cur_student CURSOR FOR SELECT studentName, studentId FROM student where studentName = 'Bruce';OPEN cur_student;FETCH cur_student INTO t_studentName, t_studentAge;...CLOSE cur_student;

studentName為Bruce的在數據里面不止一條記錄,創建游標之后就從student表中查出了studentName和studentId的值。OPEN這個游標,通過FETCH之后遍歷每一組studentName和studentAge,并放入申明的變量t_studentName和t_studentAge中,之后想怎么用這兩個字段怎么用這兩個字段了。注意,游標用完關閉掉。

IF、CASE、LOOP、LEAVE、ITERATE、REPEAT

這六個比較簡單,放在一起講了,簡單說下用法,除了第一個IF寫個例子以外,別的就不寫例子了,可以自己嘗試下。

1、IF

IF語句包含多個判斷條件,根據判斷的結果為TRUE或FALSE執行相應的語句,其格式為:

IF expr_condition THEN statement_list [ELSEIF expr_condition THEN statement_list] [ELSE statement_list] END IF

比如:

IF t_studentName IS NULL THEN SELECT studentName INTO t_studentName FROM student where studentName = 'Bruce'; ELSE UPDATE studentName set student = NULL where studentName = 'Bruce';END IF;

2、CASE

case是另外一個進行條件判斷的語句,該語句有兩種格式,第一種格式如下:

CASE case_expr WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE statement_list]END CASE

其中,case_expr參數表示判斷的表達式,決定了哪一個WHEN自居會被執行;when_value表示表達式可能的值,如果某個when_value表達式與case_expr表達式結果相同,則執行對應THEN關鍵字后的statement_list中的語句;statement_list參數表示不同when_value值的執行語句。

CASE語句的第二種格式為:

CASE WHEN expr_condition THEN statement_list [WHEN expr_condition THEN statement_list] ... [ElSE statement_list]END CASE

只是寫法稍微變了一下,參數還是第一種寫法的意思

3、LOOP

LOOP循環用來重復執行某些語句,與IF和CASE相比,LOOP只是創建一個循環操作的過程,并不進行條件判斷。LOOP內的語句一直被重復執行直到循環被退出,跳出循環過程,使用LEAVE子句。LOOP語句j的基本格式如下:

[loop_label:] LOOP statement_listEND LOOP

其中loop_label表示LOOP語句的標注名稱,該參數可以省略;statement_list參數表示需要循環執行的語句

4、LEAVE

LEAVE語句用來退出任何被標注的流程控制構造,LEAVE語句的基本格式如下:

LEAVE label

5、ITERATE

ITERATE語句將執行順序轉到語句段開頭出,語句基本格式如下:

ITERATE label

6、REPEAT

REPEAT語句用來創建一個帶有條件判斷的循環過程,每次與局執行完畢之后,會對條件表達式進行判斷,如果表達式為真,則循環結束,否則重復執行循環中的語句。REPEAT語句的基本格式如下:

[repeat_label:] REPEAT statement_listUNTIL expr_conditionEND REPEAT

其中,repeat_label為REPEAT語句的標注名稱,該參數可以省略;REPEAT語句內的語句或語句群被重復,直至expr_condition為真

調用存儲過程和函數

存儲過程已經定義好了,接下來無非就是調用。存儲過程和函數有很多種調用方法,存儲過程必須使用CALL語句調用,并且存儲過程和數據庫相關,如果要執行其他數據庫中的存儲過程,需要指定數據庫名稱,例如CALL dbname.procname。存儲函數的調用與MySQL中預定義的函數調用方式相同。

1、調用存儲過程

存儲過程是通過CALL語句進行調用的,語法如下:

CALL sp_name([parameter[,...]])

舉個例子,就調用最前面那個CountStudent的存儲過程:

CALL CountStudent('Bruce', @num);select @num;

運行結果為:

2bf47eaa0c8e7a5d58e9edd53adb5968.png

2、調用存儲函數

MySQL中調用存儲函數的使用方法和MySQL內部函數的使用方法是一樣的,無非存儲函數是用戶自己定義的,內部函數是MySQL開發者定義的。

我們調用一下上面定義的NameByZip那個函數:

select NameByZip();

運行結果為:

524ae778bb22950f974051e89f4685bc.png

可以對照一下,studenName為"James"這一條,對應的studentPhone就是"44444444",符合SELECT出來的結果

查看、刪除存儲過程和函數

1、查看存儲過程和函數的狀態

SHOW STATUS可以查看存儲過程核函數的狀態,其基本語法結構如下:

SHOW {PROCEDURE | FUNCTIOn} STATUS [LIKE 'pattern'

這個語句是一個MySQL的擴展,他返回子程序的特征,如數據庫、名字、類型、創建者及創建和修改日期。如果沒有指定樣式,根據使用的語句,所有存儲過程或存儲函數的信息都被列出。PROCEDURE和FUNCTIOn分別表示查看存儲過程和函數,LIKE語句表示匹配存儲過程或函數的名稱。

舉個例子:

SHOW PROCEDURE STATUS

運行結果為:

9529d074d1e8f6782f772f5e346ef93a.png

后面還有一些字段,截圖截不全沒辦法。查看存儲函數也一樣,可以自己試試看。

2、查看存儲過程和函數的定義

除了SHOW STATUS外,還可以使用SHOW CREATE來查看存儲過程的定義,基本格式為:

SHOW CREATE {PROCEDURE | FUNCTION} sp_name

比如:

SHOW CREATE FUNCTION NameByZip

我查看了NameByZip這個函數的定義,結果為:

09541f914e4d30d764f6c2650e7ca4a4.png

這個Create Function字段就是創建的存儲函數的內容

3、刪除存儲過程和函數

刪除存儲過程核函數,可以使用DROP語句,基本語法如下:

DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name

這個語句被用來移除一個存儲過程或函數。sp_name為待移除的存儲過程或函數的名稱。

IF EXISTS子句是一個MySQL的擴展,如果程序或函數不存儲,它可以防止錯誤發生,產生一個用SHOW WARNINGS查看的警告。舉個例子:

DROP PROCEDURE CountStudentDROP FUNCTION NameByZip;

這么簡單就可以了。注意這里沒有講修改存儲過程和存儲函數,因為修改存儲過程或者函數只能修改存儲過程或者存儲函數的特性,不能直接對已有的存儲過程或函數進行修改,如果必須要改,只能先DROP在重新編寫代碼,CREATE一個新的。

73dd3720d9ed7368a745267ab2f36616.png

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

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

相關文章

跨域訪問-預請求及跨域常見問題

預請求 參考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#預請求 簡而言之,在跨域并且嘗試添加一些特殊頭及自定義頭的情況下,由于瀏覽器的安全機制,會加多一次OPTIONS預請求(詢問請求&am…

mysql查詢優化之一:mysql查詢優化常用方式

一、為什么查詢速度會慢? 一個查詢的生命周期大致可以按照順序來看:從客戶端,到服務器,然后在服務器上進行解析,生成執行計劃,執行,并返回結果給客戶端。其中在“執行”階段包含了大量為了檢索…

修復Sonar中常見的Java安全代碼沖突

本文旨在向您展示如何快速修復最常見的Java安全代碼沖突。 它假定您熟悉代碼規則和違規的概念以及Sonar如何對其進行報告。 但是,如果您以前從未聽說過這些術語,則可以閱讀Sonar Concepts或即將出版的有關Sonar的書 ,以獲取更詳細的解釋。 為…

理解ThreadLocal

ThreadLocal:線程本地存儲,為每個線程都創建了變量的副本,線程在訪問變量時,可以直接訪問自己內部的副本變量。 理解幾個概念: 在java中ThreadLocal是一個類。 ThreadMap是一個類, Thread類是線程類。 ThreadLocal…

抖音右上角一個小黃點是什么_抖音官方入駐視頻號,釋放了一個什么樣的信號?...

專注視頻號觀察第 328 篇這幾天,視頻號生態新入駐了一個企業號,在圈里引起不少的轟動,因為這個號的名字叫做———抖音。這件事在圈里引發不少的轟動,很多人驚嘆:“連抖音都來開視頻號了,你還在等什么&…

資源包技巧和最佳實踐

今天是資源捆綁日。 通常,這是Java中最著名的國際化機制(i18n)。 使用它應該很容易。 但是,在弄臟手時會出現許多小問題。 如果您有相同的想法,則此文章適合您。 基本 java.util.ResourceBundle定義了用于訪問Java中翻…

springMvc-文件上傳

趕時間&#xff0c;又在寫垃圾博客&#xff0c;在心里給自己一耳巴 1.單文件上傳 2.多文件上傳 代碼&#xff1a; 頁面&#xff1a; <!DOCTYPE html><html><head><meta charset"UTF-8"><title>Insert title here</title></he…

c cuda 指定gpu_GPU并行編程:熟練使用CUDA C語言

【IT168 專稿】一個大任務通常可能被分解成許多可以一起處理的小任務&#xff0c;以便創建一個解決方案&#xff0c;這和粉刷房子的道理是一樣的&#xff0c;在粉刷之前&#xff0c;假設你需要買5公升油漆和5把刷子&#xff0c;你可以自己一個人干完采購和粉刷的活&#xff0c;…

js中使用0 “” null undefined {}需要注意

注意&#xff1a;在js中0為空&#xff08;false&#xff09; &#xff0c;代表空的還有“”&#xff0c;null &#xff0c;undefined&#xff1b; 如果做判斷if(&#xff01;上面的四種值)&#xff1b;返回均為false console.log(!null);// true console.log(!0);//true consol…

PhpStorm 10.0.3破解版下載

漢化破解版軟件下載&#xff1a; http://pan.baidu.com/s/1geNO24r 密碼: d5ci 這個漢化破解軟件解決了大綱視圖里空白的問題。 先安裝騰訊電腦管家&#xff0c;然后安裝這個軟件&#xff0c;安裝到最后提示有個文件有病毒已刪除&#xff0c;點確定后正常使用。轉載于:https://…

Jenkins:部署JEE工件

隨著持續集成和持續交付的出現 &#xff0c;我們的構建被分為不同的步驟&#xff0c;以創建部署管道。 這些步驟中的一些步驟可以是例如編譯和運行快速測試&#xff0c;運行慢速測試&#xff0c;運行自動驗收測試或發布應用程序等。 部署流程的最后一步意味著將我們的產品&…

seafile 部署_Seafile開啟webdav及讀寫性能測試

為什么要在seafile搞webdavSeafile 一直是一款可靠的文件同步web應用&#xff0c;經過個人測試&#xff0c;同一臺機器上&#xff0c;seafile在傳輸文件時的速度比nextcloud要快&#xff08;可能也與php的設置有關系&#xff09;&#xff0c;這是seafile的優勢。但是&#xff0…

Python--校園網爬蟲記

查成績&#xff0c;算分數&#xff0c;每年的綜合測評都是個固定的過程&#xff0c;作為軟件開發者&#xff0c;這些過程當然可以交給代碼去做&#xff0c;通過腳本進行網絡請求獲取數據&#xff0c;然后直接進行計算得到基礎分直接填表就好了&#xff0c;查成績再手動計算既容…

Spring–添加SpringMVC –第1部分

歡迎來到本教程的第四部分。 在這一部分中&#xff0c;我們將使用Spring MVC編寫控制器和視圖&#xff0c;并考慮我們的REST模型。 我們必須做的第一件事&#xff0c;就是根據目前的情況制作一個Web應用程序。 我們將web / WEB-INF文件夾添加到我們的項目根目錄。 在WEB-INF內創…

[Linux] 權限與指令間的關系

我們知道權限對于使用者帳號來說是非常重要的&#xff0c;因為他可以限制使用者能不能讀取/創建/刪除/修改文件或目錄&#xff01; 在這一章我們介紹了很多文件系統的管理指令&#xff0c;第五章則介紹了很多文件權限的意義。在這個小節當中&#xff0c; 我們就將這兩者結合起來…

access month函數用法_學會了這7個EXCEL日期函數技巧,老板再讓你加班,你找我!...

日期函數&#xff0c;常用年月日&#xff0c;時分秒&#xff0c;星期&#xff0c;季度&#xff0c;求差值等&#xff0c;學會以下幾個函數&#xff0c;老板再讓你加班&#xff0c;你找我&#xff01;1、記錄當前時間(不隨系統時間變化)NOW()函數與數據有效性結合&#xff0c;記…

css樣式表的選擇器與分類

css 樣式表的作用&#xff1a; 主要用于結構,樣式與行為,CSS主要的作用就是美化網頁的一個語言,它的特點: 1.結構與樣式分離的方式,便于后期維護與改版; 2.樣式定義精確到像素的級別; css樣式表的結構&#xff1a;CSS 稱為層疊樣式表 用于給網頁設置各種樣式 css樣式的語法由3部…

Spring 3.1緩存和@Cacheable

緩存在軟件領域已經存在很長時間了。 它們是那些真正有用的東西之一&#xff0c;一旦您開始使用它們&#xff0c;您會想知道如果沒有它們&#xff0c;您是如何相處的&#xff0c;所以似乎讓Spring的家伙們只是在版本中向Spring核心添加緩存實現有點奇怪。 3.1。 我猜想以前沒有…

pytorchyolov4訓練_使用pytorch-yolov5 訓練自己的數據集-2020.6.15

make yolov5 pytorch train datasets訓練所需環境 python3.5, pytorch1.3, torchvision 0.4.1 , tensorboard 1.14.0 , tensorflow-gpu1.14.0本例制作yolov5數據集 并進行數據訓練從VOC數據集轉為訓練所需的coco數據集代碼有待改進包含文件夾voc2coco/(Annotations/ JPEGImages…

meta 的作用 搜集

Meta標簽中的format-detection屬性及含義 format-detection翻譯成中文的意思是“格式檢測”&#xff0c;顧名思義&#xff0c;它是用來檢測html里的一些格式的&#xff0c;那關于meta的format-detection屬性主要是有以下幾個設置&#xff1a;<meta name"format-detecti…