1. 程式人生 > >JDBC呼叫SQL儲存過程返回遊標

JDBC呼叫SQL儲存過程返回遊標

1.1         CREATE  PROCEDURE  (建立)

CREATE PROCEDURE儲存過程名 (引數列表)
   BEGIN
SQL語句程式碼塊
END
注意:
由括號包圍的引數列必須總是存在。如果沒有引數,也該使用一個空引數列()。每個引數預設都是一個IN引數。要指定為其它引數,可在引數名之前使用關鍵詞 OUT或INOUT
mysql客戶端定義儲存過程的時候使用delimiter命令來把語句定界符從;變為//。
當使用delimiter命令時,你應該避免使用反斜槓(‘"’)字元,因為那是MySQL的轉義字元。
如:
mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
    -> BEGIN
    ->   SELECT COUNT(*) INTO param1 FROM t;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

1.2         ALTER  PROCEDURE (修改)

ALTER PROCEDURE 儲存過程名SQL語句程式碼塊
這個語句可以被用來改變一個儲存程式的特徵。

1.3         DROP  PROCEDURE (刪除)

DROP PROCEDURE  IF  EXISTS儲存過程名

eg:DROP PROCEDURE IF EXISTS proc_employee (proc_employee 儲存過程名)

這個語句被用來移除一個儲存程式。不能在一個儲存過程中刪除另一個儲存過程,只能呼叫另一個儲存過程

1.4         SHOW  CREATE  PROCEDURE(類似於SHOW CREATE TABLE,檢視一個已存在的儲存過程)

SHOW CREATE PROCEDURE 儲存過程名

1.5         SHOW  PROCEDURE  STATUS (列出所有的儲存過程)

SHOW  PROCEDURE  STATUS

1.6         CALL語句(儲存過程的呼叫)

CALL 儲存過程名(引數列表)

CALL語句呼叫一個先前用CREATE PROCEDURE建立的程式。
CALL語句可以用宣告為OUT或的INOUT引數的引數給它的呼叫者傳回值。
儲存過程名稱後面必須加括號,哪怕該儲存過程沒有引數傳遞

1.7         BEGIN ... END(複合語句)

[begin_label:] 
BEGIN
    [statement_list]
END 
[end_label]

儲存子程式可以使用BEGIN ... END複合語句來包含多個語句。

statement_list 代表一個或多個語句的列表。statement_list之內每個語句都必須用分號(;)來結尾。

複合語句可以被標記。除非begin_label存在,否則end_label不能被給出,並且如果二者都存在,他們必須是同樣的。

1.8         DECLARE語句(用來宣告區域性變數)

DECLARE語句被用來把不同專案局域到一個子程式:區域性變數

DECLARE僅被用在BEGIN ... END複合語句裡,並且必須在複合語句的開頭,在任何其它語句之前。

1.9         儲存程式中的變數

1.1             DECLARE區域性變數

DECLARE var_name[,...] type [DEFAULT value]
這個語句被用來宣告區域性變數。
要給變數提供一個預設值,請包含一個DEFAULT子句。
值可以被指定為一個表示式,不需要為一個常數。
如果沒有DEFAULT子句,初始值為NULL。
區域性變數的作用範圍在它被宣告的BEGIN ... END塊內。
它可以被用在巢狀的塊中,除了那些用相同名字宣告變數的塊。

1.2             變數SET語句

SET var_name = expr [, var_name = expr] 
在儲存程式中的SET語句是一般SET語句的擴充套件版本。
被參考變數可能是子程式內宣告的變數,或者是全域性伺服器變數。
在儲存程式中的SET語句作為預先存在的SET語法的一部分來實現。這允許SET a=x, b=y, ...這樣的擴充套件語法。
其中不同的變數型別(局域宣告變數及全域性和集體變數)可以被混合起來。
這也允許把區域性變數和一些只對系統變數有意義的選項合併起來。

1.3             SELECT ... INTO語句

SELECT col_name[,...] INTO var_name[,...] table_expr
這個SELECT語法把選定的列直接儲存到變數。
因此,只有單一的行可以被取回。
SELECT id,data INTO x,y FROM test.t1 LIMIT 1;
注意,使用者變數名在MySQL 5.1中是對大小寫不敏感的。

重要: SQL變數名不能和列名一樣。如果SELECT ... INTO這樣的SQL語句包含一個對列的參考,幷包含一個與列相同名字的區域性變數,MySQL當前把參考解釋為一個變數的名字。

1.10     MySQL 儲存過程引數型別(in、out、inout)

此小節內容來自:

參見地址:http://www.blogjava.net/nonels/archive/2009/04/22/233324.html

MySQL 儲存過程引數(in)

MySQL 儲存過程 “in” 引數:跟 C 語言的函式引數的值傳遞類似, MySQL 儲存過程內部可能會修改此引數,但對 in 型別引數的修改,對呼叫者(caller)來說是不可見的(not visible)。

MySQL 儲存過程引數(out)

MySQL 儲存過程 “out” 引數:從儲存過程內部傳值給呼叫者。在儲存過程內部,該引數初始值為 null,無論呼叫者是否給儲存過程引數設定值

MySQL 儲存過程引數(inout)

MySQL 儲存過程 inout 引數跟 out 類似,都可以從儲存過程內部傳值給呼叫者。不同的是:呼叫者還可以通過 inout 引數傳遞值給儲存過程。

總結

如果僅僅想把資料傳給 MySQL 儲存過程,那就使用“in” 型別引數;如果僅僅從 MySQL 儲存過程返回值,那就使用“out” 型別引數;如果需要把資料傳給 MySQL 儲存過程,還要經過一些計算後再傳回給我們,此時,要使用“inout” 型別引數。

1.11     例子:

1.1            建立儲存過程

帶(輸出引數)返回值的儲存過程:

--刪除儲存過程

DROP PROCEDURE IF EXISTS proc_employee_getCount

--建立儲存過程

CREATE PROCEDURE proc_employee_getCount(out n int)

BEGIN

     SELECT COUNT(*) FROM employee ;

END

--MYSQL呼叫儲存過程

CALL proc_employee_getCount(@n);

帶輸入引數的儲存過程:

--刪除儲存過程

DROP PROCEDURE IF EXISTS proc_employee_findById;

--建立儲存過程

CREATE PROCEDURE proc_employee_findById(in n int)

BEGIN

     SELECT * FROM employee where id=n;

END

--定義變數

SET @n=1;

--呼叫儲存過程

CALL proc_employee_findById(@n);

操作儲存過程時應注意:

1.          刪除儲存過程時只需要指定儲存過程名即可,不帶括號;

2.          建立儲存過程時,不管該儲存過程有無引數,都需要帶括號;

3.          在使用SET定義變數時應遵循SET的語法規則;

SET @變數名=初始值;

4.          在定義儲存過程引數列表時,應注意引數名與資料庫中欄位名區別開來,否則將出現無法預期的結果

1.12     Java程式碼呼叫儲存過程(JDBC)

相關API:java.sql.CallableStatement

使用到java.sql.CallableStatement介面,該介面專門用來呼叫儲存過程;

該物件的獲得依賴於java.sql.Connection;

通過Connection例項的prepareCall()方法返回CallableStatement物件

prepareCall()內部為一固定寫法{call 儲存過程名(引數列表1,引數列表2)}可用?佔位

eg: connection.prepareCall("{call proc_employee(?)}");

儲存過程中引數處理:

輸入引數:通過java.sql.CallableStatement例項的setXXX()方法賦值,用法等同於java.sql.PreparedStatement

輸出引數:通過java.sql.CallableStatement例項的registerOutParameter(引數位置, 引數型別)方法賦值,其中引數型別主要使用java.sql.Types中定義的型別

Java程式碼呼叫帶輸入引數的儲存過程 (根據輸入ID查詢僱員資訊)

publicvoid executeProcedure()

    {

        try {

            /**

             *callableStatementjava.sql.CallableStatement

             *connectionjava.sql.Connection

             *jdbc呼叫儲存過程原型

             *{call儲存過程名(引數列表1,引數列表2)}可用?代替

             */

            callableStatement=connection.prepareCall("{call proc_employee_findById(?)}");

            callableStatement.setInt(1, 1); //設定輸入引數

            resultSet=callableStatement.executeQuery();//執行儲存過程

            if(resultSet.next())

            {

                System.out.println(resultSet.getInt(1)+""t"+resultSet.getString(2));

            }

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }  

Java程式碼呼叫帶輸出引數的儲存過程 (返回資料庫中的記錄數)

publicvoid executeProcedure()

    {

        try {

            /**

             *callableStatementjava.sql.CallableStatement

             *connectionjava.sql.Connection

             *jdbc呼叫儲存過程原型

             *{call儲存過程名(引數列表1,引數列表2)}可用?代替

             */

            callableStatement=connection.prepareCall("{call proc_employee_getCount(?)}");

            //設定輸出引數

            callableStatement.registerOutParameter(1, Types.INTEGER);

            //執行儲存過程

            resultSet=callableStatement.executeQuery();

            if(resultSet.next())

            {

                System.out.println(resultSet.getInt(1));

            }

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }