Teilen über


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. Diese Funktion verbessert die Leistung von Abfragen, die skaläre UDFs in SQL Server aufrufen (beginnend mit SQL Server 2019 (15.x)).

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

Das Ziel der Funktion Skalare Inline-UDF ist es, die Leistung von Abfragen zu verbessern, die skalare T-SQL-UDFs aufrufen, bei denen die UDF-Ausführung den größten 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. Dadurch enthält der Abfrageplan keinen UDF-Operator mehr. Seine Auswirkungen werden im Plan überwacht, z.B. Ansichten oder Inline-Tabellenwertfunktionen.

Beispiel 1 - Einzelanweisung skalare UDF

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

Wie zuvor beschrieben ist die Leistung der Abfrage mit der benutzerdefinierten Funktion niedrig. Mit Scalare Inline-UDF wird der skalare Ausdruck im Textkörper der UDF nun direkt in der Abfrage ersetzt. Die Ergebnisse dieser Abfrage werden in folgender Tabelle aufgeführt:

Abfrage: Abfrage ohne benutzerdefinierte Funktion Abfrage mit benutzerdefinierter Funktion (ohne Inlining) Abfrage mit Scalarer Inline-UDF
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.

Beispiel 2: 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 DECIMAL(18,2);
  DECLARE @category 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:

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.

Abfrageplan 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 obigen Plan resultieren:

  • SQL Server hat den impliziten Join zwischen CUSTOMER und ORDERS abgeleitet und diesen über einen Joinoperator in einen expliziten transformiert.
  • 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 inlined werden, wenn alle der folgenden Bedingungen erfüllt sind:

  • 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 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 in der ORDER BY-Klausel nicht verwendet.
  • Die UDF wird nicht nativ kompiliert (Interop wird unterstützt).
  • Die UDF wird nicht in einer berechneten Spalte oder in der Definition einer CHECK-Einschränkung verwendet.
  • Die UDF verweist nicht auf benutzerdefinierte Typen.
  • Zur benutzerdefinierten Funktion werden 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 wird nicht aus einer RETURN-Anweisung aufgerufen 6.
  • Die UDF verweist nicht auf die STRING_AGG-Funktion 6.
  • Die UDF verweist nicht auf Remotetabellen 7.
  • Die Abfrage, die die UDF aufruft, verwendet GROUPING SETS, CUBE oder ROLLUP nicht 7.
  • Die Abfrage, die die UDF aufruft, enthält keine Variable, die als Zuweisungsparameter für die UDF verwendet wird (z. B. SELECT @y = 2, @x = UDF(@y)) 7.
  • Die UDF verweist nicht auf verschlüsselte Spalten 8.
  • Die UDF enthält keine Verweise auf WITH XMLNAMESPACES 8.
  • Die Abfrage, die die UDF aufruft, enthält keine allgemeinen Tabellenausdrücke (CTEs) 8.

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) CU2

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

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

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

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

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 Sie, ob ein Inlining einer UDF möglich ist

Für jede benutzerdefinierte T-SQL-Skalarfunktion enthält die Katalogansicht sys.sql_modules eine Eigenschaft namens is_inlineable, die angibt, ob für eine benutzerdefinierte Funktion ein Inlining möglich 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.

Der Wert 1 gibt an, dass ein Inlining möglich ist, während der Wert 0 angibt, dass kein Inlining möglich ist. 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 und pro benutzerdefinierter Funktion), ob für eine benutzerdefinierte Funktion ein Inlining durchgeführt wird. Einige Beispiele, in denen für eine benutzerdefinierte Funktion möglicherweise kein Inlining durchgeführt werden kann, finden Sie im Folgenden:

  • Wenn die Definition der UDF beispielsweise zu Tausenden Codezeilen führt, führt SQL Server für diese möglicherweise kein Inlining durch.

  • Wenn eine UDF in einer GROUP BY-Klausel aufgerufen wird, wird kein Inlining durchgeführt. Diese Entscheidung erfolgt, wenn die Abfrage, die auf eine benutzerdefinierte Skalarfunktion verweist, kompiliert wird.

  • Die benutzerdefinierte Funktion ist mit einem Zertifikat signiert. Da Signaturen nach der Erstellung einer UDF hinzugefügt und gelöscht werden können, wird die Entscheidung, ob Inline oder nicht, bei der Kompilierung der Abfrage getroffen, die eine skalare UDF referenziert. 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.

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

So überprüfen Sie, ob ein Inlining durchgeführt wurde oder nicht

Wenn alle Bedingungen erfüllt sind und SQL Server ein Inlining durchführt, wird die benutzerdefinierte Funktion in einen relationalen Ausdruck transformiert. Über den Abfrageplan können Sie einfach feststellen, ob ein Inlining durchgeführt wurde:

  • Die Plan-xml-Datei enthält keinen <UserDefinedFunction>-xml-Knoten für eine UDF, die erfolgreich inlined wurde.
  • Bestimmte erweiterte Events (XEvents) 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 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

Scalar UDF Inlining kann auf Datenbank-, Anweisungs- oder UDF-Ebene deaktiviert werden, wobei die Datenbankkompatibilitätsstufe 150 und höher erhalten bleibt. Um Scalar UDF Inlining auf der Ebene der Datenbank zu deaktivieren, führen Sie die folgende Anweisung im Kontext der betreffenden Datenbank aus:

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 die Option auf ON festgelegt ist, wird die Einstellung in sys.database_scoped_configurations als „aktiviert“ angezeigt. 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 oben genannte 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 für die benutzerdefinierte Funktion kein Inlining durchgeführt werden kann, wird ein Fehler ausgegeben.

Wichtige Hinweise

Wie in diesem Artikel beschrieben, wandelt Scalar UDF Inlining eine Abfrage mit skalaren UDFs in eine Abfrage mit einer entsprechenden skalaren Unterabfrage um. Durch diese Transformation kann es in folgenden Szenarios zu Unterschieden bei der Verhaltensweise kommen:

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

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

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

  4. 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.

  5. 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.

  6. 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).

  7. Wenn eine Variable mit dem Ergebnis einer Inline-UDF zugewiesen und auch als index_column_name im FORCESEEK-Abfragehinweis verwendet wird, führt dies zu dem Fehler Msg 8622, der angibt, dass der Abfrageprozessor aufgrund der in der Abfrage definierten Hinweise keinen Abfrageplan erstellen konnte.

Weitere Informationen