Inlining benutzerdefinierter Skalarfunktionen

Gilt für: SQL Server 2019 (15.x) Azure SQL-Datenbank Azure SQL Managed Instance

Dieser Artikel stellt eine Einführung in das Inlining benutzerdefinierter Skalarfunktionen dar. Dabei handelt es sich um ein Feature für die Intelligente Abfrageverarbeitung in SQL-Datenbanken. Diese Funktion verbessert die Leistung von Abfragen, die skaläre UDFs in SQL Server aufrufen (in SQL Server 2019 (15.x) und neueren Versionen).

Benutzerdefinierte T-SQL-Skalarfunktionen

Benutzerdefinierte Funktionen (UDFs), die in Transact-SQL implementiert werden und einen einzelnen Datenwert zurückgeben, werden als benutzerdefinierte Transact-SQL-Skalarfunktionen bezeichnet. T-SQL UDFs sind ein eleganter Weg, um die Wiederverwendung von Code und die Modularität von Transact-SQL-Abfragen zu erreichen. Einige Berechnungen (z.B. komplexe Geschäftsregeln) können einfacher in imperativer UDF-Form ausgedrückt werden. Mit benutzerdefinierten Funktionen können Sie eine komplexe Logik erstellen, ohne komplexe SQL-Abfragen schreiben zu können. Weitere Informationen zu benutzerdefinierten Funktionen (UDFs) finden Sie unter Erstellen von benutzerdefinierten Funktionen (Datenbank-Engine).

Leistung von benutzerdefinierten Skalarfunktionen

Die Leistung von benutzerdefinierten Skalarfunktionen ist aus folgenden Gründen häufig niedrig:

  • Iterativer Aufruf. Benutzerdefinierte Funktionen werden einmal pro qualifiziertem Tupel iterativ aufgerufen. Durch diese Funktionsaufrufe entstehen zusätzliche Kosten für den Kontextwechsel. Dies betrifft besonders benutzerdefinierte Funktionen, die Transact-SQL-Abfragen in ihrer Definition ausführen.

  • Fehlende Kostenkalkulation. Während der Optimierung fallen nur Kosten für relationale Operatoren an, nicht für Skalaroperatoren. Vor der Einführung benutzerdefinierter Skalarfunktionen waren andere Skalaroperatoren in der Regel günstig, sodass keine Kostenberechnung nötig war. Es war ausreichend, geringe CPU-Kosten für einen Skalarvorgang hinzuzufügen. In einigen Szenarios sind die tatsächlichen Kosten jedoch wichtig und werden dennoch nicht ausreichend repräsentiert.

  • Interpretierte Ausführung. Benutzerdefinierte Funktionen werden als Anweisungsbatch ausgewertet und Anweisung für Anweisung ausgeführt. Jede Anweisung wird kompiliert, und der kompilierte Plan wird zwischengespeichert. Die Zwischenspeicherung spart zwar Zeit, da Neukompilierungen vermieden werden, aber jede Anweisung wird isoliert ausgeführt. Es können keine anweisungsübergreifenden Optimierungen durchgeführt werden.

  • Serielle Ausführung. SQL Server lässt in Abfragen, die benutzerdefinierte Funktionen aufrufen, keinen abfrageinternen Parallelismus zu.

Automatisches Inlining von benutzerdefinierrten Skalarfunktionen

Mit dem Feature für das Inlining benutzerdefinierter Skalarfunktionen soll die Leistung von Abfragen verbessert werden, die benutzerdefinierte T-SQL-Skalarfunktionen ausführen, bei denen die Ausführung der benutzerdefinierten Funktion den entscheidenden Engpass darstellt.

Mit diesem neuen Feature werden benutzerdefinierte Skalarfunktionen automatisch in Skalarausdrücke oder skalare Unterabfragen transformiert, die in der aufrufenden Abfrage den UDF-Operator ersetzen. Diese Ausdrücke und Unterabfragen werden anschließend optimiert. Daher verfügt der Abfrageplan nicht mehr über einen benutzerdefinierten Funktionsoperator, aber seine Auswirkungen werden im Plan beobachtet, z. B. Ansichten oder Inline-Tabellenwertfunktionen (TVFs).

Beispiele

In den Beispielen in diesem Abschnitt wird die TPC-H-Benchmark-Datenbank verwendet. Weitere Informationen finden Sie auf der TPC-H-Homepage.

