【存儲過程】MySQL存儲過程/存儲過程與自定義函數的區別

---------------------------存儲過程--------------------

語法:

創建存儲過程:

CREATE?[definer = {user|current_user}]?PROCEDURE?sp_name ([ proc_parameter [,proc_parameter ...]]) [ characteristics..] routime_body

其中:

proc_parameter : [IN|OUT|INOUT] parameter_name type

其中IN表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出;param_name表示參數名稱;type表示參數的類型

存儲過程體中可以使用自定義函數(UDF)中使用的復合結構/流程控制/SQL語句/自定義變量等等內容,

調用存儲過程:

CALL?sp_name ([ proc_parameter [,proc_parameter ...]])

CALL?sp_name?

說明:當無參時,可以省略"()",當有參數時,不可省略"()"

存儲過程修改:

ALTER語句修改存儲過程只能修改存儲過程的注釋等無關緊要的東西,不能修改存儲過程體,所以要修改存儲過程,方法就是刪除重建!

刪除存儲過程:

DROP PROCEDURE [IF EXISTS] sp_name

示例:

創建無參存儲過程:

delimiter //
CREATE PROCEDURE showTime()
BEGIN
SELECT now();
END//
delimiter ;CALL showTime;

作用:顯示當前時間,沒什么實際意義

創建含參存儲過程:

只有一個IN參數

delimiter //
CREATE PROCEDURE seleById(IN uid SMALLINT UNSIGNED)
BEGIN
SELECT * FROM son WHERE id = uid;
END//
delimiter ;call seleById(2);

包含IN參數和OUT參數

delimiter //
CREATE PROCEDURE deleteById(IN uid SMALLINT UNSIGNED, OUT num SMALLINT UNSIGNED)
BEGIN
DELETE FROM son WHERE id = uid;
SELETE row_count() into num;
END//
delimiter ;call seleById(2,@changeLine);
SELETE @changeLine;

說明:創建存儲過程deleteById,包含一個IN參數和一個OUT參數.調用時,傳入刪除的ID和保存被修改的行數值的用戶變量@changeLine,select @changeLine;輸出被影響行數.

?

?

?

附一個根據時間修改狀態的存儲過程:

DELIMITER $$USE `exam9`$$DROP PROCEDURE IF EXISTS `updateStatus`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `updateStatus`()
BEGINUPDATE exam SET `status`="已結束" WHERE  `status` != "已結束" AND  (NOW() - endTime)>0  ;UPDATE exam  SET `status`="正在答題"  WHERE   `status` != "已結束" AND ( NOW() - startTime)>=0 AND  (NOW() - endTime)<=0;UPDATE haulinfo SET bigStatus="已結束" WHERE  bigStatus != "已結束" AND  (CURDATE() - bigEndDate)>0; UPDATE haulinfo SET bigStatus="進行中" WHERE  (CURDATE() - bigEndDate)<=0 AND  (CURDATE() - bigBeginDate)>=0;UPDATE exam SET bigStatus=(SELECT bigStatus FROM haulinfo WHERE bigId=exam.bigId);
END$$DELIMITER ;

?

?

?

?

區別:

存儲過程與自定義函數的區別:存儲過程實現的過程要復雜一些,而函數的針對性較強;存儲過程可以有多個返回值,而自定義函數只有一個返回值;存儲過程一般獨立的來執行,而函數往往是作為其他SQL語句的一部分來使用;
存儲過程存在的必要性(好處):

存儲過程說白了就是把經常使用的SQL語句或業務邏輯封裝起來,預編譯保存在數據庫中,當需要的時候從數據庫中直接調用,省去了編譯的過程.
提高了運行速度;
同時降低網絡數據傳輸量(你覺得傳一堆SQL代碼快,還是傳一個存儲過程名字和幾個參數快???)

?

?

---------------------------函數用法--------------------

自定義函數 (user-defined function UDF)就是用一個象ABS() 或 CONCAT()這樣的固有(內建)函數一樣作用的新函數去擴展MySQL。

所以UDF是對MySQL功能的一個擴展

創建和刪除自定義函數語法:

創建UDF:

  CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name type,...])

  RETURNS {STRING|INTEGER|REAL}

  runtime_body

