1. 程式人生 > >資料庫中函式和儲存過程的區別總結

資料庫中函式和儲存過程的區別總結

資料庫的使用中,經常用到函式和儲存過程。都是為了實現某個sql功能,那麼這兩者有區別嗎?都適用哪些場景?總結如下
總的來說函式限制比較多,如不能用臨時表,只能用表變數等,而儲存過程的限制相對就比較少。

1.儲存過程實現的功能要複雜一點,而函式的實現的功能針對性比較強。

2.對於儲存過程來說可以返回引數,而函式只能返回值或者表物件。

3.儲存過程一般是作為一個獨立的部分來執行,而函式可以作為查詢語句的一個部分來呼叫,由於函式可以返回一個表物件,因此它可以在查詢語句中位於FROM關鍵字的後面。

4.當儲存過程和函式被執行的時候,SQLManager會到procedurecache中去取相應的查詢語句,如果在procedurecache裡沒有相應的查詢語句,SQLManager就會對儲存過程和函式進行編譯。

Procedurecache:中儲存的是執行計劃,當編譯好之後就執行procedurecache中的executionplan,之後SQLSERVER會根據每個executionplan的實際情況來考慮是否要在cache中儲存這個plan,評判的標準一個是這個executionplan可能被使用的頻率;其次是生成這個plan的代價,也就是編譯的耗時。儲存在cache中的plan在下次執行時就不用再編譯了。

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

儲存過程:可以使得對的管理、以及顯示關於及其使用者資訊的工作容易得多。儲存過程是SQL語句和可選控制流語句的預編譯集合,以一個名稱儲存並作為一個單元處理。儲存過程儲存在資料庫內,可由應用程式通過一個呼叫執行,而且允許使用者宣告變數、有條件執行以及其它強大的程式設計功能。儲存過程可包含程式流、邏輯以及對資料庫的查詢。它們可以接受引數、輸出引數、返回單個或多個結果集以及返回值。

可以出於任何使用SQL語句的目的來使用儲存過程,它具有以下優點:

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

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

(3)可以從自己的儲存過程內引用其它儲存過程,這可以簡化一系列複雜語句。

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

(5)可以有多個返回值,即多個輸出引數,並且可以使用SELECT返回結果集。

函式:是由一個或多個SQL語句組成的子程式,可用於封裝程式碼以便重新使用。自定義函式諸多限制,有許多語句不能使用,許多功能不能實現。函式可以直接引用返回值,用表變數返回記錄集。但是,使用者定義函式不能用於執行一組修改全域性資料庫狀態的操作。

注意:雖然“可以處於任何使用SQL語句的目的來使用儲存過程”。但是,有些時候有些地方使用函式或許會更方便些。例如,存在這樣一個表:Temp_table (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
Temp_table
WHERE
Year=2008
AND Month=5;

如果不考慮空值的話,這樣完全正確,但是考慮空值的話,如果根本沒有統計02時的溫度,那麼AVG(T02)將為NULL,然後進行所有運算的結果都將為NULL。這顯然是不正確的。

這裡可以建立一個自定義函式,然後使用一個SELECT語句即可查詢:

SELECT
AVG(user.Average(T02,T08,T14,T20)
FROM
Temp_table
WHER
EYear=2008
ANDMonth=5;

總結:

使用者自定義函式在處理同一資料行中的各個欄位時,特別方便有用。雖然這裡使用儲存過程也能達到查詢目的,但是顯然沒有使用函式方便。而且,即使使用儲存過程也無法處理SELECT查詢中的同一資料行中的各個欄位的運算。因為儲存過程不返回值,使用時只能單獨呼叫;而函式卻能出現在能放置表示式的任何位置。