A. Benutzerdefinierte Skalarfunktion mit einer einzelnen Anweisung

Sehen Sie sich die folgende Abfrage an:

SELECT L_SHIPDATE,
       O_SHIPPRIORITY,
       SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT))
FROM LINEITEM
     INNER JOIN ORDERS
         ON O_ORDERKEY = L_ORDERKEY
GROUP BY L_SHIPDATE, O_SHIPPRIORITY
ORDER BY L_SHIPDATE;

Diese Abfrage berechnet die Summe der reduzierten Preise für Einzelposten und gruppiert die Ergebnisse nach Versanddatum und Versandpriorität. Der Ausdruck L_EXTENDEDPRICE *(1 - L_DISCOUNT) enthält die Formel für den reduzierten Preis eines bestimmten Einzelpostens. Solche Formeln können in Funktionen extrahiert werden, um Modularität und Wiederverwendbarkeit zu erreichen.

CREATE FUNCTION dbo.discount_price
(
    @price DECIMAL (12, 2),
    @discount DECIMAL (12, 2)
)
RETURNS DECIMAL (12, 2)
AS
BEGIN
    RETURN @price * (1 - @discount);
END

Die Abfrage kann nun geändert werden, um diese benutzerdefinierte Funktion aufzurufen.

SELECT L_SHIPDATE,
       O_SHIPPRIORITY,
       SUM(dbo.discount_price(L_EXTENDEDPRICE, L_DISCOUNT))
FROM LINEITEM
     INNER JOIN ORDERS
         ON O_ORDERKEY = L_ORDERKEY
GROUP BY L_SHIPDATE, O_SHIPPRIORITY
ORDER BY L_SHIPDATE;

Die Abfrage mit der UDF ist aus den zuvor genannten Gründen langsam. Mit Scalare Inline-UDF wird der skalare Ausdruck im Textkörper der UDF direkt in der Abfrage ersetzt. Die Ergebnisse dieser Abfrage sind in der folgenden Tabelle dargestellt:

Abfrage: Abfrage ohne benutzerdefinierte Funktion Abfrage mit benutzerdefinierter Funktion (ohne Inlining) Abfrage mit Inlining benutzerdefinierter Skalarfunktionen
Ausführungszeit: 1,6 Sekunden 29 Minuten, 11 Sekunden 1,6 Sekunden

Diese Zahlen basieren auf einer CCI-Datenbank mit 10 GB (mit dem TPC-H-Schema), die auf einem Computer mit Dualprozessor (12 Kerne), 96 GB RAM und SSD-Sicherung ausgeführt wird. Dabei wurden die Kompilier- und die Ausführungszeit mit einem kalten Prozedurcache und Pufferpool eingeschlossen. Die Standardkonfiguration wurde verwendet, und es wurden keine weiteren Indizes erstellt.

B. Skalare Inline-UDF mit mehreren Anweisungen

Für benutzerdefinierte Skalarfunktionen, die über mehrere T-SQL-Anweisungen implementiert werden, z.B. Variablenzuweisungen und bedingte Verzweigungen, kann ebenfalls ein Inlining durchgeführt werden. Sehen Sie sich folgende benutzerdefinierte Skalarfunktion an, die die Servicekategorie für einen bestimmten Kunden bestimmt, wenn ein benutzerdefinierter Schlüssel vorhanden ist. Die Kategorie wird erreicht, indem zuerst der Gesamtpreis aller Bestellungen des Kunden mithilfe einer SQL-Abfrage berechnet wird. Anschließend wird eine IF (...) ELSE-Logik verwendet, um die Kategorie auf Grundlage des Gesamtpreises zu bestimmen.

CREATE OR ALTER FUNCTION dbo.customer_category (@ckey INT)
RETURNS CHAR (10)
AS
BEGIN
    DECLARE @total_price AS DECIMAL (18, 2);
    DECLARE @category AS CHAR (10);
    SELECT @total_price = SUM(O_TOTALPRICE)
    FROM ORDERS
    WHERE O_CUSTKEY = @ckey;
    IF @total_price < 500000
        SET @category = 'REGULAR';
    ELSE
        IF @total_price < 1000000
            SET @category = 'GOLD';
        ELSE
            SET @category = 'PLATINUM';
    RETURN @category;
END