簡單來說就是:

  CREATE FUNCTION 函數名稱(參數列表)

  RETURNS 返回值類型

  函數體

刪除UDF:

  DROP FUNCTION function_name

調用自定義函數語法:

  SELECT function_name(parameter_value,...)

語法示例:

創建簡單的無參UDF

CREATE FUNCTION simpleFun()RETURNS VARVHAR(20) RETURN "Hello World!";

說明:

UDF可以實現的功能不止于此,UDF有兩個關鍵點,一個是參數,一個是返回值,UDF可以沒有參數,但UDF必須有且只有一個返回值

在函數體重我們可以使用更為復雜的語法,比如復合結構/流程控制/任何SQL語句/定義變量等等

復合結構定義語法:

在函數體中,如果包含多條語句,我們需要把多條語句放到BEGIN...END語句塊中

DELIMITER //
CREATE FUNCTION IF EXIST deleteById(uid SMALLINT UNSIGNED) 
RETURNS VARCHAR(20) 
BEGIN
DELETE FROM son WHERE id = uid;
RETURN (SELECT COUNT(id) FROM son);
END//

修改默認的結束符語法:

DELIMITER // 意思是修改默認的結束符";"為"//",以后的SQL語句都要以"//"作為結尾

特別說明:

UDF中,REURN語句也包含在BEGIN...END中

自定義函數中定義局部變量語法:

DECLARE var_name[,varname]...date_type [DEFAULT VALUE];

簡單來說就是:

DECLARE 變量1[,變量2,... ]變量類型 [DEFAULT 默認值]

這些變量的作用范圍是在BEGIN...END程序中,而且定義局部變量語句必須在BEGIN...END的第一行定義

示例:

DELIMITER //
CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT UNSIGNED) 
RETURNS SMALLINT
BEGIN
DECLARE a, b SMALLINT UNSIGNED DEFAULT 10;
SET  a = x, b = y;
RETURN a+b;
END//

上邊的代碼只是把兩個數相加,當然,沒有必要這么寫,只是說明局部變量的用法,還是要說明下:這些局部變量的作用范圍是在BEGIN...END程序中

為變量賦值語法:

SET parameter_name = value[,parameter_name = value...]

SELECT INTO parameter_name

eg:?

...在某個UDF中...
DECLARE x int;
SELECT COUNT(id) FROM tdb_name INTO x;
RETURN x;
END//

用戶變量定義語法:(可以理解成全局變量)

SET @param_name = value

SET @allParam = 100;
SELECT @allParam;

上述定義并顯示@allParam用戶變量,其作用域只為當前用戶的客戶端有效

自定義函數中流程控制語句語法:

存儲過程和函數中可以使用流程控制來控制語句的執行。

MySQL中可以使用IF語句、CASE語句、LOOP語句、LEAVE語句、ITERATE語句、REPEAT語句和WHILE語句來進行流程控制。

每個流程中可能包含一個單獨語句,或者是使用BEGIN...END構造的復合語句,構造可以被嵌套

1.IF語句

IF語句用來進行條件判斷。根據是否滿足條件,將執行不同的語句。其語法的基本形式如下:

IF search_condition THEN statement_list 
[ELSEIF search_condition THEN statement_list] ... 
[ELSE statement_list] 
END IF 

其中,search_condition參數表示條件判斷語句;statement_list參數表示不同條件的執行語句。

注意:MYSQL還有一個IF()函數,他不同于這里描述的IF語句

下面是一個IF語句的示例。代碼如下:

IF age>20 THEN SET @count1=@count1+1;  
ELSEIF age=20 THEN SET @count2=@count2+1;  
ELSE SET @count3=@count3+1;  
END IF; 

該示例根據age與20的大小關系來執行不同的SET語句。

如果age值大于20,那么將count1的值加1;如果age值等于20,那么將count2的值加1;

其他情況將count3的值加1。IF語句都需要使用END IF來結束。

2.CASE語句

CASE語句也用來進行條件判斷,其可以實現比IF語句更復雜的條件判斷。CASE語句的基本形式如下:

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

其中,case_value參數表示條件判斷的變量;

when_value參數表示變量的取值;

statement_list參數表示不同when_value值的執行語句。

CASE語句還有另一種形式。該形式的語法如下:

