- Java & MySQL 教程
- Java & MySQL - 首頁
- Java & MySQL - 概述
- Java & MySQL - 環境設定
- Java & MySQL - 示例程式碼
- Java & MySQL - 連線
- Java & MySQL - 異常
- Java & MySQL 語句
- Java & MySQL - Statement
- Java & MySQL - PreparedStatement
- Java & MySQL - 可呼叫語句 (CallableStatement)
- Java & MySQL 結果
- Java & MySQL - 結果集 (Result Set)
- Java & MySQL - 遍歷結果集
- Java & MySQL - 檢視結果集
- Java & MySQL - 更新結果集
- Java & MySQL 事務
- Java & MySQL - 事務
- Java & MySQL - 提交 & 回滾
- Java & MySQL - 儲存點事務
- Java & MySQL 批次處理
- Java & MySQL - 批次處理
- 批次處理 - Statement
- 批次處理 - PreparedStatement
- Java & MySQL 流處理
- Java & MySQL - 流式資料
- Java & MySQL 示例
- Java & MySQL - 建立資料庫
- Java & MySQL - 選擇資料庫
- Java & MySQL - 刪除資料庫
- Java & MySQL - 建立表
- Java & MySQL - 刪除表
- Java & MySQL - 插入記錄
- Java & MySQL - 查詢記錄
- Java & MySQL - 更新記錄
- Java & MySQL - 刪除記錄
- Java & MySQL - WHERE 子句
- Java & MySQL - LIKE 子句
- Java & MySQL - 資料排序
- Java & MySQL 有用資源
- Java & MySQL - 快速指南
- Java & MySQL - 有用資源
- Java & MySQL - 討論
Java & MySQL - 可呼叫語句 (CallableStatement)
CallableStatement 介面用於執行對資料庫儲存過程的呼叫。
假設您需要在 TUTORIALSPOINT 資料庫中執行以下儲存過程:
DELIMITER $$ DROP PROCEDURE IF EXISTS `TUTORIALSPOINT`.`getEmpName` $$ CREATE PROCEDURE `TUTORIALSPOINT`.`getEmpName` (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255)) BEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID; END $$ DELIMITER ;
引數存在三種類型:IN、OUT 和 INOUT。PreparedStatement 物件僅使用 IN 引數。CallableStatement 物件可以使用所有三種類型。
以下是每種型別的定義:
| 引數 | 描述 |
|---|---|
| IN | 建立 SQL 語句時其值未知的引數。您可以使用 setXXX() 方法將值繫結到 IN 引數。 |
| OUT | 由 SQL 語句返回其值的引數。您可以使用 getXXX() 方法從 OUT 引數檢索值。 |
| INOUT | 同時提供輸入和輸出值的引數。您可以使用 setXXX() 方法繫結變數,並使用 getXXX() 方法檢索值。 |
以下程式碼片段演示瞭如何使用Connection.prepareCall() 方法基於前面的儲存過程例項化CallableStatement 物件:
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
字串變數 SQL 表示儲存過程,帶有引數佔位符。
使用 CallableStatement 物件的方式與使用 PreparedStatement 物件非常相似。您必須在執行語句之前將值繫結到所有引數,否則將收到 SQLException。
如果您有 IN 引數,只需遵循適用於 PreparedStatement 物件的相同規則和技術;使用與您正在繫結的 Java 資料型別對應的 setXXX() 方法。
當您使用 OUT 和 INOUT 引數時,必須使用另一個 CallableStatement 方法 registerOutParameter()。registerOutParameter() 方法將 JDBC 資料型別繫結到儲存過程預期返回的資料型別。
呼叫儲存過程後,您可以使用相應的 getXXX() 方法從 OUT 引數檢索值。此方法將檢索到的 SQL 型別的值轉換為 Java 資料型別。
關閉 CallableStatement 物件
就像關閉其他 Statement 物件一樣,出於同樣的原因,您也應該關閉 CallableStatement 物件。
簡單的 close() 方法呼叫即可完成此操作。如果您首先關閉 Connection 物件,它也會關閉 CallableStatement 物件。但是,您應該始終顯式關閉 CallableStatement 物件以確保正確清理。
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
cstmt.close();
}
我們使用 try-with-resources,它會自動處理資源關閉。以下示例演示了上述所有概念。
此程式碼是基於上一章中完成的環境和資料庫設定編寫的。
將以下示例複製並貼上到 TestApplication.java 中,編譯並執行如下:
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class TestApplication {
static final String DB_URL = "jdbc:mysql:///TUTORIALSPOINT";
static final String USER = "guest";
static final String PASS = "guest123";
static final String QUERY = "{call getEmpName (?, ?)}";
public static void main(String[] args) {
// Open a connection
try(Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
CallableStatement stmt = conn.prepareCall(QUERY);
) {
// Bind values into the parameters.
stmt.setInt(1, 102); // This would set ID
// Because second parameter is OUT so register it
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
//Use execute method to run stored procedure.
System.out.println("Executing stored procedure..." );
stmt.execute();
//Retrieve employee name with getXXX method
String empName = stmt.getString(2);
System.out.println("Emp Name with ID: 102 is " + empName);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
現在讓我們按如下方式編譯上述示例:
C:\>javac TestApplication.java C:\>
執行TestApplication 時,它會產生以下結果:
C:\>java TestApplication Executing stored procedure... Emp Name with ID: 102 is Zaid C:\>
JDBC SQL 轉義語法
轉義語法使您可以靈活地使用使用標準 JDBC 方法和屬性無法使用的資料庫特定功能。
一般的 SQL 轉義語法格式如下:
{keyword 'parameters'}
以下是一些在執行 JDBC 程式設計時會發現非常有用的轉義序列:
d、t、ts 關鍵字
它們有助於標識日期、時間和時間戳文字。如您所知,沒有兩個 DBMS 以相同的方式表示時間和日期。此轉義語法告訴驅動程式以目標資料庫的格式呈現日期或時間。例如:
{d 'yyyy-mm-dd'}
其中 yyyy = 年,mm = 月;dd = 日。使用此語法 {d '2009-09-03'} 是 2009 年 3 月 9 日。
這是一個簡單的示例,演示如何將日期插入表中:
//Create a Statement object
stmt = conn.createStatement();
//Insert data ==> ID, First Name, Last Name, DOB
String sql="INSERT INTO STUDENTS VALUES" +
"(100,'Zara','Ali', {d '2001-12-16'})";
stmt.executeUpdate(sql);
同樣,您可以使用以下兩種語法之一,即t 或ts:
{t 'hh:mm:ss'}
其中 hh = 小時;mm = 分鐘;ss = 秒。使用此語法 {t '13:30:29'} 是下午 1:30:29。
{ts 'yyyy-mm-dd hh:mm:ss'}
這是上面兩種語法 'd' 和 't' 的組合語法,用於表示時間戳。
escape 關鍵字
此關鍵字標識在 LIKE 子句中使用的跳脫字元。在使用 SQL 萬用字元 %(匹配零個或多個字元)時很有用。例如:
String sql = "SELECT symbol FROM MathSymbols WHERE symbol LIKE '\%' {escape '\'}";
stmt.execute(sql);
如果您使用反斜槓字元 (\) 作為跳脫字元,則還必須在 Java 字串文字中使用兩個反斜槓字元,因為反斜槓也是 Java 跳脫字元。
fn 關鍵字
此關鍵字表示 DBMS 中使用的標量函式。例如,您可以使用 SQL 函式length 獲取字串的長度:
{fn length('Hello World')}
這將返回 11,即字元字串“Hello World”的長度。
call 關鍵字
此關鍵字用於呼叫儲存過程。例如,對於需要 IN 引數的儲存過程,請使用以下語法:
{call my_procedure(?)};
對於需要 IN 引數並返回 OUT 引數的儲存過程,請使用以下語法:
{? = call my_procedure(?)};
oj 關鍵字
此關鍵字用於表示外連線。語法如下:
{oj outer-join}
其中 outer-join = 表 {LEFT|RIGHT|FULL} OUTER JOIN {表 | outer-join} on 搜尋條件。例如:
String sql = "SELECT Employees FROM {oj ThisTable RIGHT OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);