Der Hauptgrund ist wahrscheinlich, dass Tabellenfunktionen eine Ergebnismenge zurückgeben, genau wie Tabellen und Ansichten. Dies bedeutet , dass sie in der verwendet werden FROM
Klausel (einschließlich JOIN
s und APPLY
s, usw.) von SELECT
, UPDATE
und DELETE
Abfragen. Sie können jedoch in keinem dieser Kontexte eine skalare UDF verwenden.
Zweitens können Sie auch EXECUTE
eine Skalar-UDF. Diese Syntax ist sehr praktisch, wenn Sie Standardwerte für Eingabeparameter angegeben haben. Nehmen Sie zum Beispiel die folgende UDF:
CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
RETURN @Param1 + @Param2;
END;
Wenn Sie einen der Eingabeparameter als "optional" behandeln möchten, müssen Sie das DEFAULT
Schlüsselwort dennoch übergeben, wenn Sie es wie eine Funktion aufrufen, da die Signatur festgelegt ist:
DECLARE @Bob1 INT;
SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);
SELECT @Bob1;
-- Returns: 102
Wenn Sie dagegen EXECUTE
die Funktion verwenden, können Sie alle Parameter mit einem Standardwert wie bei gespeicherten Prozeduren als wirklich optional behandeln. Sie können die ersten n Parameter ohne Angabe von Parameternamen übergeben:
DECLARE @Bob2 INT;
EXEC @Bob2 = dbo.OptionalParameterTest 50;
SELECT @Bob2;
-- Returns: 52
Sie können den ersten Parameter sogar überspringen, indem Sie erneut Parameternamen angeben, genau wie bei gespeicherten Prozeduren:
DECLARE @Bob3 INT;
EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;
SELECT @Bob3;
-- Returns: 51
AKTUALISIEREN
Warum möchten Sie möglicherweise die EXEC
Syntax verwenden, um eine skalare UDF wie eine gespeicherte Prozedur aufzurufen? Gelegentlich gibt es UDFs, die sich hervorragend als UDFs eignen, da sie zu einer Abfrage hinzugefügt und über die zurückgegebenen Zeilen ausgeführt werden können. Wenn der Code in einer gespeicherten Prozedur enthalten wäre, müsste er dazu in einen Cursor eingefügt werden Iterieren Sie über eine Reihe von Zeilen. Aber dann gibt es Zeiten, in denen Sie diese Funktion für einen einzelnen Wert aufrufen möchten, möglicherweise innerhalb einer anderen UDF. Das Aufrufen einer UDF für einen einzelnen Wert kann folgendermaßen erfolgen:
SELECT dbo.UDF('some value');
In diesem Fall erhalten Sie einen Rückgabewert in einer Ergebnismenge (eine Ergebnismenge funktioniert nicht). Oder es könnte wie folgt gemacht werden:
DECLARE @Dummy INT;
SET @Dummy = dbo.UDF('some value');
In diesem Fall müssen Sie die @Dummy
Variable deklarieren .
Mit der EXEC
Syntax können Sie jedoch diese beiden Belästigungen vermeiden:
EXEC dbo.UDF 'some value';
AUCH bei skalaren UDFs werden die Ausführungspläne zwischengespeichert. Dies bedeutet, dass Parameter-Sniffing-Probleme auftreten können, wenn in der UDF Abfragen mit Ausführungsplänen vorhanden sind. In Szenarien, in denen die EXEC
Syntax verwendet werden kann, können Sie auch die WITH RECOMPILE
Option verwenden, um den für diese Ausführung kompilierten Planwert zu ignorieren . Beispielsweise:
INSTALLIEREN:
GO
CREATE FUNCTION dbo.TestUDF (@Something INT)
RETURNS INT
AS
BEGIN
DECLARE @Ret INT;
SELECT @Ret = COUNT(*)
FROM sys.indexes si
WHERE si.[index_id] = @Something;
RETURN @Ret;
END;
GO
PRÜFUNG:
DECLARE @Val INT;
SET @Val = dbo.TestUDF(1);
SELECT @Val;
EXEC @Val = dbo.TestUDF 0 -- uses compiled value of (1)
SELECT @Val;
EXEC @Val = dbo.TestUDF 0 WITH RECOMPILE; -- uses compiled value of (0)
SELECT @Val;
EXEC @Val = dbo.TestUDF 3 -- uses compiled value of (1)
SELECT @Val;