CASE 
WHEN search_condition THEN statement_list 
[WHEN search_condition THEN statement_list] ... 
[ELSE statement_list] 
END CASE 

其中,search_condition參數表示條件判斷語句;

statement_list參數表示不同條件的執行語句。

下面是一個CASE語句的示例。代碼如下:

CASE age 
WHEN 20 THEN SET @count1=@count1+1; 
ELSE SET @count2=@count2+1; 
END CASE ; 

代碼也可以是下面的形式:

CASE 
WHEN age=20 THEN SET @count1=@count1+1; 
ELSE SET @count2=@count2+1; 
END CASE ; 

本示例中,如果age值為20,count1的值加1;否則count2的值加1。CASE語句都要使用END CASE結束。

注意:這里的CASE語句和“控制流程函數”里描述的SQL CASE表達式的CASE語句有輕微不同。這里的CASE語句不能有ELSE NULL子句

并且用END CASE替代END來終止!!

?

3.LOOP語句

LOOP語句可以使某些特定的語句重復執行,實現一個簡單的循環。

但是LOOP語句本身沒有停止循環的語句,必須是遇到LEAVE語句等才能停止循環。

LOOP語句的語法的基本形式如下:

[begin_label:] LOOP 
statement_list 
END LOOP [end_label] 

其中,begin_label參數和end_label參數分別表示循環開始和結束的標志,這兩個標志必須相同,而且都可以省略;

statement_list參數表示需要循環執行的語句。

下面是一個LOOP語句的示例。代碼如下:

add_num: LOOP  
SET @count=@count+1;  
END LOOP add_num ; 

該示例循環執行count加1的操作。因為沒有跳出循環的語句,這個循環成了一個死循環。

LOOP循環都以END LOOP結束。

?

4.LEAVE語句

LEAVE語句主要用于跳出循環控制。其語法形式如下:

LEAVE label 

其中,label參數表示循環的標志。

?

下面是一個LEAVE語句的示例。代碼如下:

add_num: LOOP 
SET @count=@count+1; 
IF @count=100 THEN 
LEAVE add_num ; 
END LOOP add_num ; 

該示例循環執行count加1的操作。當count的值等于100時,則LEAVE語句跳出循環。

?

5.ITERATE語句

ITERATE語句也是用來跳出循環的語句。但是,ITERATE語句是跳出本次循環,然后直接進入下一次循環。

ITERATE語句只可以出現在LOOP、REPEAT、WHILE語句內。

ITERATE語句的基本語法形式如下:

ITERATE label 

其中,label參數表示循環的標志。

下面是一個ITERATE語句的示例。代碼如下:

復制代碼
add_num: LOOP 
SET @count=@count+1; 
IF @count=100 THEN 
LEAVE add_num ; 
ELSE IF MOD(@count,3)=0 THEN 
ITERATE add_num; 
SELECT * FROM employee ; 
END LOOP add_num ; 
復制代碼

該示例循環執行count加1的操作,count值為100時結束循環。如果count的值能夠整除3,則跳出本次循環,不再執行下面的SELECT語句。

說明:LEAVE語句和ITERATE語句都用來跳出循環語句,但兩者的功能是不一樣的。

LEAVE語句是跳出整個循環,然后執行循環后面的程序。而ITERATE語句是跳出本次循環,然后進入下一次循環。

使用這兩個語句時一定要區分清楚。

?

6.REPEAT語句

REPEAT語句是有條件控制的循環語句。當滿足特定條件時,就會跳出循環語句。REPEAT語句的基本語法形式如下:

[begin_label:] REPEAT 
statement_list 
UNTIL search_condition 
END REPEAT [end_label] 

其中,statement_list參數表示循環的執行語句;search_condition參數表示結束循環的條件,滿足該條件時循環結束。

下面是一個ITERATE語句的示例。代碼如下:

REPEAT 
SET @count=@count+1; 
UNTIL @count=100 
END REPEAT ; 

該示例循環執行count加1的操作,count值為100時結束循環。

REPEAT循環都用END REPEAT結束。

?

7.WHILE語句

WHILE語句也是有條件控制的循環語句。但WHILE語句和REPEAT語句是不一樣的。

