Bạn có thể tạo một hàm giá trị bảng nhiều câu lệnh (MSTVF) trong SQL Server bằng cách sử dụng T-SQL CREATE FUNCTION
cú pháp.
Cú pháp
Đây là cú pháp chính thức cho TVF nhiều câu lệnh.
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[ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
Ví dụ 1 - MSTVF cơ bản
Dưới đây là một ví dụ về hàm có giá trị trong bảng nhiều câu lệnh.
CREATE FUNCTION dbo.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
Cấu trúc của bảng trả về được xác định ngay từ đầu khi tôi chỉ định @pets
Biến đổi. Kết quả truy vấn được chèn vào @pets
biến.
Trong trường hợp này, hàm yêu cầu nhập tên vật nuôi làm đối số. Sau đó, nó sử dụng đối số này trong các truy vấn để trả về dữ liệu có liên quan. Là một đa -bảng câu lệnh có giá trị hàm, tôi có thể bao gồm nhiều câu lệnh trong định nghĩa của hàm.
Ví dụ 2 - Thêm liên kết giản đồ
Thông thường, một ý tưởng hay là lược đồ liên kết các chức năng của bạn bằng cách sử dụng SCHEMABINDING
lý lẽ.
Làm điều này sẽ đảm bảo rằng các bảng bên dưới không thể bị thay đổi theo cách có thể ảnh hưởng đến chức năng của bạn.
Nếu không có liên kết lược đồ, các bảng bên dưới có thể được sửa đổi hoặc thậm chí bị xóa. Làm điều này có thể phá vỡ chức năng.
Đây là chức năng tương tự, nhưng lần này có liên kết giản đồ:
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING 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
Lưu ý rằng tôi đã sử dụng tên gồm hai phần khi tham chiếu đến các bảng trong truy vấn của mình (tôi đã sử dụng dbo.Cats
và dbo.Dogs
khi tham chiếu bảng, thay vì chỉ Cats
hoặc Dogs
). Thực hiện điều này là một yêu cầu đối với lược đồ ràng buộc một đối tượng. Nếu bạn cố gắng liên kết lược đồ một đối tượng mà không sử dụng tên gồm hai phần, bạn sẽ gặp lỗi.
Bây giờ, lược đồ tôi đã ràng buộc hàm của mình, nếu tôi cố gắng bỏ bảng được tham chiếu trong định nghĩa của nó, tôi sẽ gặp lỗi:
DROP TABLE Dogs;
Kết quả:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.
Nhân tiện, đây là điều sẽ xảy ra nếu tôi cố gắng tạo hàm mà không sử dụng đặt tên hai phần:
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
Kết quả:
Msg 4512, Level 16, State 3, Procedure udf_PetsByName_MSTVF, Line 10 Cannot schema bind table valued function 'dbo.udf_PetsByName_MSTVF' because name 'Cats' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
Ví dụ 3 - Thêm mã hóa
Bạn cũng có thể mã hóa các chức năng của mình bằng cách sử dụng ENCRYPTION
lý lẽ.
Dưới đây là một ví dụ về mã hóa hàm:
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING, ENCRYPTION 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
Bây giờ tôi không thể xem định nghĩa của hàm.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');
Kết quả:
+--------------+ | definition | |--------------| | NULL | +--------------+
Tôi cũng nhận được thông báo lỗi khi cố gắng tập lệnh cho định nghĩa của hàm qua Azure Data Studio:
No script was returned when scripting as Create on object UserDefinedFunction
Lưu ý rằng văn bản của hàm được mã hóa vẫn có sẵn cho người dùng có đặc quyền có thể truy cập các bảng hệ thống qua cổng DAC hoặc truy cập trực tiếp vào các tệp cơ sở dữ liệu. Ngoài ra, người dùng có thể đính kèm trình gỡ lỗi vào quy trình máy chủ có thể truy xuất quy trình ban đầu từ bộ nhớ trong thời gian chạy.