Sehen Sie sich nun eine Abfrage an, die diese benutzerdefinierte Funktion aufruft.

SELECT C_NAME,
       dbo.customer_category(C_CUSTKEY)
FROM CUSTOMER;

Der Ausführungsplan für diese Abfrage in SQL Server 2017 (14.x) (Kompatibilitätsstufe 140 und früher) sieht folgendermaßen aus:

Screenshot von Abfrageplan ohne Inlining.

Der Plan zeigt, dass SQL Server in diesem Fall eine einfache Strategie übernimmt: Für jedes Tupel in der CUSTOMER-Tabelle werden die benutzerdefinierte Funktion aufgerufen und die Ergebnisse ausgegeben. Diese Strategie ist jedoch zu einfach und nicht effizient. Durch Inlining werden solche benutzerdefinierten Funktionen in gleichwertige skalare Unterabfragen transformiert, die die benutzerdefinierte Funktion in der aufrufenden Abfrage ersetzen.

Der Plan mit Inlining der benutzerdefinierten Funktion sieht für die gleiche Abfrage folgendermaßen aus.

Screenshot des Abfrageplans mit Inlining.

Wie zuvor erwähnt enthält der Abfrageplan keinen UDF-Operator mehr. Seine Auswirkungen sind nun im Plan ersichtlich, z.B. Ansichten oder Inline-Tabellenwertfunktionen. Hier sind die wichtigsten Beobachtungen, die aus dem vorstehenden Plan resultieren:

  • SQL Server leitet die implizite Verknüpfung zwischen CUSTOMER und ORDERS macht sie über einen Join-Operator explizit.

  • SQL Server hat außerdem die implizite GROUP BY O_CUSTKEY on ORDERS-Anweisung abgeleitet und „IndexSpool + StreamAggregate“ verwendet, um diese zu implementieren.

  • SQL Server verwendet nun einen Parallelismus für alle Operatoren.

Je nach Komplexität der Logik in der benutzerdefinierten Funktion kann der resultierende Abfrageplan größer und komplexer werden. Wie wir sehen können, sind die Operationen innerhalb der UDF jetzt nicht mehr undurchsichtig, so dass der Abfrageoptimierer in der Lage ist, diese Operationen zu berechnen und zu optimieren. Da die benutzerdefinierte Funktion sich nicht mehr im Plan befindet, wird der iterative Aufruf derselben durch einen Plan ersetzt, der den Aufwand, der durch Funktionsaufrufe entsteht, vollständig vermeidet.

Anforderungen für inlinefähige skalare UDFs

Eine skalare T-SQL-UDF kann inlineiert werden, wenn die Funktionsdefinition zulässige Konstrukte verwendet, und die Funktion wird in einem Kontext verwendet, der die Inlinierung ermöglicht:

Alle folgenden Bedingungen der UDF-Definition müssen erfüllt sein:

  • Die UDF wurde mit folgenden Konstrukten geschrieben:
    • DECLARE, SET: Variablendeklaration und -zuweisungen
    • SELECT: SQL-Abfrage mit einer bzw. mehreren Variablenzuweisungen 1.
    • IF/ELSE: Verzweigung mit beliebigen Schachtelungsebenen
    • RETURN: eine oder mehrere RETURN-Anweisungen Ab SQL Server 2019 (15.x) CU5 kann die UDF nur eine einzelne RETURN-Anweisung enthalten, die für Inlining 6 berücksichtigt werden soll.
    • UDF: Geschachtelte rekursive Funktionsaufrufe 2.
    • Sonstige: relationale Operatoren wie EXISTS, IS NULL
  • Die UDF ruft keine intrinsische Funktion auf, die zeitabhängig ist (wie GETDATE()) oder Nebeneffekte3 hat (wie NEWSEQUENTIALID()).
  • Die UDF verwendet die EXECUTE AS CALLER-Klausel (Standardverhalten, wenn die EXECUTE AS-Klausel nicht angegeben wurde).
  • Die UDF verweist nicht auf Tabellenvariablen oder Tabellenwertparameter.
  • Die UDF wird nicht nativ kompiliert (Interop wird unterstützt).
  • Die UDF verweist nicht auf benutzerdefinierte Typen.
  • Der UDF 9 wurden keine Signaturen hinzugefügt.
  • Bei der UDF handelt es sich nicht um eine Partitionsfunktion.
  • Die UDF enthält keine Verweise auf allgemeine Tabellenausdrücke (CTEs).
  • Die UDF enthält keine Verweise auf intrinsische Funktionen, die die Ergebnisse ändern können, wenn ein Inlinevorgang ausgeführt wird (z. B. @@ROWCOUNT) 4.
  • Die UDF enthält keine Aggregatfunktionen, die als Parameter an eine Skalar-UDF übergeben werden 4.
  • Die UDF verweist nicht auf integrierte Anzeigen (z. B. OBJECT_ID) 4.
  • Die UDF verweist nicht auf XML-Methoden 5.
  • Die UDF enthält keine SELECT-Abfrage mit ORDER BY ohne TOP 1-Klausel 5.
  • Die UDF enthält keine SELECT-Abfrage, die eine Zuweisung in Verbindung mit der ORDER BY-Klausel durchführt (z. B. SELECT @x = @x + 1 FROM table1 ORDER BY col1) 5.
  • Die UDF enthält keine multiplen RETURN-Anweisungen 6.
  • Die UDF verweist nicht auf die STRING_AGG-Funktion 6.
  • Die UDF verweist nicht auf Remotetabellen 7.
  • Die UDF verweist nicht auf verschlüsselte Spalten 8.
  • Die UDF enthält keine Verweise auf WITH XMLNAMESPACES 8.
  • Wenn die Definition der UDF beispielsweise zu Tausenden Codezeilen führt, führt SQL Server für diese möglicherweise kein Inlining durch.

