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.