1.存儲過程是存儲在數(shù)據(jù)庫目錄中的一段聲明性SQL語句殿较。觸發(fā)器泽裳,其他存儲過程以及Java,Python增拥,PHP等應(yīng)用程序可以調(diào)用存儲過程啄巧。
2.MySQL存儲過程的優(yōu)點
通常存儲過程有助于提高應(yīng)用程序的性能。當創(chuàng)建掌栅,存儲過程被編譯之后秩仆,就存儲在數(shù)據(jù)庫中。 但是猾封,MySQL實現(xiàn)的存儲過程略有不同澄耍。 MySQL存儲過程按需編譯。 在編譯存儲過程之后晌缘,MySQL將其放入緩存中齐莲。 MySQL為每個連接維護自己的存儲過程高速緩存。 如果應(yīng)用程序在單個連接中多次使用存儲過程磷箕,則使用編譯版本选酗,否則存儲過程的工作方式類似于查詢。
存儲過程有助于減少應(yīng)用程序和數(shù)據(jù)庫服務(wù)器之間的流量岳枷,因為應(yīng)用程序不必發(fā)送多個冗長的SQL語句芒填,而只能發(fā)送存儲過程的名稱和參數(shù)呜叫。
存儲的程序?qū)θ魏螒?yīng)用程序都是可重用的和透明的。 存儲過程將數(shù)據(jù)庫接口暴露給所有應(yīng)用程序殿衰,以便開發(fā)人員不必開發(fā)存儲過程中已支持的功能朱庆。
存儲的程序是安全的。 數(shù)據(jù)庫管理員可以向訪問數(shù)據(jù)庫中存儲過程的應(yīng)用程序授予適當?shù)臋?quán)限闷祥,而不向基礎(chǔ)數(shù)據(jù)庫表提供任何權(quán)限娱颊。
3.MySQL存儲過程的缺點
如果使用大量存儲過程,那么使用這些存儲過程的每個連接的內(nèi)存使用量將會大大增加蜀踏。 此外维蒙,如果您在存儲過程中過度使用大量邏輯操作,則CPU使用率也會增加果覆,因為數(shù)據(jù)庫服務(wù)器的設(shè)計不當于邏輯運算颅痊。
存儲過程的構(gòu)造使得開發(fā)具有復(fù)雜業(yè)務(wù)邏輯的存儲過程變得更加困難。
很難調(diào)試存儲過程局待。只有少數(shù)數(shù)據(jù)庫管理系統(tǒng)允許您調(diào)試存儲過程斑响。不幸的是,MySQL不提供調(diào)試存儲過程的功能钳榨。
開發(fā)和維護存儲過程并不容易舰罚。開發(fā)和維護存儲過程通常需要一個不是所有應(yīng)用程序開發(fā)人員擁有的專業(yè)技能。這可能會導(dǎo)致應(yīng)用程序開發(fā)和維護階段的問題薛耻。
4.編寫一個存儲過程:
DELIMITER//
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END//
DELIMITER;
SQL
讓我們來詳細地說明上述存儲過程:
第一個命令是DELIMITER //营罢,它與存儲過程語法無關(guān)。DELIMITER語句將標準分隔符 - 分號(;)更改為://饼齿。 在這種情況下饲漾,分隔符從分號(;)更改為雙斜杠//。為什么我們必須更改分隔符缕溉? 因為我們想將存儲過程作為整體傳遞給服務(wù)器考传,而不是讓mysql工具一次解釋每個語句。 在END關(guān)鍵字之后证鸥,使用分隔符//來指示存儲過程的結(jié)束僚楞。 最后一個命令(DELIMITER;)將分隔符更改回分號(;)。
使用CREATE PROCEDURE語句創(chuàng)建一個新的存儲過程枉层。在CREATE PROCEDURE語句之后指定存儲過程的名稱泉褐。在這個示例中,存儲過程的名稱為:GetAllProducts鸟蜡,并把括號放在存儲過程的名字之后膜赃。
BEGIN和END之間的部分稱為存儲過程的主體。將聲明性SQL語句放在主體中以處理業(yè)務(wù)邏輯矩欠。 在這個存儲過程中财剖,我們使用一個簡單的SELECT語句來查詢products表中的數(shù)據(jù)。
CALL GetAllProducts(); 調(diào)用存儲過程
5.聲明變量
聲明變量
要在存儲過程中聲明一個變量癌淮,可以使用DECLARE語句躺坟,如下所示:
DECLARE variable_name? datatype(size) DEFAULTdefault_value;
SQL
下面來更詳細地解釋上面的語句:
首先,在DECLARE關(guān)鍵字后面要指定變量名乳蓄。變量名必須遵循MySQL表列名稱的命名規(guī)則咪橙。
其次,指定變量的數(shù)據(jù)類型及其大小虚倒。變量可以有任何MySQL數(shù)據(jù)類型美侦,如INT,VARCHAR魂奥,DATETIME等菠剩。
第三,當聲明一個變量時耻煤,它的初始值為NULL具壮。但是可以使用DEFAULT關(guān)鍵字為變量分配默認值。
分配變量值
當聲明了一個變量后哈蝇,就可以開始使用它了棺妓。要為變量分配一個值,可以使用SET語句炮赦,例如:
DECLARE total_count INTDEFAULT 0;
SET total_count=10;
SQL
上面語句中怜跑,分配total_count變量的值為10。
變量范圍(作用域)
一個變量有自己的范圍(作用域)吠勘,它用來定義它的生命周期性芬。 如果在存儲過程中聲明一個變量,那么當達到存儲過程的END語句時看幼,它將超出范圍批旺,因此在其它代碼塊中無法訪問。
如果您在BEGIN END塊內(nèi)聲明一個變量诵姜,那么如果達到END汽煮,它將超出范圍。 可以在不同的作用域中聲明具有相同名稱的兩個或多個變量棚唆,因為變量僅在自己的作用域中有效暇赤。 但是,在不同范圍內(nèi)聲明具有相同名稱的變量不是很好的編程習慣宵凌。
以@符號開頭的變量是會話變量鞋囊。直到會話結(jié)束前它可用和可訪問。
6.存儲過程參數(shù)
MySQL存儲過程參數(shù)簡介
在現(xiàn)實應(yīng)用中瞎惫,開發(fā)的存儲過程幾乎都需要參數(shù)溜腐。這些參數(shù)使存儲過程更加靈活和有用译株。 在MySQL中,參數(shù)有三種模式:IN挺益,OUT或INOUT歉糜。
IN- 是默認模式。在存儲過程中定義IN參數(shù)時望众,調(diào)用程序必須將參數(shù)傳遞給存儲過程匪补。 另外,IN參數(shù)的值被保護烂翰。這意味著即使在存儲過程中更改了IN參數(shù)的值夯缺,在存儲過程結(jié)束后仍保留其原始值。換句話說甘耿,存儲過程只使用IN參數(shù)的副本踊兜。
OUT- 可以在存儲過程中更改OUT參數(shù)的值,并將其更改后新值傳遞回調(diào)用程序棵里。請注意润文,存儲過程在啟動時無法訪問OUT參數(shù)的初始值。
INOUT-INOUT參數(shù)是IN和OUT參數(shù)的組合殿怜。這意味著調(diào)用程序可以傳遞參數(shù)典蝌,并且存儲過程可以修改INOUT參數(shù)并將新值傳遞回調(diào)用程序。
在存儲過程中定義參數(shù)的語法如下:
MODE param_name param_type(param_size)
SQL
上面語法說明如下 -
根據(jù)存儲過程中參數(shù)的目的头谜,MODE可以是IN骏掀,OUT或INOUT。
param_name是參數(shù)的名稱柱告。參數(shù)的名稱必須遵循MySQL中列名的命名規(guī)則截驮。
在參數(shù)名之后是它的數(shù)據(jù)類型和大小。和變量一樣际度,參數(shù)的數(shù)據(jù)類型可以是任何有效的MySQL數(shù)據(jù)類型葵袭。
如果存儲過程有多個參數(shù),則每個參數(shù)由逗號(,)分隔乖菱。
7.IF語句使用:
8.case語句:
8存儲函數(shù):
存儲的函數(shù)是返回單個值的特殊類型的存儲程序坡锡。您使用存儲的函數(shù)來封裝在SQL語句或存儲的程序中可重用的常用公式或業(yè)務(wù)規(guī)則。
與存儲過程不同窒所,您可以在SQL語句中使用存儲的函數(shù)鹉勒,也可以在表達式中使用。 這有助于提高程序代碼的可讀性和可維護性吵取。
MySQL存儲函數(shù)語法
以下說明了創(chuàng)建新存儲函數(shù)的最簡單語法:
CREATE FUNCTION function_name(param1,param2…)
RETURNS datatype
[NOT] DETERMINISTIC
statements
SQL
首先禽额,在CREATE FUNCTION子句之后指定存儲函數(shù)的名稱。
其次皮官,列出括號內(nèi)存儲函數(shù)的所有參數(shù)脯倒。 默認情況下实辑,所有參數(shù)均為IN參數(shù)。不能為參數(shù)指定IN徙菠,OUT或INOUT修飾符。
第三郁岩,必須在RETURNS語句中指定返回值的數(shù)據(jù)類型。它可以是任何有效的MySQL數(shù)據(jù)類型缺狠。
第四问慎,對于相同的輸入?yún)?shù),如果存儲的函數(shù)返回相同的結(jié)果挤茄,這樣則被認為是確定性的如叼,否則存儲的函數(shù)不是確定性的。必須決定一個存儲函數(shù)是否是確定性的穷劈。 如果您聲明不正確笼恰,則存儲的函數(shù)可能會產(chǎn)生意想不到的結(jié)果,或者不使用可用的優(yōu)化歇终,從而降低性能社证。
第五,將代碼寫入存儲函數(shù)的主體中评凝。 它可以是單個語句或復(fù)合語句追葡。 在主體部分中,必須至少指定一個RETURN語句奕短。RETURN語句用于返回一個值給調(diào)用者宜肉。 每當?shù)竭_RETURN語句時,存儲的函數(shù)的執(zhí)行將立即終止翎碑。