在前面的 JDBC-Statement 對象這章里,我們已經(jīng)學習了如何在 JDBC 中使用存儲過程。本章與該章有些類似,但本章將告訴你有關 JDBC 轉義語法的額外信息。
正如一個 Connection 對象創(chuàng)建了 Statement 和 PreparedStatement 對象,它也創(chuàng)造了在數(shù)據(jù)庫中被執(zhí)行調用的 CallableStatement 對象。
假設,你需要執(zhí)行下面的 Oracle 存儲過程-
CREATE OR REPLACE PROCEDURE getEmpName
(EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
SELECT first INTO EMP_FIRST
FROM Employees
WHERE ID = EMP_ID;
END;
注意:上面的存儲過程是在 Oracle 使用的,但我們使用的是 MySQL 數(shù)據(jù)庫,所以我們在 MySQL 的環(huán)境下需要重新寫出相同功能的代碼,下面的代碼是在 EMP 數(shù)據(jù)庫中創(chuàng)建相同功能的代碼-
DELIMITER $$
DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName`
(IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
SELECT first INTO EMP_FIRST
FROM Employees
WHERE ID = EMP_ID;
END $$
DELIMITER ;
當前有三種類型的參數(shù):IN,OUT 和 INOUT。PreparedStatement 對象只能使用 IN 參數(shù)。CallableStatement 對象可以使用所有的三種類型。
下面是三種類型參數(shù)的定義-
參數(shù) | 描述 |
---|---|
IN | 當 SQL 語句創(chuàng)建的時候,該參數(shù)的值是未知的。你可以用 setXXX() 方法將值綁定到 IN 參數(shù)里。 |
OUT | 該參數(shù)的值是由 SQL 語句的返回值。你可以用 getXXX() 方法從 OUT 參數(shù)中檢索值。 |
INOUT | 該參數(shù)同時提供輸入和輸出值。你可以用 setXXX() 方法將值綁定到 IN 參數(shù)里,并且也可以用 getXXX() 方法從 OUT 參數(shù)中檢索值。 |
下面的代碼片段展示了如何使用 Connection.prepareCall() 方法實現(xiàn)一個基于上述存儲過程的 CallableStatement 對象-
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
字符串變量 SQL 使用參數(shù)占位符來表示存儲過程。
使用 CallableStatement 對象就像使用 PreparedStatement 對象。在執(zhí)行該語句前,你必須將值綁定到所有的參數(shù),否則你將收到一個 SQL 異常。
如果你有 IN 參數(shù),只要按照適用于 PreparedStatement 對象相同的規(guī)則和技巧;用 setXXX()方法來綁定對應的 Java 數(shù)據(jù)類型。
當你使用 OUT 和 INOUT 參數(shù)就必須采用額外的 CallableStatement 方法:registerOutParameter()。registerOutParameter() 方法將 JDBC 數(shù)據(jù)類型綁定到存儲過程返回的數(shù)據(jù)類型。
一旦你調用了存儲過程,你可以用適當?shù)?getXXX()方法從 OUT 參數(shù)參數(shù)中檢索數(shù)值。這種方法將檢索出來的 SQL 類型的值映射到 Java 數(shù)據(jù)類型。
正如你關閉其它的 Statement 對象,出于同樣的原因,你也應該關閉 CallableStatement 對象。
close()方法簡單的調用就可以完成這項工作。如果你先關閉了 Connection 對象,那么它也會關閉 CallableStatement 對象。然而,你應該始終明確關閉 CallableStatement 對象,以確保該對象被徹底關閉。
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
cstmt.close();
}
轉義語法使能夠讓你通過使用標準的 JDBC 方法和屬性,來靈活的使用數(shù)據(jù)庫的某些特定功能,而該特定功能對你來說本來是不可用的。
常用的 SQL 轉義語法格式如下所示-
{keyword 'parameters'}
當你在編程的時候,你會發(fā)現(xiàn)以下的這些轉義序列會非常有用的-
它們能幫助確定日期,時間和時間戳的文字。眾所周知,沒有兩個數(shù)據(jù)庫管理系統(tǒng)的時間和日期的表現(xiàn)方式是相同的。該轉義語法告訴驅動程序以目標數(shù)據(jù)庫的格式來呈現(xiàn)日期或時間。例如-
{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' 表示時間戳的組合語法。
該關鍵字在 LIKE 子句中使用,來定義轉義字符。當使用 SQL 通配符%,來匹配零個或多個字符時,該關鍵字就非常有用。例如-
String sql = "SELECT symbol FROM MathSymbols
WHERE symbol LIKE '\%' {escape '\'}";
stmt.execute(sql);
如果你使用反斜杠字符(\)作為轉義字符,你必須在 Java 字符串里使用兩個反斜杠字符,因為反斜杠也是一個 Java 轉義字符。
該關鍵字代表在數(shù)據(jù)庫管理系統(tǒng)中使用標量函數(shù)。例如,你可以使用 SQL 的 length 函數(shù)來計算字符串的長度-
{fn length('Hello World')}
這將返回11,也就是字符串'Hello World'的長度。
該關鍵字是用來調用存儲過程的。例如,對于一個需要一個 IN 參數(shù)的存儲過程,使用以下語法-
{call my_procedure(?)};
對于需要一個 IN 參數(shù)并返回一個 OUT 參數(shù)的存儲過程,使用下面的語法-
{? = call my_procedure(?)};
該關鍵字用來表示外部連接,其語法如下所示-
{oj outer-join}
其中 outer - join = 表 { LEFT | RIGHT | FULL } OUTER JOIN {表| outer - join }的搜索條件。例如-
String sql = "SELECT Employees
FROM {oj ThisTable RIGHT
OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);
更多建議: