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(); } } |