Freigeben über


Gespeicherte Prozeduren – Aufrufen in SQL Server Native Client

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL verwaltete Instanz Azure Synapse Analytics Analytics Platform System (PDW)

Wichtig

Der SQL Server Native Client (häufig abgekürzt mit SNAC) wurde aus SQL Server 2022 (16.x) und SQL Server Management Studio 19 (SSMS) entfernt. Sowohl der OLE DB-Anbieter für den SQL Server Native Client (SQLNCLI oder SQLNCLI11) als auch der Microsoft OLE DB-Legacyanbieter für SQL Server (SQLOLEDB) werden für Neuentwicklungen nicht empfohlen. Verwenden Sie in Zukunft den neuen Microsoft OLE DB-Treiber für SQL Server (MSOLEDBSQL).

Eine gespeicherte Prozedur kann 0 oder mehr Parameter haben. Sie kann auch einen Wert zurückgeben: Bei Verwendung des OLE DB-Anbieters für sql Server Native Client können Parameter an eine gespeicherte Prozedur übergeben werden:

  • Durch Hartcodierung des Datenwerts

  • Durch Verwendung einer Parametermarkierung (?) zum Angeben von Parametern, Binden einer Programmvariablen an die Parametermarkierung und Einfügen des Datenwerts in die Programmvariable

Hinweis

Wenn gespeicherte SQL Server-Prozeduren mit benannten Parametern mit OLE DB aufgerufen werden, müssen die Parameternamen mit dem Zeichen „@“ beginnen. Dies ist eine SQL Server-spezifische Einschränkung. Der OLE DB-Anbieter von SQL Server Native Client erzwingt diese Einschränkung strenger als MDAC.

Damit Parameter unterstützt werden, wird die ICommandWithParameters-Schnittstelle auf dem Befehlsobjekt verfügbar gemacht. Wenn die Parameter verwendet werden sollen, beschreibt der Consumer die Parameter zunächst dem Anbieter, indem er die ICommandWithParameters::SetParameterInfo-Methode aufruft (oder optional eine Aufrufanweisung vorbereitet, die die GetParameterInfo-Methode aufruft). Der Consumer erstellt dann einen Accessor, der die Struktur eines Puffers angibt und Parameterwerte in diesen Puffer einfügt. Schließlich übergibt er das Handle des Accessors und einen Zeiger auf den Puffer an Execute. Bei späteren Aufrufen von Execute fügt der Consumer neue Parameterwerte in den Puffer ein und ruft Execute mit dem Accessorhandle und Pufferzeiger auf.

Ein Befehl, der eine temporär gespeicherte Prozedur mit Parametern aufruft, muss zunächst ICommandWithParameters::SetParameterInfo aufrufen, um die Parameterinformationen zu definieren, bevor der Befehl erfolgreich vorbereitet werden kann. Der Grund dafür ist, dass der interne Name für eine temporär gespeicherte Prozedur anders lautet als der externe Name, der von einem Client verwendet wird. Zudem kann SQLOLEDB die Systemtabellen nicht abfragen, um die Parameterinformationen für eine temporär gespeicherte Prozedur zu ermitteln.

Der Parameterbindungsprozess umfasst folgende Schritte:

  1. Geben Sie die Parameterinformationen in ein Array aus DBPARAMBINDINFO-Strukturen ein, also den Parameternamen, den anbieterspezifischen Namen für den Datentyp des Parameters oder einen standardmäßigen Datentypennamen usw. Jede Struktur im Array beschreibt einen Parameter. Dieses Array wird dann an die SetParameterInfo-Methode übergeben.

  2. Rufen Sie die ICommandWithParameters::SetParameterInfo-Methode auf, um dem Anbieter Parameter zu beschreiben. SetParameterInfo gibt den nativen Datentyp jedes Parameters an. SetParameterInfo-Argumente sind:

    • Die Anzahl von Parametern, für die Typinformationen festzulegen sind

    • Ein Array aus Ordnungszahlen von Parametern, für die Typinformationen festzulegen sind

    • Ein Array aus DBPARAMBINDINFO-Strukturen

  3. Erstellen Sie mit dem Befehl IAccessor::CreateAccessor einen Parameteraccessor. Der Accessor gibt die Struktur eines Puffers an und fügt Parameterwerte in den Puffer ein. Der Befehl CreateAccessor erstellt aus mehreren Bindungen einen Accessor. Diese Bindungen werden vom Consumer mithilfe eines Arrays aus DBBINDING-Strukturen beschrieben. Jede Bindung ordnet dem Puffer des Consumers einen einzelnen Parameter zu und enthält Informationen wie z. B.:

    • Die Ordnungszahl des Parameters, auf den sich die Bindung bezieht

    • Die Angabe, was gebunden wird (der Datenwert, seine Länge und sein Status)

    • Den Offset im Puffer zu jedem dieser Teile

    • Die Länge und den Typ des Datenwerts, wie er im Puffer des Consumers vorhanden ist

    Ein Accessor wird von seinem Handle identifiziert, das den Typ HACCESSOR aufweist. Dieses Handle wird von der CreateAccessor-Methode zurückgegeben. Sobald der Consumer einen Accessor nicht mehr benötigt, muss er die ReleaseAccessor-Methode aufrufen, um den belegten Arbeitsspeicher freizugeben.

    Wenn der Consumer eine Methode wie z.B. ICommand::Execute aufruft, übergibt er das Handle an einen Accessor und einen Zeiger auf den Puffer selbst. Der Anbieter verwendet diesen Accessor, um zu bestimmen, wie die im Puffer enthaltenen Daten übertragen werden.

  4. Geben Sie die DBPARAMS-Struktur ein. Die Consumervariablen, von denen Eingabeparameterwerte übernommen und in die Ausgabeparameterwerte geschrieben werden, werden zur Laufzeit an ICommand::Execute in der DBPARAMS-Struktur übergeben. Die DBPARAMS-Struktur beinhaltet drei Elemente:

    • Einen Zeiger auf den Puffer, aus dem der Anbieter Eingabeparameterdaten abruft und in den der Anbieter Ausgabeparameterdaten zurückgibt, gemäß den vom Accessorhandle angegebenen Bindungen

    • Die Anzahl von Parametersätzen im Puffer

    • Das in Schritt 3 erstellte Accessorhandle

  5. Führen Sie den Befehl mit ICommand::Execute aus.

