首页 / 软件开发 / JAVA / JDBC基础教程之CallableStatement
JDBC基础教程之CallableStatement2010-12-02概述CallableStatement 对象为所有的 DBMS 提供了一种以标准形式调用已储存 过程的方法。已储存过程储存在数据库中。对已储存过程的调用是 CallableStatement对象所含的内容。这种调用是用一种换码语法来写的,有两 种形式:一种形式带结果参,另一种形式不带结果参数。结果参数是一种输出 (OUT) 参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN 参数)、输出(OUT 参数)或输入和输出(INOUT 参数)的参数。问号将用作参 数的占位符。在 JDBC 中调用已储存过程的语法如下所示。注意,方括号表示其间的内容 是可选项;方括号本身并不是语法的组成部份。{call 过程名[(?, ?, ...)]}返回结果参数的过程的语法为:{? = call 过程名[(?, ?, ...)]}不带参数的已储存过程的语法类似:{call 过程名}通常,创建 CallableStatement 对象的人应当知道所用的 DBMS 是支持已储 存过程的,并且知道这些过程都是些什么。然而,如果需要检查,多种 DatabaseMetaData 方法都可以提供这样的信息。例如,如果 DBMS 支持已储存 过程的调用,则supportsStoredProcedures 方法将返回 true,而 getProcedures 方法将返回对已储存过程的描述。CallableStatement 继承 Statement 的方法(它们用于处理一般的 SQL 语句),还继承了 PreparedStatement 的方法(它们用于处理 IN 参)。CallableStatement 中定义的所有方法都用于处理 OUT 参数或 INOUT 参数 的输出部分:注册 OUT 参数的 JDBC 类型(一般 SQL 类型)、从这些参数中检 索结果,或者检查所返回的值是否为 JDBC NULL。1、创建 CallableStatement 对象CallableStatement 对象是用 Connection 方法 prepareCall 创建的。下例 创建 CallableStatement 的实例,其中含有对已储存过程 getTestData 调用。 该过程有两个变量,但不含结果参数:CallableStatement cstmt = con.prepareCall("{call getTestData(?, ?)}");其中?占位符为IN、OUT还是INOUT参数,取决于已储存过程getTestData。2、IN和OUT参数将IN参数传给 CallableStatement 对象是通过 setXXX 方法完成的。该方法 继承自 PreparedStatement。所传入参数的类型决定了所用的setXXX方法(例如 ,用 setFloat 来传入 float 值等)。如果已储存过程返回 OUT 参数,则在执行 CallableStatement 对象以前必 须先注册每个 OUT 参数的 JDBC 类型(这是必需的,因为某些 DBMS 要求 JDBC 类型)。注册 JDBC 类型是用 registerOutParameter 方法来完成的。语句执行 完后,CallableStatement 的 getXXX 方法将取回参数值。正确的 getXXX 方法 是为各参数所注册的 JDBC 类型所对应的 Java 类型。换言之, registerOutParameter 使用的是 JDBC 类型(因此它与数据库返回的 JDBC 类 型匹配),而 getXXX 将之转换为 Java 类型。作为示例,下述代码先注册 OUT 参数,执行由 cstmt 所调用的已储存过程 ,然后检索在 OUT 参数中返回的值。方法 getByte 从第一个 OUT 参数中取出 一个 Java 字节,而 getBigDecimal 从第二个 OUT 参数中取出一个 BigDecimal 对象(小数点后面带三位数):CallableStatement cstmt = con.prepareCall("{call getTestData(?, ?)}");
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3);
cstmt.executeQuery();
byte x = cstmt.getByte(1);
java.math.BigDecimal n = cstmt.getBigDecimal(2, 3);
CallableStatement 与 ResultSet 不同,它不提供用增量方式检索大 OUT 值的特殊机制。