Anda dapat membuat fungsi bernilai tabel multi-pernyataan (MSTVF) di SQL Server menggunakan CREATE FUNCTION T-SQL sintaks.
Sintaks
Inilah sintaks resmi untuk TVF multi-pernyataan.
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
[ ; ]
Contoh 1 – MSTVF Dasar
Berikut adalah contoh fungsi bernilai tabel multi-pernyataan.
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
Struktur tabel pengembalian ditentukan di awal ketika saya menentukan @pets variabel. Hasil kueri dimasukkan ke dalam @pets variabel.
Dalam hal ini, fungsi memerlukan nama hewan peliharaan yang diteruskan sebagai argumen. Kemudian menggunakan argumen ini dalam kueri untuk mengembalikan data yang relevan. Menjadi multi -fungsi bernilai tabel pernyataan, saya dapat menyertakan beberapa pernyataan dalam definisi fungsi.
Contoh 2 – Tambahkan Pengikatan Skema
Biasanya merupakan ide yang baik untuk mengikat skema fungsi Anda dengan menggunakan SCHEMABINDING argumen.
Melakukan ini akan memastikan bahwa tabel yang mendasarinya tidak dapat diubah dengan cara yang akan memengaruhi fungsi Anda.
Tanpa pengikatan skema, tabel yang mendasarinya dapat dimodifikasi atau bahkan dihapus. Melakukan hal ini dapat merusak fungsi.
Ini fungsinya sama, tapi kali ini dengan skema binding:
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
Perhatikan saya menggunakan nama dua bagian saat mereferensikan tabel dalam kueri saya (saya menggunakan dbo.Cats dan dbo.Dogs saat mereferensikan tabel, alih-alih hanya Cats atau Dogs ). Melakukan ini adalah persyaratan untuk skema yang mengikat objek. Jika Anda mencoba untuk mengikat skema objek tanpa menggunakan nama dua bagian, Anda akan mendapatkan kesalahan.
Sekarang saya telah mengikat skema fungsi saya, jika saya mencoba untuk menjatuhkan tabel yang dirujuk dalam definisinya, saya mendapatkan kesalahan:
DROP TABLE Dogs;
Hasil:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.
Omong-omong, inilah yang terjadi jika saya mencoba membuat fungsi tanpa menggunakan penamaan dua bagian:
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
Hasil:
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.
Contoh 3 – Tambahkan Enkripsi
Anda juga dapat mengenkripsi fungsi Anda menggunakan ENCRYPTION argumen.
Berikut ini contoh mengenkripsi fungsi:
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
Sekarang saya tidak dapat melihat definisi fungsi.
SELECT definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');
Hasil:
+--------------+ | definition | |--------------| | NULL | +--------------+
Saya juga mendapatkan pesan kesalahan saat mencoba membuat skrip definisi fungsi melalui Azure Data Studio:
No script was returned when scripting as Create on object UserDefinedFunction
Perhatikan bahwa teks fungsi terenkripsi masih tersedia untuk pengguna istimewa yang dapat mengakses tabel sistem melalui port DAC atau mengakses file database secara langsung. Selain itu, pengguna yang dapat melampirkan debugger ke proses server dapat mengambil prosedur asli dari memori saat runtime.