日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例

發布時間:2024/4/14 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一個存儲過程是一個可編程的函數,它可以在MySQL中創建并保存。它是由一些SQL語句和一些特殊的控制結構語句組成。

當希望在不同的應用程序或平臺上執行相同的函數,或者封裝特定的功能時,存儲過程是一個非常有用的方式。數據庫中的存儲過程可以看做是對編程中面向對象方法的模擬。

基本示例total_ordres

delimiter?//

create?procedure?total_orders?(out?total?float)

BEGIN

select?sum(amount)??into?total?from?orders;

END

//

delimiter?;

下面,讓我們來逐行分析以上代碼:

第一行語句:

delimiter?//

將語句末尾的分隔符從默認值(MySQL的默認分隔符為 ; )改變為// 。這樣做的目的是可以在存儲過程中使用分號分隔符,這樣MySQL就會將分號作為存儲過程的代碼,從而不會立即執行。

接下來的語句:

create?procedure?total_ordres??(out?total?float)

定義一個存儲過程。該存儲過程的名稱是 total_orders ,它只有一個total參數,該參數是最后得到結果的值。out表示該參數將被 傳出 或 返回。這里也可以聲明為 in ,表示該值必須傳入到存儲過程中。或者 inout 表示該值必須傳入但是可以被存儲過程修改。

float 表示參數的類型。

如果希望使用多個參數,可以提供一個由逗號間隔的參數列表,就像在PHP中一樣。 過程體必須封裝在BEGIN ?END 語句中。

在聲明了過程后,可以將分隔符重新設置為分號:

delimiter?;

在過程聲明了之后,可以用call 關鍵字調用該過程:

call??total_orders(@h);

這個語句將調用total_orders 過程,并且傳入一個用來保存結果的變量。

要查看該變量,如下語句所示:

select?@h?;

函數

與創建過程的方法類似,還可以創建一個函數。函數接收輸入參數并且返回一個唯一值。創建函數的基本語法幾乎相同。

delimiter?//

create?function?add_tax?(price?float)??retuns?float

return?price*1.1?;

delimiter?;

可以看到,該示例使用了function關鍵字。而不是之前的procedure 關鍵字。此外,二者還存在一些其他差異。

參數不必通過IN 或 OUT來指定,因為在函數中所有參數都是IN 或輸入參數。在參數列表之后是returns float子句,它指定了返回值的類型。需要再次提到的是,該值可以是任何有效的MySQL類型。

使用return 語句可以返回一個值,就像PHP中所介紹的一樣。

請注意,這個示例中并沒有使用BEGIN 和 END語句。當然可以使用它們,但是它們并不是必需的。就像PHP中,如果一個語句塊只包含了一個語句,那么該語句塊的開始和結束標記可以省略。

調用函數 與 調用過程 存在一些差異。可以調用內置函數的相同方式調用一個存儲函數。

select?add_tax(100);

該語句的返回如下所示:

+-------------------+

| add_tax(100) |

+-------------------+

| ? ? ? ? ? ? ? ?110 |

+-------------------+

在定義了存儲過程 和 存儲函數之后,可以使用如下所示的語句來查看定義這些過程和函數的代碼:

show?create?procedure?total_orders;

或者

show?create?function?add_tax;

也可以使用如下語句來刪除它們:

drop?procedure?total_orders;

或者

drop?function?add_tax;

存儲過程提供了使用控制結構、變量、DECLARE句柄(就像異常)的功能,以及游標這個重要概念。

在接下來的文章中,我們將簡單介紹這些概念。

局部變量

使用declare語句,可以在BEGIN ... END語句塊中聲明局部變量。

例如,可以對add_tax函數進行修改,使其使用一個局部變量來保存稅率。

示例:

delimiter?//

create?function?add_tax?(price?float)?returns?float

begin

declare?tax?float?default?0.10;

return?price*(1+tax);

end

//

delimiter?;

正如你看到的,我們使用了declare關鍵字以及變量名稱和變量類型聲明了該局部變量。

default子句是可選的,它指定了該變量的初始值。現在可以開始使用這個變量了。

游標 和 控制結構

現在,讓我們來分析一個更復雜的例子。在這個例子中,我們將編寫一個存儲過程,該存儲過程將計算出最大金額的訂單,并且返回該訂單的orderid(很明顯,這可以通過一個簡單的查詢就可以得出結果,但是這個簡單的示例只是為了說明如何使用游標 和 控制結構)。

代碼如下:

delimiter?//

create?procedure?largest_order?(out?largest_id??int)

begin

