JDBC - 存储过程

我们在讨论 JDBC  - 语句时学习了如何在JDBC中使用存储过程章节.本章与该部分类似,但它将为您提供有关JDBC SQL转义语法的其他信息.

正如Connection对象创建Statement和PreparedStatement对象一样,它也会创建CallableStatement对象,它将用于执行对数据库存储过程的调用.

创建CallableStatement对象

假设,您需要执行以下Oracle存储procedure :

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数据库,所以,让我们写相同的存储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 {
   . . .
}

字符串变量SQL表示存储过程,带有参数占位符.

使用CallableStatement对象就像使用PreparedStatement对象一样.您必须在执行语句之前将值绑定到所有参数,否则您将收到SQLException.

如果您有IN参数,请遵循适用于PreparedStatement对象的相同规则和技术;使用与您绑定的Java数据类型相对应的setXXX()方法.

使用OUT和INOUT参数时,必须使用额外的CallableStatement方法registerOutParameter(). registerOutParameter()方法将JDBC数据类型绑定到存储过程应返回的数据类型.

一旦调用存储过程,就从OUT参数中检索值.适当的getXXX()方法.此方法将检索到的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();
}


JDBC SQL转义语法

转义语法使您可以灵活地使用不可用的数据库特定功能通过使用标准JDBC方法和属性来使用.

一般SQL转义语法格式如下 :

 
 {关键字'参数'}

以下是转义序列,您在执行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);