| 類型 | 回傳值 | 特點 |
|---|---|---|
| 標量函數 | 單一標量值 | 類似內建函數 (如 GETDATE()),可在 SELECT/WHERE/CASE 中使用 |
| 內嵌表值函數 | TABLE (單一 SELECT) | 效能最佳,優化器可展開查詢計畫,參數化視圖 |
| 多陳述式表值函數 | TABLE (變數表) | 邏輯複雜時使用,支援多步驟、流程控制,但無法展開計畫 |
CREATE FUNCTION [schema.]function_name
( [ @param_name [AS] scalar_type [ = default ] [ ,...n ] ] )
RETURNS { scalar_type | TABLE }
[ WITH [ ,...n ] ]
[ AS ]
BEGIN
function_body
RETURN { scalar_expr | } -- 標量/多陳述式需 RETURN
END
WITHENCRYPTION:加密函數定義 (隱藏邏輯)。SCHEMABINDING:綁定參考物件結構,防止被誤刪/修改導致函數失效。CREATE FUNCTION dbo.fn_TaxPrice(@Price MONEY, @TaxRate FLOAT = 0.05)
RETURNS MONEY
WITH SCHEMABINDING
AS
BEGIN
RETURN ROUND(@Price * (1 + @TaxRate), 2);
END
GO
-- 呼叫
SELECT dbo.fn_TaxPrice(100, 0.05); -- 105.00
CREATE FUNCTION dbo.fn_ProductsByCategory(@CatID INT)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT ProductID, ProductName, UnitPrice
FROM dbo.Products
WHERE CategoryID = @CatID
);
GO
-- 呼叫 (如資料表)
SELECT * FROM dbo.fn_ProductsByCategory(1);
CREATE FUNCTION dbo.fn_DateRange(@Start DATE, @End DATE)
RETURNS @Dates TABLE (Dt DATE PRIMARY KEY)
AS
BEGIN
DECLARE @Cur DATE = @Start;
WHILE @Cur <= @End
BEGIN
INSERT @Dates VALUES (@Cur);
SET @Cur = DATEADD(DAY, 1, @Cur);
END
RETURN;
END
GO
-- 呼叫
SELECT * FROM dbo.fn_DateRange('2023-01-01', '2023-01-07');
ALTER FUNCTION dbo.fn_TaxPrice ... -- 修改
DROP FUNCTION dbo.fn_TaxPrice; -- 刪除
SELECT dbo.fn_Name(...) 或 EXEC @ret = dbo.fn_Name ... (僅標量)。SELECT * FROM dbo.fn_Name(...) (FROM 子句)。GETDATE(), NEWID(), RAND()) —— 除非 WITH SCHEMABINDING 未指定且為多陳述式表值函數 (2005+ 放寬)。APPLY / 內嵌表值 / 直接內聯運算式。SCHEMABINDING 獲得穩定性與潛在優化。UDF 是封裝可重用邏輯的利器,選對類型、避開 RBAR 陷阱,能讓 T-SQL 程式碼更模組化、可維護。