WHILE語句是當滿足條件時,執行循環內的語句。

WHILE語句的基本語法形式如下:

[begin_label:] WHILE search_condition DO 
statement_list 
END WHILE [end_label] 

其中,search_condition參數表示循環執行的條件,滿足該條件時循環執行;

statement_list參數表示循環的執行語句。

下面是一個ITERATE語句的示例。代碼如下:

WHILE @count<100 DO 
SET @count=@count+1; 
END WHILE ; 

該示例循環執行count加1的操作,count值小于100時執行循環。

如果count值等于100了,則跳出循環。WHILE循環需要使用END WHILE來結束。

?

轉載于:https://www.cnblogs.com/qlqwjy/p/7920012.html

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

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

相關文章

Java死鎖故障排除和解決

JavaOne年度會議的一大優點是&#xff0c;主題專家介紹了幾個技術和故障排除實驗室。 其中的一個實驗室今年特別吸引了我的注意力&#xff1a;“ HOL6500-查找和解決Java死鎖 ”&#xff0c;由Java冠軍Heinz Kabutz提出 。 這是我在該主題上看到的最好的演示之一。 我建議您自己…

java.util.scanner sc_關于Java的Scanner的問題,菜鳥求各大神解答

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓package leetcode;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.…

3. HTML中的容器標簽

什么是容器標簽&#xff1f;在HTML開發中我們常常會使用一類標簽作為容器放置一些內容&#xff0c;我們把這類標簽稱之為容器標簽&#xff0c;可以作為容器標簽的包括列表標簽、表格標簽、框架標簽、布局標簽&#xff0c;在這里我們就來總結下這些內容。 列表標簽 1 <!-- 無…

python自帶sqlite庫_Python標準庫之sqlite3使用實例

Python自帶一個輕量級的關系型數據庫SQLite。這一數據庫使用SQL語言。SQLite作為后端數據庫&#xff0c;可以搭配Python建網站&#xff0c;或者制作有數據存儲需求的工具。SQLite還在其它領域有廣泛的應用&#xff0c;比如HTML5和移動端。Python標準庫中的sqlite3提供該數據庫的…

GitHub上Java的Bloom Bloom實現

布隆過濾器是集數據結構的一種 。 對于那些不了解的對象&#xff0c;“設置數據結構”僅包含一個主要方法。 它僅用于確定特定元素是否包含在一組元素中。 大多數數據結構&#xff08;例如Hash Map &#xff0c; Linked List或Array &#xff09;都可以相當輕松地創建此函數。 …

Hibernate(十五):QBC檢索、本地SQL檢索和HQL刪除

QBC檢索QBC查詢就是通過使用Hibernate提供的Query By Criteria API來查詢對象&#xff0c;這種API封裝了SQL語句的動態拼裝&#xff0c;對查詢提供了更加面向對象的功能接口。 1&#xff09;通過Critera實現具有條件的查詢 1 Test2 public void testCriteria00() {3 …

java 創建連接池失敗_java-Presto JDBC連接池創建錯誤“不支持禁用...

我正在嘗試使用Spring-JDBC連接到Presto,并且我正在使用Hikari CP作為數據源.這是我的配置&#xff1a;Beanpublic DataSource myDataSource() {HikariDataSource hikariDataSource new HikariDataSource();hikariDataSource.setDriverClassName("com.facebook.presto.jd…

ni軟件管理器_NI 技術支持丨我的 NI 硬件設備不能被識別,怎么辦?Windows

這篇指南可以幫助您解決在您的 Windows 系統上無法識別您的 NI 硬件有關的問題。癥狀包括以下幾種情況&#xff1a;連接至 USB 端口時&#xff0c;硬件上的 LED 燈不亮/不閃爍。連接至 USB 后已連接設備的 LED 燈持續閃爍。僅限音頻接口&#xff1a;該設備在音頻應用程序或 Win…

環境搭建相關

1.檢測jre運行環境 java -version 沒有的話 按照提示安裝 default-jre 夠用 http://www.linuxidc.com/Linux/2016-11/136958.htm 否則按照上面處理 2.pycharm下載 https://www.jetbrains.com/pycharm/download/ 選擇下載一個linux的 3.下載crackjar http://idea.lanyus.com/jar…

