Sql-Server

函式和儲存過程有什麼區別?

  • June 25, 2015

聽說SQL Server中函式和儲存過程的區別是函式不儲存在數據庫中,而儲存過程儲存在數據庫中。

真的嗎?如果不是,它們之間有什麼區別?

另外,我知道儲存過程只編譯一次,然後直接執行。函式呢?

一個函式總是試圖返回一些東西,並且有幾個限制——例如,你不能有任何副作用,所以你不能發出 DML、呼叫儲存過程、使用動態 SQL、呼叫NEWID()等。你也不能有錯誤在函式內部定義的處理、事務或非確定性函式(例如GETDATE(),在舊版本中,至少在 SQL Server 2000 中 - 儘管有解決方法)。

函式有多種類型,主要是標量函式和表值函式。標量函式可以內聯呼叫,例如

CREATE FUNCTION dbo.PrettyDate(@d DATETIME)
RETURNS CHAR(10)
AS
BEGIN
   RETURN(SELECT CONVERT(CHAR(10), @d, 120));
END
GO

DECLARE @Date DATETIME = CURRENT_TIMESTAMP;
SELECT dbo.PrettyDate(@Date);

結果:

----------
2012-03-14

表值函式的呼叫方式需要稍有不同,因為它們的行為本質上類似於參數化視圖。例如:

CREATE FUNCTION dbo.DatesInRange
(
 @StartDate DATETIME,
 @EndDate   DATETIME
)
RETURNS TABLE  
AS  
 RETURN (SELECT [date] = DATEADD(DAY, n-1, @StartDate)
   FROM (SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id])
     FROM sys.objects) AS x
     WHERE n <= DATEDIFF(DAY, @StartDate, @EndDate) + 1
 );
GO

SELECT [date] 
 FROM dbo.DatesInRange('20120101', '20120105')
 ORDER BY [date];

結果:

date
-----------------------
2012-01-01 00:00:00.000
2012-01-02 00:00:00.000
2012-01-03 00:00:00.000
2012-01-04 00:00:00.000
2012-01-05 00:00:00.000

儲存過程不一定返回數據,但它可以返回多個結果集。可以用來影響數據(更新/插入/刪除)等副作用,可以包含動態SQL,可以有事務,可以有錯誤處理,對非確定性函式沒有限制,可以呼叫其他儲存過程。

編輯

我不太確定“函式不儲存在數據庫中”是什麼意思。當您創建儲存過程或函式時,它的定義肯定會儲存在目錄視圖sys.sql_modules中,並且會在 中創建對模組的引用sys.objects。儲存過程有一個sys.procedures單獨sys.objects的目錄視圖IFFN``TF

我將回到問題的編譯部分。

這是錯誤的:儲存過程和函式都儲存在數據庫中;函式不能包含 INSERT 或 UPDATE 命令,它們僅用於計算某些值,並且可以在返回記錄集時在 SELECT 中使用。您可以在此處閱讀有關差異以及何時使用 SP 或函式的更多資訊:

http://web.archive.org/web/20150511155511/http://databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html

引用自:https://dba.stackexchange.com/questions/14980