1 Für SELECT mit einer Variablenakkumulation/-aggregation (z. B. SELECT @val += col1 FROM table1) wird kein Inlining unterstützt.

2 Für rekursive benutzerdefinierte Funktionen wird das Inlining nur bis zu einem bestimmten Grad durchgeführt.

3 Intrinsische Funktionen, deren Ergebnisse von der aktuellen Systemzeit abhängen, sind zeitabhängig. Ein Beispiel für eine Funktion mit Nebeneffekten ist eine intrinsische Funktion, die einen internen globalen Status aktualisieren kann. Solche Funktionen geben bei jedem Aufruf unterschiedliche Ergebnisse auf Grundlage des internen Status zurück.

4 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 2

5 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 4

6 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 5

7 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 6

8 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 11

9 Da Signaturen nach dem Erstellen einer UDF hinzugefügt und abgelegt werden konnten, entscheidet sich, ob inline ausgeführt wird, wenn die Abfrage, die auf eine skalare UDF verweist, kompiliert wird. Systemfunktionen sind z. B. in der Regel mit einem Zertifikat signiert. Sie können sys.crypt_properties verwenden, um zu ermitteln, welche Objekte signiert sind.

Alle folgenden Anforderungen des Ausführungskontexts müssen erfüllt sein:

  • Die UDF wird in der ORDER BY-Klausel nicht verwendet.
  • Die Abfrage, die eine skalare UDF aufruft, verweist in ihrer Klausel GROUP BY nicht auf einen skalaren UDF-Aufruf.
  • Die Abfrage, die eine skalare UDF in der Auswahlliste mit der DISTINCT-Klausel aufruft, verfügt nicht über eine ORDER BY-Klausel.
  • Die UDF wird nicht aus einer RETURN-Anweisung 1 aufgerufen.
  • Die Abfrage, die die UDF aufruft, enthält keine gemeinsamen Tabellenausdrücke (CTEs) 3.
  • Die UDF-aufrufende Abfrage verwendet GROUPING SETSweder noch CUBEROLLUP 2.
  • Die UDF-aufrufende Abfrage enthält keine Variable, die als UDF-Parameter für die Zuweisung (zSELECT @y = 2. B. , ) @x = UDF(@y)2 verwendet wird.
  • Die UDF wird nicht in einer berechneten Spalte oder in der Definition einer CHECK-Einschränkung verwendet.

1 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 5

2 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 6

3 Einschränkung hinzugefügt in SQL Server 2019 (15.x) CU 11

Informationen zu den neuesten Fehlerkorrekturen beim T-SQL Scalar UDF Inlining und zu den Änderungen bei den Inlining-Zulässigkeitsszenarien finden Sie im Knowledge Base Artikel: FIX: Scalar UDF Inlining Probleme in SQL Server 2019.

