Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Buat Fungsi Bernilai Tabel Multi-Pernyataan (MSTVF) di SQL Server

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kembalikan Informasi Kolom untuk Prosedur Tersimpan di SQL Server:sp_sproc_columns

  2. Cara membuat pekerjaan di edisi SQL Server Express

  3. Kesalahan "Tidak dapat melepaskan pemicu" saat Mencoba Menjatuhkan Pemicu Masuk? Coba ini.

  4. Mendapatkan minimal dua nilai dalam SQL

  5. Apa cara terbaik untuk memanfaatkan huruf pertama dari setiap kata dalam string di SQL Server?