Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Utwórz wielowyrazową funkcję z wartościami tabelarycznymi (MSTVF) w programie SQL Server

Możesz utworzyć wieloinstrukcyjną funkcję z wartościami tabelarycznymi (MSTVF) w SQL Server przy użyciu CREATE FUNCTION języka T-SQL składnia.

Składnia

Oto oficjalna składnia wielowyrazowych plików 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  
[ ; ]

Przykład 1 – Podstawowy MSTVF

Oto przykład funkcji z wartościami w tabeli zawierającej wiele instrukcji.

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 tabeli zwrotów jest zdefiniowana na początku, kiedy określam @pets zmienny. Wyniki zapytania są wstawiane do @pets zmienna.

W takim przypadku funkcja wymaga podania jako argumentu imienia zwierzaka. Następnie używa tego argumentu w zapytaniach w celu zwrócenia odpowiednich danych. Bycie wieloosobowym -statement funkcja z wartościami tabelarycznymi, mogę zawrzeć wiele instrukcji w definicji funkcji.

Przykład 2 – Dodaj powiązanie schematu

Zwykle dobrym pomysłem jest powiązanie schematu funkcji za pomocą SCHEMABINDING argument.

W ten sposób zapewnisz, że tabel bazowych nie będzie można zmienić w sposób, który wpłynąłby na twoją funkcję.

Bez powiązania schematu bazowe tabele mogą być modyfikowane, a nawet usuwane. Może to spowodować uszkodzenie funkcji.

Oto ta sama funkcja, ale tym razem z powiązaniem schematu:

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

Zauważ, że podczas odwoływania się do tabel w moim zapytaniu użyłem dwuczęściowych nazw (użyłem dbo.Cats i dbo.Dogs podczas odwoływania się do tabeli, zamiast po prostu Cats lub Dogs ). Jest to wymagane do powiązania obiektu ze schematem. Jeśli spróbujesz powiązać obiekt w schemacie bez użycia dwuczęściowych nazw, otrzymasz błąd.

Teraz, gdy powiązałem schemat z moją funkcją, jeśli spróbuję usunąć tabelę, do której odwołuje się jej definicja, otrzymuję błąd:

DROP TABLE Dogs;

Wynik:

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

A tak przy okazji, oto co się stanie, jeśli spróbuję utworzyć funkcję bez używania dwuczęściowego nazewnictwa:

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

Wynik:

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.

Przykład 3 – Dodaj szyfrowanie

Możesz także zaszyfrować swoje funkcje za pomocą ENCRYPTION argument.

Oto przykład szyfrowania funkcji:

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

Teraz nie mogę wyświetlić definicji funkcji.

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

Wynik:

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

Otrzymuję również komunikat o błędzie podczas próby skryptowania definicji funkcji za pomocą Azure Data Studio:

No script was returned when scripting as Create on object UserDefinedFunction

Należy zauważyć, że tekst zaszyfrowanej funkcji jest nadal dostępny dla uprzywilejowanych użytkowników, którzy mogą uzyskiwać dostęp do tabel systemowych przez port DAC lub bezpośrednio uzyskiwać dostęp do plików bazy danych. Ponadto użytkownicy, którzy mogą podłączyć debugger do procesu serwera, mogą pobrać oryginalną procedurę z pamięci w czasie wykonywania.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wysyłaj wiadomości e-mail z załącznikami w SQL Server (T-SQL)

  2. Konwertuj „datetime2” na „time” w SQL Server (przykłady T-SQL)

  3. SQL Server 2008 — Pobierz ograniczenia dotyczące tabel

  4. Pobierz obraz z bazy danych w asp.net

  5. Co to jest @@MAX_PRECISION w programie SQL Server?