Überprüfen, ob eine UDF inlined sein kann

Für jede T-SQL-skalare UDF enthält die Katalogansicht sys.sql_modules eine Eigenschaft namens is_inlineable, die angibt, ob eine UDF inlineierbar ist.

Die is_inlineable-Eigenschaft wird von den Konstrukten abgeleitet, die in der Definition der benutzerdefinierten Skalarfunktion gefunden werden. Es wird nicht überprüft, ob für die UDF zum Zeitpunkt der Kompilierung tatsächlich ein Inlining möglich ist. Weitere Informationen finden Sie im Abschnitt zu den Bedingungen für Inlining.

Ein Wert von 1 gibt an, dass die UDF inlineierbar ist und 0 andernfalls angibt. Diese Eigenschaft enthält für alle Inline-Tabellenwertfunktionen den Wert 1. Für alle anderen Module ist der Wert 0.

Wenn eine skalare UDF inline-fähig ist, bedeutet das nicht, dass sie immer inline-fähig ist. SQL Server entscheidet (pro Abfrage, pro UDF), ob eine UDF inline werden soll. Weitere Informationen finden Sie weiter oben in diesem Artikel in den Listen der Anforderungen.

SELECT *
FROM sys.crypt_properties AS cp
     INNER JOIN sys.objects AS o
         ON cp.major_id = o.object_id;

Überprüfen, ob die Inlinierung stattgefunden hat

Wenn alle Bedingungen erfüllt sind und SQL Server ein Inlining durchführt, wird die benutzerdefinierte Funktion in einen relationalen Ausdruck transformiert. Anhand des Abfrageplans können Sie herausfinden, ob die Gliederung erfolgt ist:

  • Die Plan-xml-Datei enthält keinen <UserDefinedFunction>-xml-Knoten für eine UDF, die erfolgreich inlined wurde.
  • Bestimmte erweiterte Ereignisse werden ausgegeben.

Skalar-UDF-Inlining aktivieren

Sie können Workloads automatisch für das Inlining benutzerdefinierter Skalarfunktionen zulassen, indem Sie den Kompatibilitätsgrad 150 für die Datenbank aktivieren. Diesen können Sie mit Transact-SQL festlegen. Zum Beispiel:

ALTER DATABASE [WideWorldImportersDW]
    SET COMPATIBILITY_LEVEL = 150;

Es müssen in diesem Schritt keine weiteren Änderungen vorgenommen, damit dieses Feature für benutzerdefinierte Funktionen oder Abfragen verwendet werden kann.

Deaktivieren von Scalar UDF Inlining ohne Änderung des Kompatibilitätslevels

Das Inlining von benutzerdefinierten Skalarfunktionen kann im Datenbank- oder Anweisungs-, oder UDF-Bereich deaktiviert werden, während der Datenbankkompatibilitätsgrad weiterhin bei 150 und höher bleibt. Führen Sie folgende Anweisung im Kontext einer Datenbank aus, um das Inlining für benutzerdefinierte Skalarfunktionen im Datenbankbereich zu deaktivieren:

ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;

Führen Sie folgende Anweisung im Kontext einer Datenbank aus, um das Inlining für benutzerdefinierte Skalarfunktionen für eine Datenbank wieder zu aktivieren:

ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = ON;

Wenn ON aktiviert ist, wird diese Eistellung in sys.database_scoped_configurations als aktiviert aufgeführt.

Sie können das Inlining benutzerdefinierter Skalarfunktionen für eine bestimmte Abfrage auch deaktivieren, indem Sie DISABLE_TSQL_SCALAR_UDF_INLINING als USE HINT-Abfragehinweis festlegen.

Ein USE HINT-Abfragehinweis hat Vorrang vor einer datenbankweit gültigen Konfiguration oder einer Einstellung des Kompatibilitätsgrads.

Zum Beispiel:

SELECT L_SHIPDATE,
       O_SHIPPRIORITY,
       SUM(dbo.discount_price(L_EXTENDEDPRICE, L_DISCOUNT))
FROM LINEITEM
     INNER JOIN ORDERS
         ON O_ORDERKEY = L_ORDERKEY
GROUP BY L_SHIPDATE, O_SHIPPRIORITY
ORDER BY L_SHIPDATE
OPTION (USE HINT('DISABLE_TSQL_SCALAR_UDF_INLINING'));

