文件首頁
MySQL Connector/J 開發人員指南
相關文件 下載本手冊
PDF (美式信紙) - 1.2Mb
PDF (A4) - 1.2Mb


MySQL Connector/J 開發人員指南  /  JDBC 概念  /  使用 JDBC CallableStatements 執行預存程序

7.3 使用 JDBC CallableStatements 執行預存程序

Connector/J 完全實作 java.sql.CallableStatement 介面。

如需有關 MySQL 預存程序的詳細資訊,請參閱使用預存常式

Connector/J 透過 JDBC 的 CallableStatement 介面公開預存程序功能。

以下範例顯示一個預存程序,該程序會傳回 inOutParam 的值加 1,並使用 inputParam 作為 ResultSet 傳入的字串

範例 7.3 Connector/J:呼叫預存程序

CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), \
                        INOUT inOutParam INT)
BEGIN
    DECLARE z INT;
    SET z = inOutParam + 1;
    SET inOutParam = z;

    SELECT inputParam;

    SELECT CONCAT('zyxw', inputParam);
END


若要搭配 Connector/J 使用 demoSp 程序,請依照下列步驟執行

  1. 使用 Connection.prepareCall() 準備可呼叫的陳述式。

    請注意,您必須使用 JDBC 跳脫語法,並且括住參數預留位置的括號不是選用的

    範例 7.4 Connector/J:使用 Connection.prepareCall()

    import java.sql.CallableStatement;
    
    ...
    
        //
        // Prepare a call to the stored procedure 'demoSp'
        // with two parameters
        //
        // Notice the use of JDBC-escape syntax ({call ...})
        //
    
        CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
    
    
    
        cStmt.setString(1, "abcdefg");

    注意

    Connection.prepareCall() 是一個昂貴的方法,因為驅動程式會執行中繼資料擷取以支援輸出參數。基於效能考量,請盡量減少不必要地呼叫 Connection.prepareCall(),方法是在您的程式碼中重複使用 CallableStatement 執行個體。

  2. 註冊輸出參數 (如果有的話)

    若要擷取輸出參數的值 (在您建立預存程序時指定為 OUTINOUT 的參數),JDBC 要求必須在執行陳述式之前使用 CallableStatement 介面中的各種 registerOutputParameter() 方法來指定這些參數

    範例 7.5 Connector/J:註冊輸出參數

    import java.sql.Types;
    ...
    //
    // Connector/J supports both named and indexed
    // output parameters. You can register output
    // parameters using either method, as well
    // as retrieve output parameters using either
    // method, regardless of what method was
    // used to register them.
    //
    // The following examples show how to use
    // the various methods of registering
    // output parameters (you should of course
    // use only one registration per parameter).
    //
    
    //
    // Registers the second parameter as output, and
    // uses the type 'INTEGER' for values returned from
    // getObject()
    //
    
    cStmt.registerOutParameter(2, Types.INTEGER);
    
    //
    // Registers the named parameter 'inOutParam', and
    // uses the type 'INTEGER' for values returned from
    // getObject()
    //
    
    cStmt.registerOutParameter("inOutParam", Types.INTEGER);
    ...


  3. 設定輸入參數 (如果有的話)

    輸入和輸入/輸出參數的設定方式與 PreparedStatement 物件相同。不過,CallableStatement 也支援依名稱設定參數

    範例 7.6 Connector/J:設定 CallableStatement 輸入參數

    ...
    
        //
        // Set a parameter by index
        //
    
        cStmt.setString(1, "abcdefg");
    
        //
        // Alternatively, set a parameter using
        // the parameter name
        //
    
        cStmt.setString("inputParam", "abcdefg");
    
        //
        // Set the 'in/out' parameter using an index
        //
    
        cStmt.setInt(2, 1);
    
        //
        // Alternatively, set the 'in/out' parameter
        // by name
        //
    
        cStmt.setInt("inOutParam", 1);
    
    ...


  4. 執行 CallableStatement,並擷取任何結果集或輸出參數。

    雖然 CallableStatement 支援呼叫任何 Statement 執行方法 (executeUpdate()executeQuery()execute()),但最彈性的呼叫方法是 execute(),因為您不需要事先知道預存程序是否會傳回結果集

    範例 7.7 Connector/J:擷取結果和輸出參數值

    ...
    
        boolean hadResults = cStmt.execute();
    
        //
        // Process all returned result sets
        //
    
        while (hadResults) {
            ResultSet rs = cStmt.getResultSet();
    
            // process result set
            ...
    
            hadResults = cStmt.getMoreResults();
        }
    
        //
        // Retrieve output parameters
        //
        // Connector/J supports both index-based and
        // name-based retrieval
        //
    
        int outputValue = cStmt.getInt(2); // index-based
    
        outputValue = cStmt.getInt("inOutParam"); // name-based
    
    ...