Parameter und Wiederverwendung von Ausführungsplänen

Durch die Verwendung von Parametern, einschließlich der Parametermarkierungen in ADO-, OLE DB- und ODBC-Anwendungen, kann die Wiederverwendbarkeit von Ausführungsplänen erhöht werden.

SicherheitshinweisSicherheitshinweis

Es ist sicherer, Parameter oder Parametermarkierungen zu verwenden, die vom Endbenutzer eingegebene Werte enthalten, als die Werte in einer Zeichenfolge zu verketten, die dann mithilfe einer API-Datenzugriffsmethode, einer EXECUTE-Anweisung oder einer gespeicherten sp_executesql-Prozedur ausgeführt werden.

Die zwei folgenden SELECT-Anweisungen unterscheiden sich lediglich im Hinblick auf die Werte, die in der WHERE-Klausel verglichen werden:

SELECT * 
FROM AdventureWorks2008R2.Production.Product 
WHERE ProductSubcategoryID = 1;

SELECT * 
FROM AdventureWorks2008R2.Production.Product 
WHERE ProductSubcategoryID = 4;

Die Ausführungspläne für diese Abfragen unterscheiden sich lediglich hinsichtlich des Werts, der für den Vergleich mit der ProductSubcategoryID-Spalte gespeichert wird. Das Ziel von SQL Server, stets zu erkennen, wenn Anweisungen im Prinzip den gleichen Plan generieren, und diesen Plan dann wiederzuverwenden, kann von SQL Server in komplexen SQL-Anweisungen manchmal nicht erfüllt werden.

Wenn Sie Konstanten mithilfe von Parametern von den SQL-Anweisungen trennen, unterstützen Sie das relationale Modul dabei, doppelte Pläne zu erkennen. Es gibt folgende Möglichkeiten, um Parameter zu verwenden:

  • Verwenden Sie sp_executesql in Transact-SQL:

    DECLARE @MyIntParm INT
    SET @MyIntParm = 1
    EXEC sp_executesql
      N'SELECT * 
      FROM AdventureWorks2008R2.Production.Product 
      WHERE ProductSubcategoryID = @Parm',
      N'@Parm INT',
      @MyIntParm
    

    Diese Methode wird für Transact-SQL-Skripts, gespeicherte Prozeduren oder Trigger empfohlen, die SQL-Anweisungen dynamisch generieren.

  • ADO, OLE DB und ODBC verwenden Parametermarkierungen. Parametermarkierungen sind Fragezeichen (?), die eine Konstante in einer SQL-Anweisung ersetzen und an eine Programmvariable gebunden sind. Beispielsweise können Sie in einer ODBC-Anwendung folgende Aktionen ausführen:

    • Verwenden Sie SQLBindParameter, um eine ganzzahlige Variable an die erste Parametermarkierung in einer SQL-Anweisung zu binden.

    • Speichern Sie den ganzzahligen Wert in der Variablen.

    • Führen Sie die Anweisung aus, und geben Sie dabei die Parametermarkierung (?) an:

      SQLExecDirect(hstmt, 
        "SELECT * 
        FROM AdventureWorks2008R2.Production.Product 
        WHERE ProductSubcategoryID = ?",
        SQL_NTS);
      

      Der SQL Server Native Client-OLE DB-Anbieter und der SQL Server Native Client-ODBC-Treiber, die beide mit SQL Server zur Verfügung gestellt werden, verwenden sp_executesql, um Anweisungen an SQL Server zu senden, wenn Parametermarkierungen in Anwendungen verwendet werden.

  • Zum Entwerfen von gespeicherten Prozeduren mit vorprogrammierter Parameterverwendung

Wenn Sie beim Entwerfen ihrer Anwendungen nicht explizit Parameter in diese einbauen, können Sie auch den SQL Server-Abfrageoptimierer heranziehen, um bestimmte Abfragen mithilfe des Standardverhaltens der einfachen Parametrisierung (siehe Einfache Parametrisierung) automatisch zu parametrisieren. Sie können auch erzwingen, dass der Abfrageoptimierer die Parametrisierung aller Abfragen in der Datenbank in Betracht zieht, indem Sie die PARAMETERIZATION-Option der ALTER DATABASE-Anweisung auf FORCED festlegen. Weitere Informationen finden Sie unter Erzwungene Parametrisierung.

Auch wenn die erzwungene Parametrisierung aktiviert ist, kann die einfache Parametrisierung erfolgen. Die folgende Abfrage kann beispielsweise gemäß den Regeln der erzwungenen Parametrisierung nicht parametrisiert werden:

SELECT * FROM Person.Address
WHERE AddressID = 1 + 2;

Sie kann jedoch nach den Regeln der einfachen Parametrisierung parametrisiert werden. Wenn die erzwungene Parametrisierung einen Fehler erzeugt, wird anschließend die einfache Parametrisierung versucht.