JDBC存儲過程調(diào)用
在討論JDBC Statement教程文章時分别,我們已經(jīng)學(xué)習(xí)了如何在JDBC中使用存儲過程。 本教程文章與該部分類似存淫,但它將講解演示有關(guān)JDBC SQL轉(zhuǎn)義語法的其他信息茎杂。
就像Connection
對象創(chuàng)建Statement
和PreparedStatement
對象一樣,它可使用同樣的方式創(chuàng)建CallableStatement
對象纫雁,該對象將用于執(zhí)行對數(shù)據(jù)庫存儲過程的調(diào)用煌往。
創(chuàng)建CallableStatement對象
假設(shè)需要執(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;
SQL
注意:上面的存儲過程是為Oracle編寫的,但是如果使用MySQL數(shù)據(jù)庫轧邪,參考以下代碼為MySQL編寫相同的存儲過程刽脖,如下在
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 ;
SQL
存在三種類型的參數(shù):IN
,OUT
和INOUT
忌愚。 PreparedStatement
對象只使用IN
參數(shù)曲管。 CallableStatement
對象可以使用上面三種類型參數(shù)。
以下是上面三種類型參數(shù)的定義 -
參數(shù) | 描述 |
---|---|
IN | 創(chuàng)建SQL語句時其參數(shù)值是未知的硕糊。 使用setXXX() 方法將值綁定到IN 參數(shù)院水。 |
OUT | 由SQL語句返回的參數(shù)值〖蚴可以使用getXXX() 方法從OUT參數(shù)中檢索值檬某。 |
INOUT | 提供輸入和輸出值的參數(shù)。使用setXXX() 方法綁定變量并使用getXXX() 方法檢索值螟蝙。 |
以下代碼片段顯示了如何使用Connection.prepareCall()
方法根據(jù)上述存儲過程來實例化一個CallableStatement
對象 -
CallableStatement cstmt = null;
try {
String str = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
. . .
}
Java
String變量str
表示存儲過程恢恼,帶有參數(shù)占位符。
使用CallableStatement
對象與使用PreparedStatement
對象很像胰默。 在執(zhí)行語句之前场斑,必須將值綁定到所有參數(shù)漓踢,否則將收到一個SQLException
異常。
如果有IN
參數(shù)漏隐,只需遵循適用于PreparedStatement
對象的相同規(guī)則和技術(shù); 使用與綁定的Java數(shù)據(jù)類型相對應(yīng)的setXXX()
方法喧半。
使用OUT
和INOUT
參數(shù)時,必須使用一個額外的CallableStatement
對象方法registerOutParameter()
青责。 registerOutParameter()
方法將JDBC數(shù)據(jù)類型綁定到存儲過程預(yù)期返回的數(shù)據(jù)類型挺据。
當(dāng)調(diào)用存儲過程后,可以使用適當(dāng)?shù)?code>getXXX()方法從OUT
參數(shù)中檢索該值爽柒。 此方法將檢索到的SQL類型的值轉(zhuǎn)換為Java數(shù)據(jù)類型吴菠。
關(guān)閉CallableStatement對象
就像關(guān)閉其他Statement對象一樣者填,由于同樣的原因(節(jié)省資源)浩村,還應(yīng)該關(guān)閉CallableStatement
對象。
簡單的調(diào)用close()
方法將執(zhí)行關(guān)閉工作占哟。 如果先關(guān)閉Connection
對象心墅,它也會關(guān)閉CallableStatement
對象。 但是榨乎,應(yīng)該始終顯式關(guān)閉CallableStatement
對象怎燥,以確保正確的順序清理。
CallableStatement cstmt = null;
try {
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
. . .
}
catch (SQLException e) {
. . .
}
finally {
cstmt.close();
}
Java
有關(guān)更多的細節(jié)蜜暑,建議學(xué)習(xí)研究“Callable實例代碼”
JDBC SQL轉(zhuǎn)義語法
通過使用標(biāo)準(zhǔn)JDBC方法和屬性铐姚,轉(zhuǎn)義語法使您能夠靈活地使用不可用的數(shù)據(jù)庫特定功能。
一般SQL轉(zhuǎn)義語法格式如下 -
{keyword 'parameters'}
以下是以下轉(zhuǎn)義序列肛捍,在執(zhí)行JDBC編程時非常有用 -
d, t, ts關(guān)鍵字
它們用于幫助確定日期隐绵,時間和時間戳文字。沒有哪兩個DBMS表示時間和日期的方式相同拙毫。 該轉(zhuǎn)義語法告訴驅(qū)動程序以目標(biāo)數(shù)據(jù)庫的格式呈現(xiàn)日期或時間依许。 例如 -
{d 'yyyy-mm-dd'}
yyyy
=年份,mm
=月份; dd
=日期缀蹄。 使用這種語法{d'2019-09-03'}
表示的是2019年3月9日峭跳。
這是一個簡單的示例,顯示如何將日期插入表中 -
//Create a Statement object
stmt = conn.createStatement();
//Insert data ==> ID, First Name, Last Name, DOB
String sql="INSERT INTO STUDENTS VALUES" +
"(100,'Kobe','Bryant', {d '2002-12-16'})";
stmt.executeUpdate(sql);
Java
同樣缺前,還可以使用以下兩種語法:t
或ts
-
{t 'hh:mm:ss'}
這里蛀醉,hh
=小時,mm
=分鐘衅码, ss
=秒滞欠。 使用這種語法{t '13:30:29'}
是1:30:29 PM
。
{ts 'yyyy-mm-dd hh:mm:ss'}
這里“d
”和“t
”是上述兩種語法的組合語法來表示時間戳肆良。
escape關(guān)鍵字
escape
關(guān)鍵字標(biāo)識LIKE
子句中使用轉(zhuǎn)義字符筛璧。 使用SQL通配符%
(與0
個或多個字符匹配)時很有用逸绎。 例如 -
String sql = "SELECT symbol FROM MathSymbols
WHERE symbol LIKE '\%' {escape '\'}";
stmt.execute(sql);
Java
如果使用反斜杠字符(\
)作為轉(zhuǎn)義字符,則還必須在Java字符串文字中使用兩個反斜杠字符夭谤,因為反斜杠也是Java轉(zhuǎn)義字符棺牧。
fn 關(guān)鍵字
這個關(guān)鍵字表示DBMS中使用的標(biāo)量函數(shù)。 例如朗儒,可以使用SQL函數(shù)長度來獲取字符串的長度 -
{fn length('Hello World')}
Java
上面語句返回結(jié)果值為:11
颊乘,也就是字符串’Hello World
‘的長度。
call 關(guān)鍵字
此關(guān)鍵字用于調(diào)用存儲過程醉锄。 例如乏悄,對于需要IN
參數(shù)的存儲過程,請使用以下語法 -
{call my_procedure(?)};
Java
對于需要IN
參數(shù)并返回OUT
參數(shù)的存儲過程恳不,請使用以下語法 -
{? = call my_procedure(?)};
Java
oj關(guān)鍵字
此關(guān)鍵字用于表示外部連接檩小。 語法如下 -
{oj outer-join}
Java
這里,outer-join = table {LEFT|RIGHT|FULL} OUTERJOIN {table | outer-join} 搜索條件烟勋。 例如 -
String sql = "SELECT Employees
FROM {oj ThisTable RIGHT
OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);