Lý do chính rất có thể là các Hàm có giá trị bảng trả về Tập kết quả, giống như Bảng và dạng xem. Điều này có nghĩa rằng chúng có thể được sử dụng trong các FROM
điều khoản (bao gồm cả JOIN
s và APPLY
s, vv) của SELECT
, UPDATE
và DELETE
truy vấn. Tuy nhiên, bạn không thể sử dụng UDF vô hướng trong bất kỳ bối cảnh nào.
Thứ hai, bạn cũng có thể là EXECUTE
một UDF vô hướng. Cú pháp này khá tiện lợi khi bạn có các giá trị mặc định được chỉ định cho các tham số đầu vào. Lấy UDF sau, ví dụ:
CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
RETURN @Param1 + @Param2;
END;
Nếu bạn muốn coi bất kỳ tham số đầu vào nào là "tùy chọn", bạn vẫn cần chuyển DEFAULT
từ khóa khi gọi nó như một hàm vì chữ ký được cố định:
DECLARE @Bob1 INT;
SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);
SELECT @Bob1;
-- Returns: 102
Mặt khác, nếu bạn EXECUTE
là hàm, thì bạn có thể coi bất kỳ tham số nào có giá trị mặc định là thực sự tùy chọn, giống như bạn có thể với Thủ tục lưu trữ. Bạn có thể truyền vào n tham số đầu tiên mà không chỉ định tên tham số:
DECLARE @Bob2 INT;
EXEC @Bob2 = dbo.OptionalParameterTest 50;
SELECT @Bob2;
-- Returns: 52
Bạn thậm chí có thể bỏ qua tham số đầu tiên bằng cách chỉ định lại tên tham số, giống như với Thủ tục lưu trữ:
DECLARE @Bob3 INT;
EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;
SELECT @Bob3;
-- Returns: 51
CẬP NHẬT
Tại sao bạn có thể muốn sử dụng EXEC
cú pháp để gọi UDF vô hướng giống như Thủ tục được lưu trữ? Đôi khi, có những UDF rất tuyệt vời khi có UDF vì chúng có thể được thêm vào một truy vấn và hoạt động trên tập hợp các hàng được trả về, trong khi nếu mã nằm trong Quy trình được lưu trữ thì nó cần phải được đặt vào một con trỏ để lặp đi lặp lại trên một tập hợp các hàng. Nhưng sau đó, có những lúc bạn muốn gọi hàm đó trên một giá trị duy nhất, có thể từ bên trong một UDF khác. Gọi UDF cho một giá trị có thể được thực hiện như sau:
SELECT dbo.UDF('some value');
trong trường hợp bạn nhận được giá trị trả về trong tập kết quả (tập kết quả sẽ không hoạt động). Hoặc nó có thể được thực hiện như sau:
DECLARE @Dummy INT;
SET @Dummy = dbo.UDF('some value');
trong trường hợp bạn cần khai báo @Dummy
biến;
TUY NHIÊN, với EXEC
cú pháp, bạn có thể tránh được cả hai điều phiền toái đó:
EXEC dbo.UDF 'some value';
CSONG, UDF vô hướng có kế hoạch thực thi của họ được lưu trữ. Điều này có nghĩa là có thể chạy vào các vấn đề đánh hơi tham số nếu có các truy vấn trong UDF có kế hoạch thực hiện. Đối với các kịch bản có thể sử dụng EXEC
cú pháp, thì cũng có thể sử dụng WITH RECOMPILE
tùy chọn để bỏ qua các giá trị được biên dịch cho các thực thi đó . Ví dụ:
THIẾT LẬP:
GO
CREATE FUNCTION dbo.TestUDF (@Something INT)
RETURNS INT
AS
BEGIN
DECLARE @Ret INT;
SELECT @Ret = COUNT(*)
FROM sys.indexes si
WHERE si.[index_id] = @Something;
RETURN @Ret;
END;
GO
KIỂM TRA:
DECLARE @Val INT;
SET @Val = dbo.TestUDF(1);
SELECT @Val;
EXEC @Val = dbo.TestUDF 0 -- uses compiled value of (1)
SELECT @Val;
EXEC @Val = dbo.TestUDF 0 WITH RECOMPILE; -- uses compiled value of (0)
SELECT @Val;
EXEC @Val = dbo.TestUDF 3 -- uses compiled value of (1)
SELECT @Val;