Khi bạn tạo một hàm giá trị bảng (TVF) trong SQL Server, bạn có thể làm cho nó trở thành một hàm giá trị bảng nội tuyến (ITVF) hoặc một hàm giá trị bảng nhiều câu lệnh (MSTVF). Có sự khác biệt giữa các loại hàm này và chúng sử dụng một cú pháp khác cho phù hợp.
Bài viết này đề cập đến sự khác biệt giữa MSTVF và ITVF.
Sự khác biệt
Dưới đây là những điểm khác biệt chính giữa MSTVF và ITVF.
ITVF | MSTVF | |
---|---|---|
Cú pháp RETURNS | Bạn chỉ cần nêu RETURNS TABLE và định nghĩa của bảng trả về sẽ dựa trên SELECT của hàm tuyên bố. Không cần chỉ định cấu trúc của bảng trả về. | RETURNS của bạn cú pháp xác định rõ ràng cấu trúc của bảng trả về. Điều này được thực hiện bằng cách khai báo một biến TABLE sẽ được sử dụng để lưu trữ và tích lũy các hàng được trả về dưới dạng giá trị của hàm. |
Cú pháp BEGIN / END | ITVF không sử dụng BEGIN / END cú pháp. | MSTVF sử dụng BEGIN / END cú pháp. |
Hiệu suất | Nói chung nhanh hơn MTSVFs. | Nói chung chậm hơn ITVF. |
Cập nhật dữ liệu | Trong một số trường hợp, có thể cập nhật dữ liệu trong các bảng bên dưới bằng ITFV. | Bạn không thể cập nhật dữ liệu trong các bảng bên dưới bằng MSTVF. |
Cú pháp
Hãy xem xét sự khác biệt trong cú pháp của từng loại hàm.
Hàm định giá trong bảng nội tuyến
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [ READONLY ] } [ ,...n ] ] ) RETURNS TABLE [ WITH <function_option> [ ,...n ] ] [ AS ] RETURN [ ( ] select_stmt [ ) ] [ ; ]
Hàm đa giá trị trong bảng sao kê
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [READONLY] } [ ,...n ] ] ) RETURNS @return_variable TABLE <table_type_definition> [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
Lưu ý rằng MSTVF bắt đầu bằng định nghĩa bảng, nhưng ITVF không có định nghĩa như vậy.
MSTVF bắt đầu bằng RETURNS @return_variable TABLE
tiếp theo là định nghĩa bảng. Đây, @return_variable
là một biến TABLE, được sử dụng để lưu trữ và tích lũy các hàng sẽ được trả về dưới dạng giá trị của hàm.
Ví dụ 1 - Hàm Inline Table-Valued
Đây là một ví dụ về ITVF đơn giản.
CREATE FUNCTION udf_PetsByName_ITVF( @PetName varchar(70)) RETURNS TABLE AS RETURN ( SELECT CONCAT('Cat', ' ', CatId) AS PetId, CatName FROM dbo.Cats WHERE CatName = @PetName UNION ALL SELECT CONCAT('Dog', ' ', DogId) AS PetId, DogName FROM dbo.Dogs WHERE DogName = @PetName ); GO
Ở đây, tôi chọn từ hai bảng bằng cách sử dụng UNION ALL
và hàm chỉ trả về kết quả.
Ví dụ 2 - Chức năng có giá trị trong bảng đa câu lệnh
Dưới đây là một ví dụ về việc sử dụng MSTVF để làm điều tương tự, nhưng theo một cách khác.
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; RETURN; END; GO
Hàm bắt đầu với việc khai báo một biến TABLE có tên là @pets
. Khi làm điều này, chúng tôi chỉ định rõ ràng cấu trúc của bảng trả về.
Các truy vấn bên trong BEGIN
/ END
khối được lưu vào biến TABLE có tên là @pets
.
Trong trường hợp này, tôi đã chọn không sử dụng UNION ALL
. Thay vào đó, tôi thực hiện các câu lệnh riêng biệt và lưu kết quả của từng câu lệnh vào @pets
biến.
Ví dụ 3 - Thêm một câu lệnh khác vào MSTVF
Để chứng minh thêm về khía cạnh “nhiều câu lệnh” của MSTVF, chúng ta có thể thêm nhiều câu lệnh hơn vào MSTVF ở trên và lưu kết quả vào cùng một biến trả về.
Ví dụ:
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
Trong trường hợp này, tôi đã thêm một số mã để trả về một thông báo đặc biệt bất cứ khi nào kết quả truy vấn không có hàng nào được trả lại.