Verwenden von gespeicherten Prozeduren mit Ausgabeparametern
Eine aufrufbare gespeicherte SQL Server-Prozedur gibt mindestens einen OUT-Parameter zurück, mit dem die gespeicherte Prozedur Daten an die aufrufende Anwendung zurückgibt. Der Microsoft-JDBC-Treiber für SQL Server stellt die Klasse SQLServerCallableStatement bereit, mit der Sie diese Art gespeicherter Prozedur aufrufen und die zurückgegebenen Daten verarbeiten können.
Wenn Sie diese Art von gespeicherter Prozedur mit dem JDBC-Treiber aufrufen, müssen Sie die SQL-Escapesequenz call
zusammen mit der prepareCall-Methode der SQLServerConnection-Klasse verwenden. Die Syntax für die Escapesequenz call
mit OUT-Parameter lautet wie folgt:
{call procedure-name[([parameter][,[parameter]]...)]}
Hinweis
Weitere Informationen zu SQL-Escapesequenzen finden Sie unter Verwenden von SQL-Escapesequenzen.
Geben Sie die OUT-Parameter beim Erstellen der Escapesequenz call
mit dem Fragezeichen (?) an. das als Platzhalter für die Parameterwerte fungiert, die von der gespeicherten Prozedur zurückgegeben werden. Sie müssen den Datentyp für jeden Parameter angeben, um einen Wert für einen OUT-Parameter festzulegen, indem Sie die Methode registerOutParameter der Klasse „SQLServerCallableStatement“ verwenden, bevor Sie die gespeicherte Prozedur ausführen.
Bei dem Wert, den Sie für den OUT-Parameter in der Methode „registerOutParameter“ angeben, muss es sich um einen der in „java.sql.Types“ enthaltenen JDBC-Datentypen handeln, der wiederum einem der nativen SQL Server-Datentypen zugeordnet wird. Weitere Informationen zu JDBC- und SQL Server-Datentypen finden Sie unter Grundlegendes zu den Datentypen des JDBC-Treibers.
Wenn Sie einen Wert an die Methode „registerOutParameter“ für einen OUT-Parameter übergeben, müssen Sie nicht nur den für den Parameter zu verwendenden Datentyp angeben, sondern auch die ordinale Position des Parameters oder den Namen des Parameters der gespeicherten Prozedur. Wenn die gespeicherte Prozedur beispielsweise einen einzigen OUT-Parameter enthält, ist der Ordinalwert 1. Wenn die gespeicherte Prozedur zwei Parameter enthält, ist der erste Ordinalwert 1 und der zweite Ordinalwert 2.
Hinweis
Die Verwendung der SQL Server-Datentypen CURSOR, SQLVARIANT, TABLE und TIMESTAMP als OUT-Parameter wird vom JDBC-Treiber nicht unterstützt.
Erstellen Sie als Beispiel die folgende gespeicherte Prozedur in der AdventureWorks2022-Beispieldatenbank:
CREATE PROCEDURE GetImmediateManager
@employeeID INT,
@managerID INT OUTPUT
AS
BEGIN
SELECT @managerID = ManagerID
FROM HumanResources.Employee
WHERE EmployeeID = @employeeID
END
Diese gespeicherte Prozedur gibt abhängig vom angegebenen IN-Parameter "employeeID" (ein integer-Wert) einen einzigen OUT-Parameter "managerID" zurück (ebenfalls ein integer-Wert). Bei dem im OUT-Parameter zurückgegebenen Wert handelt es sich um die auf "EmployeeID" basierende "ManagerID", die in der Tabelle "HumanResources.Employee" enthalten ist.
Im folgenden Beispiel wird eine offene Verbindung zur AdventureWorks2022-Beispieldatenbank an die Funktion übergeben und die Methode execute wird zum Aufruf der gespeicherten Prozedur GetImmediateManager verwendet:
public static void executeStoredProcedure(Connection con) throws SQLException {
try(CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}");) {
cstmt.setInt(1, 5);
cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
cstmt.execute();
System.out.println("MANAGER ID: " + cstmt.getInt(2));
}
}
In diesem Beispiel werden die Ordnungspositionen verwendet, um die Parameter zu identifizieren. Alternativ können Sie einen Parameter mit seinem Namen anstelle der Ordnungsposition identifizieren. Im folgenden Codebeispiel wird das vorhergehende Beispiel geändert, um die Verwendung von benannten Parametern in einer Java-Anwendung zu veranschaulichen. Beachten Sie, dass die Parameternamen den Parameternamen in der Definition der gespeicherten Prozedur entsprechen:
public static void executeStoredProcedure(Connection con) throws SQLException {
try(CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}"); ) {
cstmt.setInt("employeeID", 5);
cstmt.registerOutParameter("managerID", java.sql.Types.INTEGER);
cstmt.execute();
System.out.println("MANAGER ID: " + cstmt.getInt("managerID"));
}
}
Für Treiber der Version 12.6 und höher wurde eine neue Verbindungseigenschaft useFlexibleCallableStatements
eingeführt. Wenn diese Eigenschaft auf true
festgelegt wird, bleibt das alte Verhalten des Treibers erhalten, sodass Benutzer beim Identifizieren von Parametern eine Mischung aus Ordnungspositionen und Parameternamen verwenden können. Wenn die Eigenschaft auf false
festgelegt wird, kann der Benutzer nur eine dieser Möglichkeiten, nicht aber beide verwenden.
Darüber hinaus behält useFlexibleCallableStatements
das bisherige Verhalten in Bezug auf die flexible Reihenfolge zum Festlegen der Anweisungsparameter bei, wenn die Eigenschaft auf true
festgelegt wird. Wenn sie dagegen auf false
festgelegt wird, muss die Reihenfolge mit der Definition der gespeicherten Prozedur übereinstimmen. Beide Features für useFlexibleCallableStatements=true
sind im folgenden Beispiel zu sehen:
public static void executeStoredProcedure(Connection con) throws SQLException {
try(CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}"); ) {
cstmt.registerOutParameter("managerID", java.sql.Types.INTEGER);
cstmt.setInt(1, 5);
cstmt.execute();
System.out.println("MANAGER ID: " + cstmt.getInt("managerID"));
}
}
Hinweis
In diesen Beispielen wird die execute-Methode der SQLServerCallableStatement-Klasse zum Ausführen der gespeicherten Prozedur verwendet. da von der gespeicherten Prozedur nicht auch ein Resultset zurückgegeben wurde. Andernfalls müsste die executeQuery-Methode verwendet werden.
Gespeicherte Prozeduren können Updatezählungen und mehrere Resultsets zurückgeben. Der Microsoft JDBC-Treiber für SQL Server folgt der JDBC 3.0-Spezifikation, die festlegt, dass mehrere Resultsets und Updatezählungen vor dem Abrufen der OUT-Parameter abgerufen werden. Dies bedeutet, dass die Anwendung alle ResultSet-Objekte und Updatezählungen abrufen sollte, bevor die OUT-Parameter mit den CallableStatement.getter-Methoden abgerufen werden. Andernfalls gehen die noch nicht abgerufenen ResultSet-Objekte und Updatezählungen verloren, wenn die OUT-Parameter abgerufen werden. Weitere Informationen zu Updatezählungen und mehreren Resultsets finden Sie unter Verwenden einer gespeicherten Prozedur mit aktualisierten Zählerwerten und Verwenden mehrerer Resultsets.