11赞
530
当前位置:  开发笔记 > 数据库 > 正文

JDBCTM指南:入门7-CallableStatement

JDBCTM指南:入门7-CallableStatement
7 - CallableStatement
本概述是从《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》这本书中摘引来的。JavaSoft 目前正在准备这本书。这本书是一本教程,同时也是 JDBC 的重要参考手册,它将作为 Java 系列的组成部份在 1997 年春季由 Addison-Wesley 出版公司出版。

>>
7.1 概述
CallableStatement 对象为所有的 DBMS 提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是 CallableStatement 对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参数,另一种形式不带结果参数(有关换码语法的信息,参见第 4 节“语句”)。结果参数是一种输出 (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。

>

7.1.1 创建 CallableStatement 对象
CallableStatement 对象是用 Connection 方法 prepareCall 创建的。下例创建 CallableStatement 的实例,其中含有对已储存过程 getTestData 调用。该过程有两个变量,但不含结果参数:




CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}")
;

其中 ? 占位符为 IN、 OUT 还是 INOUT 参数,取决于已储存过程 getTestData。>
>

7.1.2 IN 和 OUT 参数
将 IN 参数传给 CallableStatement 对象是通过 setXXX 方法完成的。该方法继承自 PreparedStatement。所传入参数的类型决定了所用的 setXXX 方法(例如,用 setFloat 来传入 float 值等)




如果已储存过程返回 OUT 参数,则在执行 CallableStatement 对象以前必须先注册每个 OUT 参数的 JDBC 类型(这是必需的,因为某些 DBMS 要求 JDBC 类型)。注册 JDBC 类型是用 registerOutParameter 方法来完成的。语句执行完后,CallableStatement 的 getXXX 方法将取回参数值。正确的 getXXX 方法是为各参数所注册的 JDBC 类型所对应的 Java 类型(从 JDBC 类型到 Java 类型的标准映射见 8.6.1 节中的表)。换言之, 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 值的特殊机制。>

>

7.1.3 INOUT 参数
既支持输入又接受输出的参数(INOUT 参数)除了调用 registerOutParameter 方法外,还要求调用适当的 setXXX 方法(该方法是从 PreparedStatement 继承来的)。setXXX 方法将参数值设置为输入参数,而 registerOutParameter 方法将它的 JDBC 类型注册为输出参数。setXXX 方法提供一个 Java 值,而驱动程序先把这个值转换为 JDBC 值,然后将它送到数据库中。
>
这种 IN 值的 JDBC 类型和提供给 registerOutParameter 方法的 JDBC 类型应该相同。然后,要检索输出值,就要用对应的 getXXX 方法。例如,Java 类型为 byte 的参数应该使用方法 setByte 来赋输入值。应该给 registerOutParameter 提供类型为 TINYINT 的 JDBC 类型,同时应使用 getByte 来检索输出值 (第 8 节“JDBC 和 Java 类型之间的映射”将给出详细信息和类型映射表)。
>
下例假设有一个已储存过程 reviseTotal,其唯一参数是 INOUT 参数。方法 setByte 把此参数设为 25,驱动程序将把它作为 JDBC TINYINT 类型送到数据库中。接着,registerOutParameter 将该参数注册为 JDBC TINYINT。执行完该已储存过程后,将返回一个新的 JDBC TINYINT 值。方法 getByte 将把这个新值作为 Java byte 类型检索。
>
CallableStatement cstmt = con.prepareCall(
"{call reviseTotal(?)}")
;
cstmt.setByte(1, 25);
cstmt.registerOutParameter(1, java.sql.Types.TINYINT)

;
cstmt.executeUpdate();
byte x = cstmt.getByte(1)
>
;

7.1.4 先检索结果,再检索 OUT 参数
由于某些 DBMS 的限制,为了实现最大的可移植性,建议先检索由执行 CallableStatement 对象所产生的结果,然后再用 CallableStatement.getXXX 方法来检索 OUT 参数
>


如果 CallableStatement 对象返回多个 ResultSet 对象(通过调用 execute 方法),在检索 OUT 参数前应先检索所有的结果。这种情况下,为确保对所有的结果都进行了访问,必须对 Statement 方法 getResultSet、getUpdateCount 和 getMoreResults 进行调用,直到不再有结果为止。
>
检索完所有的结果后,就可用 CallableStatement.getXXX 方法来检索 OUT 参数中的值。>
>

7.1.5 检索作为 OUT 参数的 NULL 值
返回到 OUT 参数中的值可能会是 JDBC NULL。当出现这种情形时,将对 JDBC NULL 值进行转换以使 getXXX 方法所返回的值为 null、0 或 false,这取决于 getXXX 方法类型。对于 ResultSet 对象,要知道 0 或 false 是否源于 JDBC NULL 的唯一方法,是用方法 wasNull 进行检测。如果 getXXX 方法读取的最后一个值是 JDBC NULL,则该方法返回 true,否则返回 flase。第 5 节“ResultSet”将给出详细信息










推荐阅读
  • Javaweb学习路线:1、Java基础;2、javaAPI输入输出,多线程,网络编程,反射注解等;3、数据库SQL基础;4、JDBC编程;5、HTML语言学习;6、JavaScript脚本语言;7、Servlet开发;8、JSP开发。 ... [详细]
  • java数据库中文乱码解决方法:在数据库配置的url后加useUnicodetrue&characterEncodingUTF-8参数即可解决数据库乱码。 ... [详细]
  • 本文来自java入门程序,文中为大家详细介绍了高内聚低耦合的概念,希望能帮助大家更好地理解这个概念。高内聚低耦合是判断软件设计好坏的标准,主要用于程序的面向对象的设计。 ... [详细]
  • java调用mysql数据的方法:首先定义一个过程,获取users表总记录数,将10设置到变量count中;然后修改mysql语句的结果符;接着将结果覆给变量a;最后显示变量a的值。 ... [详细]
  • java中mysql查询语句:1、简单查询;2、简单查询;3、排序查询;4、分组查询,代码为【groupby被分组的字段.[Having条件]】;5、分页查询,代码为【select*from表名limitx;】。 ... [详细]
  • 在数据库物理设计阶段,为数据表创建索引的目的是:提高查询的检索能力、提高查询效率。索引是对数据表中一个或多个列的值进行排序的一种结构,建立索引可以极大地提高在数据库中获取所需信息的速度,同时还能提高服务器处理相关搜索请求的效率。 ... [详细]
  • IT资讯,揭秘:微信是如何用libco支撑8亿用户的,UDN开发者论坛,专注企业互联网开发的IT技术社区 ... [详细]
  • 微信公众平台开发--快递查询 ... [详细]
  • 以下是我自己编写的一个代码,功能是在微信公众号开发过程中实现倒计时的。效果如下,订单已提交,请在2分57秒内完成支付。纯代码解析。 ... [详细]
  • 本篇文章主要给大家介绍PHP对url中的汉字进行编码及解码的具体实现方法。有的新手朋友们对于url编码解码这个概念,或许有点陌生。但是如果这么说,当我们在浏览各大网页时,可能发现有的url里有一些特殊符号比如#号,&号,_号或者汉字等等,那么为了符合url的规范,存在这些符号的url就需要对其进行编码。这样简单的说明大家是否对url编码解码有一点了解了呢?url编码解码,也可以叫做百分号编码,是统一资源定位(URL)编码方式。 ... [详细]
devbox
qapo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有 京ICP备19059560号-4