Aufrufen einer gespeicherten Prozedur (OLE DB)
Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)
Eine gespeicherte Prozedur kann 0 oder mehr Parameter haben. Sie kann auch einen Wert zurückgeben: Wenn Sie den OLE DB-Treiber für SQL Server verwenden, können Parameter wie folgt 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-Treiber für SQL Server 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. Dieser Aufruf muss erfolgen, bevor der Befehl erfolgreich vorbereitet werden kann. Diese Anforderung ist der Tatsache geschuldet, dass der interne Name einer temporär gespeicherten Prozedur sich von dem von einem Client verwendeten externen Name unterscheidet. MSOLEDBSQL kann die Systemtabellen nicht abfragen, um die Parameterinformationen für eine temporär gespeicherte Prozedur zu ermitteln.
Der Parameterbindungsprozess umfasst die folgenden Schritte:
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.
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
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.
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
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 OLE DB-Treiber für SQL Server:
- 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 die Prozedur mehrmals aufgerufen wird, bietet die RPC-Escapesequenz die beste Leistung der drei Möglichkeiten, eine gespeicherte Prozedur aufzurufen.
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 zurück. Sie können für die gespeicherte Prozedur außerdem keinen SQL Server-Cursor ö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 SQL-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-Treiber für SQL Server verwendet den RPC-Mechanismus von SQL Server zum Optimieren der Befehlsverarbeitung. Das RPC-Protokoll steigert die Leistung, indem es einen Großteil der Parameterverarbeitung und Anweisungsauswertung auf dem Server überflüssig macht.
Nachfolgend sehen Sie ein SQL-Beispiel der EXECUTE-Anweisung (Transact-SQL):
EXECUTE SalesByCategory 'Produce', '1995'