存储过程(Stored Procedure)
在讨论JDBC-Statements章节时,我们已经学习了如何在JDBC中使用Stored Procedures 。 本章与该部分类似,但它将为您提供有关JDBC SQL转义语法的其他信息。
就像Connection对象创建Statement和PreparedStatement对象一样,它也会创建CallableStatement对象,该对象将用于执行对数据库存储过程的调用。
创建CallableStatement对象
假设您需要执行以下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;
NOTE:上面的存储过程是为Oracle编写的,但是我们正在使用MySQL数据库,所以,让我们为MySQL编写相同的存储过程,如下所示在EMP数据库中创建它 -
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 ;
存在三种类型的参数: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 {
. . .
}
String变量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();
}
我们已经在Callable - Example Code中研究了更多细节。
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'的上述两种语法的组合语法,用于表示时间戳。
逃脱关键字
此关键字标识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'的长度。
调用关键字
此关键字用于调用存储过程。 例如,对于需要IN参数的存储过程,请使用以下语法 -
{call my_procedure(?)};
对于需要IN参数并返回OUT参数的存储过程,请使用以下语法 -
{? = call my_procedure(?)};
oj关键字
此关键字用于表示外部联接。 语法如下 -
{oj outer-join}
where outer-join = table {LEFT | RIGHT | FULL} OUTERJOIN {table | search-condition上的outer-join}。 例如 -
String sql = "SELECT Employees
FROM {oj ThisTable RIGHT
OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);