Methoden zum Aufrufen einer gespeicherten Prozedur

Beim Ausführen einer gespeicherten Prozedur in SQL Server unterstützt der OLE DB-Anbieter von SQL Server Native Client folgendes:

  • ODBC CALL-Escapesequenz

  • RPC-Escapesequenz (Remote Procedure Call, Remoteprozeduraufruf)

  • EXECUTE-Anweisung (Transact-SQL)

ODBC CALL-Escapesequenz

Wenn Sie die Parameterinformationen kennen, rufen Sie die ICommandWithParameters::SetParameterInfo-Methode auf, um dem Anbieter die Parameter zu beschreiben. Wenn hingegen die ODBC CALL-Syntax zum Aufrufen einer gespeicherten Prozedur verwendet wird, ruft der Anbieter eine Hilfsfunktion auf, um die Parameterinformationen der gespeicherten Prozedur zu ermitteln.

Wenn Sie nicht sicher sind, was die Parameterinformationen (Parametermetadaten) betrifft, empfiehlt sich die Verwendung der ODBC CALL-Syntax.

Die allgemeine Syntax zum Aufrufen einer Prozedur mit der ODBC CALL-Escapesequenz lautet:

{[?=]callProzedurname[([Parameter][,[Parameter]]...)]}

Beispiel:

{call SalesByCategory('Produce', '1995')}  

RPC-Escapesequenz

Die RPC-Escapesequenz ist der ODBC CALL-Syntax für den Aufruf einer gespeicherten Prozedur ähnlich. Wenn Sie die Prozedur mehrmals aufrufen müssen, ist die RPC-Escapesequenz von den drei Methoden zum Aufrufen einer gespeicherten Prozedur die leistungsfähigste.

Wenn die RPC-Escapesequenz zur Ausführung einer gespeicherten Prozedur verwendet wird, ruft der Anbieter keine Hilfsfunktion auf, um die Parameterinformationen zu ermitteln (wie dies bei der ODBC CALL-Syntax der Fall ist). Die RPC-Syntax ist einfacher als die ODBC CALL-Syntax, weshalb der Befehl schneller verarbeitet und die Leistung gesteigert wird. In diesem Fall müssen Sie die Parameterinformationen durch Ausführen von ICommandWithParameters::SetParameterInfo bereitstellen.

Bei der RPC-Escapesequenz ist es erforderlich, einen Rückgabewert zu erhalten. Wenn die gespeicherte Prozedur keinen Wert zurückgibt, gibt der Server standardmäßig 0 (null) zurück. Darüber hinaus können Sie keinen SQL Server-Cursor für die gespeicherte Prozedur öffnen. Die gespeicherte Prozedur wird implizit vorbereitet, und beim Aufruf von ICommandPrepare::Prepare tritt ein Fehler auf. Da es nicht möglich ist, einen RPC-Aufruf vorzubereiten, können keine Spaltenmetadaten abgefragt werden. IColumnsInfo::GetColumnInfo und IColumnsRowset::GetColumnsRowset geben DB_E_NOTPREPARED zurück.

Wenn Sie alle Parametermetadaten kennen, ist die RPC-Escapesequenz die empfohlene Methode für die Ausführung gespeicherter Prozeduren.

Es folgt ein Beispiel für eine RPC-Escapesequenz zum Aufrufen einer gespeicherten Prozedur:

{rpc SalesByCategory}  

Eine Beispielanwendung, die eine RPC-Escapesequenz veranschaulicht, finden Sie unter Ausführen einer gespeicherten Prozedur (mithilfe der RPC-Syntax) und Verarbeiten von Rückgabecode und Ausgabeparametern (OLE DB).

'EXECUTE'-Anweisung (Transact-SQL)

Die ODBC CALL-Escapesequenz und die RPC-Escapesequenz stellen im Vergleich zur EXECUTE-Anweisung die bevorzugten Methoden zum Aufrufen einer gespeicherten Prozedur dar. Der OLE DB-Anbieter von SQL Server Native Client verwendet den RPC-Mechanismus von SQL Server, um die Befehlsverarbeitung zu optimieren. Dieses RPC-Protokoll erhöht die Leistung, indem es einen Großteil der Parameterverarbeitung und Anweisungsauswertung auf dem Server überflüssig macht.

Dies ist ein Beispiel für die Transact-SQL EXECUTE-Anweisung :

EXECUTE SalesByCategory 'Produce', '1995'  

Weitere Informationen

Gespeicherte Prozeduren