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.