sql >> Databáze >  >> RDS >> Sqlserver

Vytvořte Multi-Statement Table-Valued Function (MSTVF) v SQL Server

Můžete vytvořit vícepříkazovou tabulkovou funkci (MSTVF) v SQL Server pomocí T-SQL CREATE FUNCTION syntaxe.

Syntaxe

Zde je oficiální syntaxe pro vícepříkazové TVF.

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  
[ ; ]

Příklad 1 – Základní MSTVF

Zde je příklad vícepříkazové funkce s tabulkovou hodnotou.

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

Struktura návratové tabulky je definována na začátku, když zadám @pets variabilní. Výsledky dotazu se vloží do @pets proměnná.

V tomto případě funkce vyžaduje, aby bylo jako argument předáno jméno domácího mazlíčka. Tento argument pak použije v dotazech, aby vrátil relevantní data. Být multi -funkce s hodnotou tabulky příkazů, mohu do definice funkce zahrnout více příkazů.

Příklad 2 – Přidání vazby schématu

Obvykle je dobrý nápad svázat vaše funkce do schématu pomocí SCHEMABINDING argument.

Tím zajistíte, že podkladové tabulky nebude možné změnit způsobem, který by ovlivnil vaši funkci.

Bez vazby schématu by mohly být základní tabulky upraveny nebo dokonce odstraněny. Mohlo by dojít k přerušení funkce.

Zde je stejná funkce, ale tentokrát s vazbou schématu:

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

Všimněte si, že jsem při odkazování na tabulky v dotazu použil dvoudílné názvy (použil jsem dbo.Cats a dbo.Dogs při odkazování na tabulku namísto pouhého Cats nebo Dogs ). Toto je požadavek pro vazbu schématu na objekt. Pokud se pokusíte svázat objekt do schématu bez použití dvoudílných názvů, dostanete chybu.

Nyní, když jsem svou funkci svázal schématem, pokud se pokusím zrušit tabulku odkazovanou v její definici, zobrazí se chyba:

DROP TABLE Dogs;

Výsledek:

Msg 3729, Level 16, State 1, Line 1
Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.

Mimochodem, zde je to, co se stane, když se pokusím vytvořit funkci bez použití dvoudílného pojmenová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

Výsledek:

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.

Příklad 3 – Přidat šifrování

Své funkce můžete také zašifrovat pomocí ENCRYPTION argument.

Zde je příklad šifrování funkce:

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

Nyní nemohu zobrazit definici funkce.

SELECT definition 
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');

Výsledek:

+--------------+
| definition   |
|--------------|
| NULL         |
+--------------+

Při pokusu o skriptování definice funkce prostřednictvím Azure Data Studio se mi také zobrazí chybová zpráva:

No script was returned when scripting as Create on object UserDefinedFunction

Pamatujte, že text zašifrované funkce je stále dostupný privilegovaným uživatelům, kteří mohou přistupovat k systémovým tabulkám přes port DAC nebo přímo přistupovat k databázovým souborům. Také uživatelé, kteří mohou k procesu serveru připojit ladicí program, mohou za běhu načíst původní proceduru z paměti.


  1. Spusťte soubor PostgreSQL .sql pomocí argumentů příkazového řádku

  2. Uložená procedura T-SQL, která přijímá více hodnot ID

  3. Prague PostgreSQL Developer Day 2016

  4. pomocí hodnot oddělených čárkami uvnitř klauzule IN pro sloupec NUMBER