当前位置: 首页 > 文档资料 > JDBC API 中文教程 >

存储过程(Stored Procedure)

优质
小牛编辑
133浏览
2023-12-01

在讨论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);

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

{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);