declare?this_id?int;

declare?this_amount?float;

declare?l_amount?float?default?0.0;

declare?l_id?int;

declare?done?int?default?0;

declare?c1?cursor?for?select?orderid,?amount??from??orders;

declare?continue?handle?for?sqlstate?'02000'??set?done?=?1?;

open?c1?;

repeat

fetch?c1??into??this_id?,?this_amount?;

if?not?done?then

if?this_amount?>?l_amount??then

set?l_amount?=?this_amount?;

set?l_id??=?this_id?;

end?if;

end?if;

until??done?end??repear;

close?c1?;

set?largest_id?=?l_id?;

end

//

delimiter?;

以上代碼使用了控制語句(條件語句和循環語句)、游標 和 聲明句柄。下面我們逐行分析以上代碼。

this_id 和 this_amount變量保存了當前行orderid 和 amount值。 l_amount 和 l_id 變量用來存儲最大的訂單金額和與之對應的ID。

下一個變量被聲明為done ,初始化為0 。這個變量是循環標記。當遍歷了所有需要查看的行,可以將該變量設置為1 (True)。

declare?continue?handle?for?sqlstate?'02000'??set?done?=?1?;

是一個聲明句柄。它類似于存儲過程中的一個異常。在continue句柄和 exit句柄中,也可以使用它。就像以上代碼所顯示的,continue 句柄執行了指定的動作,并且繼續存儲過程的執行。 exit句柄將從最近的begin...end代碼中退出。

聲明句柄的下一個部分指定了句柄被調用的時間。在這個例子中,該句柄將在sqlstate '02000' 語句被執行時調用。 你可能會奇怪,這是個什么意思,因為該語句非常神秘。這意味著,該句柄將在無法再得到記錄行之后被調用。我們將逐行處理一個結果集,而且當遍歷了所有需要處理的記錄時,這個句柄才會被調用。 ?也可以指定等價的 FOR NOT FOUND語句。其他選項還包括SQLWARNING 和 SQLEXCEPTION 。

接下來就是游標。一個游標類似于一個數組;它將從一個查詢中獲得結果集,并且允許一次只處理一行。分析以下游標:

declare?c1??cursor??for?select??orderid,?amount??from?orders?;

這個游標名稱為 c1 。它只是將要保存內容的定義。該查詢還不會被執行。

接下來一行代碼:

open??c1?;

真正運行這個查詢。要獲得每一個數據行,必須運行一個 fetch 語句。可以在repeat 循環中完成此操作。

在這個例子中,循環語句如下所示:

repeat

....

until??done?end??repeat?;

請注意,只有在循環語句塊的末尾才會檢查循環條件。

存儲過程還支持while 循環,如下所示:

while??condition??do

....

end?while

此外,還支持loop循環語句,如下所示:

loop

....

end??loop

這些循環沒有內置的循環條件,但是可以通過 leave 語句退出循環。

請注意,存儲過程不支持 for 循環。

繼續這個例子,一下代碼將獲得一個數據行:

fetch??c1??into??thid_id,??this_amount?;

以上代碼將從游標查詢中獲得一個數據行。該查詢所獲得的兩個屬性保存在兩個指定的局部變量中。

我們可以檢查一個數據航是否被獲得,然后再將當前循環量與最大的存儲值進行比較,通過兩個 if 語句的方式,如下所示:

if??not??done??then

if??this_amount?>?l_amount??then

set?l_amount?=??this_amount?;

set?l_id?=??this_id?;

end?if?;

end??if?;

請注意,變量值將通過set 語句進行設置。

除了if ... then 語句外,存儲過程還支持 if ... then ... else 語句結構。如下所示:

if??condition??then

...

[elseif??condition?then]

...

[else]

...

end?if

此外,也可以使用case語句,如下形式所示:

case??value

when??value??then??statement

[when?value?then?statement?...?]

[else?statement]

end?case

回到這個例子,在循環語句末尾,將執行一些清除操作:

close?c1?;

set??largest_id?=?l_id?;

close語句將關閉這個游標。

最后,將所有計算出的最大值賦值給 OUT 參數。不能將該參數作為臨時變量,只能用來保存最終值。

如果按照以上方式創建了這個存儲過程,可以像調用其他存儲過程一樣調用這個存儲過程:

call??largest_order?(@k)?;

select?@k?;

將獲得類似于如下所示的輸出:

+--------+

| ?@k ? |

+--------+

| ?3 ? ? |

+--------+

你可以自己檢查計算結果是否正確。

總結

以上是生活随笔為你收集整理的mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。