Du kan oprette en indlejret tabelværdi-funktion (ITVF) i SQL Server ved hjælp af T-SQL CREATE FUNCTION
syntaks.
Syntaks
Her er den officielle syntaks for inline TVF'er.
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 [ ) ] [ ; ]
Eksempel 1 – Grundlæggende ITVF
Her er et eksempel på en grundlæggende inline-tabel-vurderet funktion.
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
I dette tilfælde kræver funktionen, at et kattenavn sendes ind som et argument. Den bruger derefter dette argument i forespørgslen for at returnere de relevante data.
Eksempel 2 – Tilføj skemabinding
Det er normalt en god idé at skemabinde dine funktioner ved at bruge SCHEMABINDING
argument.
Dette vil sikre, at de underliggende tabeller ikke kan ændres på en måde, der ville påvirke din funktion.
Uden skemabinding kunne de underliggende tabeller ændres eller endda slettes. Dette kan ødelægge funktionen.
Her er den samme funktion, men denne gang med skemabinding:
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
Bemærk, at jeg brugte det todelte navn, når jeg refererede til tabellen i min forespørgsel (jeg brugte dbo.Cats
når man refererer til tabellen, i stedet for kun Cats
). At gøre dette er et krav for skemabinding af et objekt. Hvis du forsøger at skemabinde et objekt uden at bruge todelte navne, får du en fejl.
Nu hvor jeg har skemabundet min funktion, får jeg en fejlmeddelelse, hvis jeg forsøger at droppe tabellen, der henvises til i dens definition:
DROP TABLE Cats;
Resultat:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'cats' because it is being referenced by object 'udf_CatsByName_ITVF'.
Forresten, her er hvad der sker, hvis jeg forsøger at oprette funktionen uden at bruge todelt navngivning:
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
Resultat:
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.
Eksempel 3 – Tilføj kryptering
Du kan også kryptere dine funktioner ved at bruge ENCRYPTION
argument.
Her er et eksempel på kryptering af funktionen:
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
Nu kan jeg ikke se funktionens definition.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');
Resultat:
+--------------+ | definition | |--------------| | NULL | +--------------+
Jeg får også en fejlmeddelelse, når jeg forsøger at scripte funktionens definition via Azure Data Studio:
No script was returned when scripting as Create on object UserDefinedFunction
Bemærk, at en krypteret funktions tekst stadig er tilgængelig for privilegerede brugere, der enten kan få adgang til systemtabeller over DAC-porten eller direkte få adgang til databasefiler. Brugere, der kan knytte en debugger til serverprocessen, kan også hente den originale procedure fra hukommelsen under kørsel.