Das Inlining benutzerdefinierter Skalarfunktionen kann auch für eine bestimmte benutzerdefinierte Funktion deaktiviert werden, indem Sie die INLINE-Klausel in der CREATE FUNCTION- oder ALTER FUNCTION-Anweisung verwenden. Zum Beispiel:

CREATE OR ALTER FUNCTION dbo.discount_price
(
    @price DECIMAL (12, 2),
    @discount DECIMAL (12, 2)
)
RETURNS DECIMAL (12, 2)
WITH INLINE = OFF
AS
BEGIN
    RETURN @price * (1 - @discount);
END

Sobald die vorgenannte Anweisung ausgeführt wurde, wird für diese benutzerdefinierte Funktion kein Inlining durchgeführt, wenn sie von einer Abfrage aufgerufen wird. Führen Sie folgende Anweisung aus, um das Inlining für diese benutzerdefinierte Funktion wieder zu aktivieren:

CREATE OR ALTER FUNCTION dbo.discount_price
(
    @price DECIMAL (12, 2),
    @discount DECIMAL (12, 2)
)
RETURNS DECIMAL (12, 2)
WITH INLINE = ON
AS
BEGIN
    RETURN @price * (1 - @discount);
END

Die INLINE-Klausel ist nicht verbindlich. Wenn die INLINE-Klausel nicht festgelegt ist, wird sie automatisch auf ON/OFF festgelegt, je nachdem, ob ein Inlining für die UDF durchgeführt werden kann. Wenn INLINE = ON festgelegt ist, aber festgestellt wird, dass für die benutzerdefinierte Funktion kein Inlining durchgeführt werden kann, wird ein Fehler ausgegeben.

Hinweise

Wie in diesem Artikel beschrieben wurde, wird beim Inlining einer benutzerdefinierten Skalarfunktion eine Abfrage mit benutzerdefinierten Skalarfunktionen in eine Abfrage mit einer gleichwertigen skalaren Unterabfrage transformiert. Aufgrund dieser Transformation kann es in folgenden Szenarios zu Unterschieden bei der Verhaltensweise kommen:

  • Das Inlining führt zu einem anderen Abfragehash für den gleichen Abfragetext.

  • Bestimmte Warnungen in Anweisungen in der benutzerdefinierten Funktion (z.B. die Division durch 0), die zuvor ausgeblendet waren, werden durch das Inlining nun vielleicht angezeigt.

  • Joinhinweise auf Abfrageebene sind ggf. nicht mehr gültig, da durch das Inlining neue Joins hinzugefügt werden. Sie müssen stattdessen lokale Joinhinweise verwenden.

  • Anzeigen, die auf skalare Inline-UDFs verweisen, können nicht indiziert werden. Wenn Sie einen Index in einer entsprechenden Ansicht erstellen müssen, sollten Sie das Inlining für die benutzerdefinierten Funktionen deaktivieren, auf die verwiesen wird.

  • Durch das Inlining benutzerdefinierter Funktionen kann das Verhalten der dynamischen Datenmaskierung sich ändern.

    In bestimmten Situationen (abhängig von der Logik in der UDF) kann das Inlining im Hinblick auf die Maskierung von Ausgabespalten konservativer sein. In Szenarios, bei denen es sich bei den Spalten, auf die in einer UDF verwiesen wird, nicht um Ausgabespalten handelt, werden diese nicht maskiert.

  • Wenn eine benutzerdefinierte Funktion auf integrierte Funktionen wie SCOPE_IDENTITY(), @@ROWCOUNT oder @@ERROR verweist, ändert sich der Wert, der von der integrierten Funktion zurückgegeben wird, durch das Inlining. Diese Änderung im Verhalten geht darauf zurück, dass das Inlining den Bereich der Anweisungen in der benutzerdefinierten Funktion ändert. Ab SQL Server 2019 (15.x) CU2 wird das Inlining blockiert, wenn die UDF auf bestimmte intrinsische Funktionen verweist (z. B. @@ROWCOUNT).

  • Wenn eine Variable mit dem Ergebnis einer inlineierten UDF zugewiesen wird und sie auch als index_column_name FORCESEEK Abfragehinweise verwendet wird, führt sie zu Fehler 8622, was angibt, dass der Abfrageprozessor aufgrund der in der Abfrage definierten Hinweise keinen Abfrageplan erstellen konnte.