JDBC - 存储过程


我们在讨论JDBC - 语句一章时学习了如何在 JDBC 中使用存储过程。本章与该部分类似,但它将为您提供有关 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;

注意- 上面的存储过程是为 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 对象可以使用所有这三个。

以下是每个的定义 -

范围 描述
创建 SQL 语句时其值未知的参数。您可以使用 setXXX() 方法将值绑定到 IN 参数。
出去 其值由它返回的 SQL 语句提供的参数。您可以使用 getXXX() 方法从 OUT 参数中检索值。
进出 提供输入值和输出值的参数。您可以使用 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();
}

研究我们在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);

同样,您可以使用以下两种语法之一,tts -

{t 'hh:mm:ss'}

其中 hh = 小时;毫米=分钟;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 outer-join}

其中外连接=表{LEFT|RIGHT|FULL} OUTERJOIN {表| 搜索条件上的外连接}。例如 -

String sql = "SELECT Employees 
              FROM {oj ThisTable RIGHT
              OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);