在Java應用程序中使用密碼學

這篇文章描述了如何使用Java密碼體系結構 &#xff08;JCA&#xff09;&#xff0c;該體系結構使您可以在應用程序中使用密碼服務。 Java密碼體系結構服務 JCA提供了許多加密服務&#xff0c;例如消息摘要和簽名 。 這些服務可以通過特定于服務的API來訪問&#xff0c;例如Me…

CSS學習筆記-04 a標簽-導航練習

個人練習&#xff0c;各位大神勿笑 。。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&qu…

AngularJs簡介

AngualrJs是一個javascript框架&#xff0c;它通過<script>標簽加到HTML頁面中。 Angular通過指令拓展了HTML&#xff0c;且通過表達式綁定數據到HTML。 Angular是一個javascript框架 Angular是一個javascript框架。它是一個以javascript編寫的庫。 Angular是以一個javas…

java怎樣訪問servlet_如何訪問URL并從java servlet獲取響應?

你需要做這樣的事情import java.io.*;import java.net.URL;import java.net.URLConnection;import javax.servlet.http.*;import javax.servlet.*;public class URLServlet extends HttpServlet {public void doGet(HttpServletRequest req, HttpServletResponse res)throws Se…

深度學習loss值變為0_利用TensorFlow2.0為膽固醇、血脂、血壓數據構建時序深度學習模型(python源代碼)...

背景數據描述膽固醇、高血脂、高血壓是壓在廣大中年男性頭上的三座大山&#xff0c;如何有效的監控他們&#xff0c;做到早發現、早預防、早治療尤為關鍵&#xff0c;趁著這個假期我就利用TF2.0構建了一套時序預測模型&#xff0c;一來是可以幫我預發疾病&#xff0c;二來也可以…

在Spring MVC Web應用程序中使用reCaptcha

CAPTCHA是一種程序&#xff0c;可以生成人類可以通過的測試并對其進行評分&#xff0c;而計算機程序“ 不能 ”通過。 所采取的策略之一是向用戶顯示具有扭曲文本的圖像&#xff0c;并且用戶應在輸入區域中書寫文本。 如果顯示的文字與用戶輸入的文字相同&#xff0c;則我們可以…

洛谷 P1757 通天之分組背包

P1757 通天之分組背包 題目背景 直達通天路小A歷險記第二篇 題目描述 自01背包問世之后&#xff0c;小A對此深感興趣。一天&#xff0c;小A去遠游&#xff0c;卻發現他的背包不同于01背包&#xff0c;他的物品大致可分為k組&#xff0c;每組中的物品相互沖突&#xff0c;現在&a…

課時109.外邊距合并現象(掌握)

我們先寫一個案例&#xff0c;通過案例來了解 它們之間的水平距離就是兩個間距的和 我們看完水平再來看垂直方向 在默認布局的垂直方向上&#xff0c;默認情況下外邊距是不會疊加的&#xff0c;會出現合并現象&#xff0c;誰的外邊距比較大就聽誰的 本文轉載于:猿2048?https:…

純 CSS實現三角形

最近項目上做評論回復&#xff0c;設計師提高交互性特意設計了小三角&#xff0c;如下&#xff1a; 下面介紹一下實現效果的css方法&#xff1a; 1.border 通過設置上下左右border寬度來實現。 首先查看一下全部設置的效果&#xff1a; <style>   .triangle{     w…

python access_Python3 os.access() 方法

Python3 os.access() 方法概述os.access() 方法使用當前的uid/gid嘗試訪問路徑。大部分操作使用有效的 uid/gid, 因此運行環境可以在 suid/sgid 環境嘗試。語法access()方法語法格式如下&#xff1a;os.access(path, mode);參數path -- 要用來檢測是否有訪問權限的路徑。mode -…

小米的java待遇怎么樣_【Java工資】小米2021年Java工資待遇-看準網

已經不是面試官遲到的問題了&#xff0c;是約好了面試時間&#xff0c;結果徹底沒有然后了&#xff0c;這種言而無信我頭一回見。小米運營部門令人困惑的工作作風&#xff0c;簡單總結一句就是&#xff1a;敷衍不走心&#xff0c;面試規則內部都不統一。兩次面小米&#xff0c;…