數(shù)據(jù)庫(kù)中存儲(chǔ)過(guò)程和函數(shù)的區(qū)別
函數(shù)限制比較多,如不能用臨時(shí)表,只能用表變量等,而存儲(chǔ)過(guò)程的限制相對(duì)就比較少。
1.一般來(lái)說(shuō),存儲(chǔ)過(guò)程實(shí)現(xiàn)的功能要復(fù)雜一點(diǎn),而函數(shù)的實(shí)現(xiàn)的功能針對(duì)性比較強(qiáng)。
2.對(duì)于存儲(chǔ)過(guò)程來(lái)說(shuō)可以返回參數(shù),而函數(shù)只能返回值或者表對(duì)象。
3.存儲(chǔ)過(guò)程一般是作為一個(gè)獨(dú)立的部分來(lái)執(zhí)行,而函數(shù)可以作為查詢語(yǔ)句的一個(gè)部分來(lái)調(diào)用,由于函數(shù)可以返回一個(gè)表對(duì)象,因此它可以在查詢語(yǔ)句中位于FROM關(guān)鍵字的后面。
4.當(dāng)存儲(chǔ)過(guò)程和函數(shù)被執(zhí)行的時(shí)候,SQLManager會(huì)到procedurecache中去取相應(yīng)的查詢語(yǔ)句,如果在procedurecache里沒有相應(yīng)的查詢語(yǔ)句,SQLManager就會(huì)對(duì)存儲(chǔ)過(guò)程和函數(shù)進(jìn)行編譯。
Procedurecache:中保存的是執(zhí)行計(jì)劃,當(dāng)編譯好之后就執(zhí)行procedurecache中的executionplan,之后SQLSERVER會(huì)根據(jù)每個(gè)executionplan的實(shí)際情況來(lái)考慮是否要在cache中保存這個(gè)plan,評(píng)判的標(biāo)準(zhǔn)一個(gè)是這個(gè)executionplan可能被使用的頻率;其次是生成這個(gè)plan的代價(jià),也就是編譯的耗時(shí)。保存在cache中的plan在下次執(zhí)行時(shí)就不用再編譯了。
存儲(chǔ)過(guò)程和函數(shù)具體的區(qū)別:
存儲(chǔ)過(guò)程:可以使得對(duì)的管理、以及顯示關(guān)于及其用戶信息的工作容易得多。存儲(chǔ)過(guò)程是SQL語(yǔ)句和可選控制流語(yǔ)句的預(yù)編譯集合,以一個(gè)名稱存儲(chǔ)并作為一個(gè)單元處理。存儲(chǔ)過(guò)程存儲(chǔ)在數(shù)據(jù)庫(kù)內(nèi),可由應(yīng)用程序通過(guò)一個(gè)調(diào)用執(zhí)行,而且允許用戶聲明變量、有條件執(zhí)行以及其它強(qiáng)大的編程功能。存儲(chǔ)過(guò)程可包含程序流、邏輯以及對(duì)數(shù)據(jù)庫(kù)的查詢。它們可以接受參數(shù)、輸出參數(shù)、返回單個(gè)或多個(gè)結(jié)果集以及返回值。
可以出于任何使用SQL語(yǔ)句的目的來(lái)使用存儲(chǔ)過(guò)程,它具有以下優(yōu)點(diǎn):
(1)功能強(qiáng)大,限制少。
(2)可以在單個(gè)存儲(chǔ)過(guò)程中執(zhí)行一系列SQL語(yǔ)句。
(3)可以從自己的存儲(chǔ)過(guò)程內(nèi)引用其它存儲(chǔ)過(guò)程,這可以簡(jiǎn)化一系列復(fù)雜語(yǔ)句。
(4)存儲(chǔ)過(guò)程在創(chuàng)建時(shí)即在上進(jìn)行編譯,所以執(zhí)行起來(lái)比單個(gè)SQL語(yǔ)句快。
(5)可以有多個(gè)返回值,即多個(gè)輸出參數(shù),并且可以使用SELECT返回結(jié)果集。
函數(shù):是由一個(gè)或多個(gè)SQL語(yǔ)句組成的子程序,可用于封裝代碼以便重新使用。自定義函數(shù)諸多限制,有許多語(yǔ)句不能使用,許多功能不能實(shí)現(xiàn)。函數(shù)可以直接引用返回值,用表變量返回記錄集。但是,用戶定義函數(shù)不能用于執(zhí)行一組修改全局?jǐn)?shù)據(jù)庫(kù)狀態(tài)的操作。
補(bǔ)充:
前面有一句,“可以處于任何使用SQL語(yǔ)句的目的來(lái)使用存儲(chǔ)過(guò)程”。這里想說(shuō)的是,有些時(shí)候有些地方使用函數(shù)或許會(huì)更方便些。例如,存在這樣一個(gè)表:Temperature(Year,Month,Day,T02,T08,T14,T20),其中Year,Month,Day是時(shí)間字段,T02,T08,T14,T20是指2時(shí)、8時(shí)、14時(shí)、20時(shí)四個(gè)時(shí)刻對(duì)應(yīng)的溫度值,這些溫度值可為空。現(xiàn)在,要求統(tǒng)計(jì)2008年5月份的平均溫度。
或許大家會(huì)這樣寫:
SELECT(AVG(T02)+AVG(T08)+AVG(T14)+AVG(T20))/4FROMTemperatureWHEREYear=2008ANDMonth=5
如果不考慮空值的話,這樣完全正確,但是考慮空值的話,如果根本沒有統(tǒng)計(jì)02時(shí)的溫度,那么AVG(T02)將為NULL,然后進(jìn)行所有運(yùn)算的結(jié)果都將為NULL。這顯然是不正確的。
這里可以創(chuàng)建一個(gè)自定義函數(shù),然后使用一個(gè)SELECT語(yǔ)句即可查詢:
SELECTAVG(user.Average(T02,T08,T14,T20)FROMTemperatureWHEREYear=2008ANDMonth=5
總結(jié):
用戶自定義函數(shù)在處理同一數(shù)據(jù)行中的各個(gè)字段時(shí),特別方便有用。雖然這里使用存儲(chǔ)過(guò)程也能達(dá)到查詢目的,但是顯然沒有使用函數(shù)方便。而且,即使使用存儲(chǔ)過(guò)程也無(wú)法處理SELECT查詢中的同一數(shù)據(jù)行中的各個(gè)字段的運(yùn)算。因?yàn)榇鎯?chǔ)過(guò)程不返回值,使用時(shí)只能單獨(dú)調(diào)用;而函數(shù)卻能出現(xiàn)在能放置表達(dá)式的任何位置。
【編輯推薦】