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.