Sie können eine Tabellenwertfunktion mit mehreren Anweisungen (MSTVF) in SQL Server mithilfe von T-SQL CREATE FUNCTION
erstellen Syntax.
Syntax
Hier ist die offizielle Syntax für TVFs mit mehreren Anweisungen.
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 [ ; ]
Beispiel 1 – Basis-MSTVF
Hier ist ein Beispiel für eine Tabellenwertfunktion mit mehreren Anweisungen.
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
Die Struktur der Rückgabetabelle wird zu Beginn definiert, wenn ich den @pets
spezifiziere Variable. Die Abfrageergebnisse werden in @pets
eingefügt Variable.
In diesem Fall muss der Funktion ein Kosename als Argument übergeben werden. Dieses Argument wird dann in den Abfragen verwendet, um die relevanten Daten zurückzugeben. Ein Multi sein -Anweisung Tabellenwertfunktion kann ich mehrere Anweisungen in die Definition der Funktion aufnehmen.
Beispiel 2 – Schemabindung hinzufügen
Es ist normalerweise eine gute Idee, Ihre Funktionen mithilfe von SCHEMABINDING
an ein Schema zu binden Streit.
Dadurch wird sichergestellt, dass die zugrunde liegenden Tabellen nicht in einer Weise geändert werden können, die Ihre Funktion beeinträchtigen würde.
Ohne Schemabindung könnten die zugrunde liegenden Tabellen geändert oder sogar gelöscht werden. Dadurch könnte die Funktion unterbrochen werden.
Hier ist die gleiche Funktion, aber diesmal mit Schemabindung:
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
Beachten Sie, dass ich beim Verweisen auf die Tabellen in meiner Abfrage zweiteilige Namen verwendet habe (ich habe dbo.Cats
verwendet und dbo.Dogs
wenn auf die Tabelle verwiesen wird, statt nur Cats
oder Dogs
). Dies ist eine Voraussetzung für die Schemabindung eines Objekts. Wenn Sie versuchen, ein Objekt an ein Schema zu binden, ohne zweiteilige Namen zu verwenden, erhalten Sie eine Fehlermeldung.
Jetzt, da ich meine Funktion schemagebunden habe, erhalte ich eine Fehlermeldung, wenn ich versuche, die Tabelle, auf die in ihrer Definition verwiesen wird, zu löschen:
DROP TABLE Dogs;
Ergebnis:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.
Übrigens passiert Folgendes, wenn ich versuche, die Funktion ohne zweiteilige Benennung zu erstellen:
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
Ergebnis:
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.
Beispiel 3 – Verschlüsselung hinzufügen
Sie können Ihre Funktionen auch mit ENCRYPTION
verschlüsseln Streit.
Hier ist ein Beispiel für die Verschlüsselung der Funktion:
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
Jetzt kann ich die Definition der Funktion nicht anzeigen.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');
Ergebnis:
+--------------+ | definition | |--------------| | NULL | +--------------+
Ich erhalte auch eine Fehlermeldung, wenn ich versuche, die Definition der Funktion über Azure Data Studio zu skripten:
No script was returned when scripting as Create on object UserDefinedFunction
Beachten Sie, dass der Text einer verschlüsselten Funktion weiterhin für privilegierte Benutzer verfügbar ist, die entweder über den DAC-Port auf Systemtabellen oder direkt auf Datenbankdateien zugreifen können. Außerdem können Benutzer, die einen Debugger an den Serverprozess anhängen können, die ursprüngliche Prozedur zur Laufzeit aus dem Speicher abrufen.