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

Tworzenie wbudowanej funkcji z wartościami tabelarycznymi (ITVF) w programie SQL Server

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

Składnia

Oto oficjalna składnia wbudowanych plików TVF.

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type   
    [ = default ] [ READONLY ] }   
    [ ,...n ]  
  ]  
)  
RETURNS TABLE  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    RETURN [ ( ] select_stmt [ ) ]  
[ ; ]  

Przykład 1 – Podstawowy ITVF

Oto przykład podstawowej wbudowanej funkcji z wartościami tabelarycznymi.

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO

W takim przypadku funkcja wymaga podania imienia kota jako argumentu. Następnie używa tego argumentu w zapytaniu, aby zwrócić odpowiednie dane.

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_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO

Zauważ, że użyłem dwuczęściowej nazwy podczas odwoływania się do tabeli w moim zapytaniu (użyłem dbo.Cats podczas odwoływania się do tabeli, zamiast po prostu Cats ). Jest to wymagane do powiązania obiektu ze schematem. Jeśli spróbujesz schematycznie powiązać obiekt 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 Cats;

Wynik:

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

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

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM Cats
    WHERE CatName = @CatName
    );

GO

Wynik:

Msg 4512, Level 16, State 3, Procedure udf_CatsByName_ITVF, Line 7
Cannot schema bind table valued function 'dbo.udf_CatsByName_ITVF' 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_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING, ENCRYPTION
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO

Teraz nie mogę wyświetlić definicji funkcji.

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

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. Jak znaleźć najwolniejsze zapytania

  2. Co się stanie, jeśli nie zatwierdzisz transakcji w bazie danych (np. SQL Server)?

  3. Limit czasu połączenia dla serwera SQL

  4. Wyodrębnij numer tygodnia z daty w SQL Server (T-SQL)

  5. Jak sprawdzić zgodność bazy danych SQL Server po przestarzałej funkcji sp_dbcmptlevel?