存儲過程與函數的區別

原文地址:存儲過程與函數的區別做者:yu000hong

核心提示:本質上沒區別。只是函數有限制只能返回一個標量,而存儲過程能夠返回多個。而且函數是能夠嵌入在SQL中使用的,能夠在SELECT等SQL語句中調用,而存儲過程不行。執行的本質都同樣。html

 

    函數限制比較多,如不能用臨時表,只能用表變量等,而存儲過程的限制相對就比較少。數據庫

    1. 通常來講,存儲過程實現的功能要複雜一點,而函數的實現的功能針對性比較強。編程

    2. 對於存儲過程來講能夠返回參數,而函數只能返回值或者表對象。函數

    3. 存儲過程通常是做爲一個獨立的部分來執行,而函數能夠做爲查詢語句的一個部分來調用,因爲函數spa

       能夠返回一個表對象,所以它能夠在查詢語句中位於FROM關鍵字的後面htm

    4. 當存儲過程和函數被執行的時候,SQL Manager會到procedure cache中去取相應的查詢語句,若是在對象

       procedure cache裏沒有相應的查詢語句,SQL Manager就會對存儲過程和函數進行編譯。blog

Procedure cache:中保存的是執行計劃,當編譯好以後就執行procedure cache中的execution plan,以後SQL SERVER會根據每一個execution plan的實際狀況來考慮是否要在cache中保存這個plan,評判的標準一個是這個execution plan可能被使用的頻率;其次是生成這個plan的代價,也就是編譯的耗時。保存在cache中的plan在下次執行時就不用再編譯了。ip

存儲過程和函數具體的區別:ci

    存儲過程:可使得對的管理、以及顯示關於及其用戶信息的工做容易得多。存儲過程是 SQL 語句和可選控制流語句的預編譯集合,以一個名稱存儲並做爲一個單元處理。存儲過程存儲在數據庫內,可由應用程序經過一個調用執行,並且容許用戶聲明變量、 有條件執行以及其它強大的編程功能。存儲過程可包含程序流、邏輯以及對數據庫的查詢。它們能夠接受參數、輸出參數、返回單個或多個結果集以及返回值。

   能夠出於任何使用 SQL 語句的目的來使用存儲過程,它具備如下優勢

    (1)功能強大,限制少。

    (2)能夠在單個存儲過程當中執行一系列 SQL 語句。

    (3)能夠從本身的存儲過程內引用其它存儲過程,這能夠簡化一系列複雜語句。

    (4)存儲過程在建立時即在上進行編譯,因此執行起來比單個 SQL 語句快。

    (5)能夠有多個返回值,即多個輸出參數,而且可使用SELECT返回結果集。

 

    函數:是由一個或多個 SQL 語句組成的子程序,可用於封裝代碼以便從新使用。自定義函數諸多限制,有許多語句不能使用,許多功能不能實現。函數能夠直接引用返回值,用表變量返回記錄集。可是,用戶定義函數不能用於執行一組修改全局數據庫狀態的操做。 

 

補充:

    前面有一句,「能夠處於任何使用SQL語句的目的來使用存儲過程」。這裏想說的是,有些時候有些地方使用函數或許會更方便些。例如,存在這樣一個表:Temperature(Year, Month, Day, T02, T08, T14, T20),其中Year,Month,Day是時間字段,T02, T08, T14, T20是指2時、8時、14時、20時四個時刻對應的溫度值,這些溫度值可爲空。如今,要求統計2008年5月份的平均溫度。

    或許你們會這樣寫:

    SELECT (AVG(T02)+AVG(T08)+AVG(T14)+AVG(T20))/4 FROM Temperature WHERE Year=2008 AND Month=5

    若是不考慮空值的話,這樣徹底正確,可是考慮空值的話,若是根本沒有統計02時的溫度,那麼AVG(T02)將爲NULL,而後進行全部運算的結果都將爲NULL。這顯然是不正確的。

    這裏能夠建立一個自定義函數,而後使用一個SELECT語句便可查詢:

    SELECT AVG(user.Average(T02,T08,T14,T20)) FROM Temperature WHERE Year=2008 AND Month=5

總結:

   用戶自定義函數在處理同一數據行中的各個字段時,特別方便有用。雖然這裏使用存儲過程也能達到查詢目的,可是顯然沒有使用函數方便。並且,即便使用存儲過程也沒法處理SELECT查詢中的同一數據行中的各個字段的運算。由於存儲過程不返回值,使用時只能單獨調用;而函數卻能出如今能放置表達式的任何位置

 

CREATE FUNCTION user.Average

(

    @T02 float,

    @T08 float,

    @T14 float,

    @T20 float

)
RETURNS float AS 
BEGIN

DECLARE @sum float
DECLARE @num int
DECLARE @Ret float

SET @sum=0
SET @num=0

IF @T02 IS NOT NULL
BEGIN
    SET @sum = @sum + @T02
    SET @num = @num + 1
END

IF @T08 IS NOT NULL
BEGIN
    SET @sum = @sum + @T08
    SET @num = @num + 1
END

IF @T14 IS NOT NULL
BEGIN
    SET @sum = @sum + @T14
    SET @num = @num + 1
END

IF @T20 IS NOT NULL
BEGIN
    SET @sum = @sum + @T20
    SET @num = @num + 1
END

IF @num>0   SET @Ret = @sum / @num

Return @Ret

END

GO

相關文章
相關標籤/搜索