JDBC基础教程之CallableStatement
摘要
CallableStatement对象为所有DBMS提供了调用存储过程的标准方式。存储过程存储在数据库中。对存储过程的调用是CallableStatement对象中包含的内容。这种调用是用代码转义语法编写的,有两种形式:一种有结果参数,另一种没有结果参数。结果是一个OUT参数,它是存储过程的返回值。两种形式都可以有可变数量的输入参数(in参数)、输出参数(out参数)或输入输出参数(INOUT参数)。问号将用作参数的占位符。
在JDBC中调用存储过程的语法如下。注意,方括号表示中间的内容是可选的;方括号本身不是语法的一部分。
{调用过程名[(?, ?,...)]}
返回结果参数的过程的语法是:
{?=调用过程名[(?, ?,...)]}
不带参数的存储过程的语法类似:
{调用过程名称}
通常,创建CallableStatement对象的人应该知道所使用的DBMS支持存储过程,并且知道这些过程是什么。但是,如果需要检查,各种DatabaseMetaData方法可以提供这样的信息。例如,如果DBMS支持存储过程的调用,supportsStoredProcedures方法将返回true,而getProcedures方法将返回存储过程的描述。CallableStatement继承了Statement的方法(用于处理一般的SQL语句)和PreparedStatement的方法(用于处理in参数)。
CallableStatement中定义的所有方法都用于处理OUT参数或INOUT参数的输出部分:注册OUT参数的JDBC类型(通用SQL类型),从这些参数中检索结果,或者检查返回值是否为JDBC NULL。
1.创建可调用语句对象。
CallableStatement对象是使用连接方法prepareCall创建的。以下示例创建CallableStatement的一个实例,该实例包含对存储过程getTestData的调用。该过程有两个变量,但没有结果参数:
callable statement cs TMT = con . prepare call(" { call gettest data(?, ?)}");
其中?占位符是IN、OUT或INOUT参数,具体取决于存储过程getTestData。
2.输入和输出参数
将in参数传递给CallableStatement对象是由setXXX方法完成的。该方法继承自PreparedStatement。传入的参数类型决定了使用的setXXX方法(例如,使用setFloat传入浮点值等。).
如果存储过程返回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对象(小数点后有三位数字):
callable statement cs TMT = con . prepare call(" { call gettest data(?, ?)}");
cstmt . registeroutparameter(1,Java . SQL . types . tinyint);
cstmt . registeroutparameter(2,Java.sql.Types.DECIMAL,3);
cs TMT . execute query();
byte x = cstmt . get byte(1);
Java . math . bigdecimal n = cstmt . getbigdecimal(2,3);
与ResultSet不同,Callable语句不提供增量检索大值的特殊机制。
3。INOUT参数
除了registerOutParameter方法之外,同时支持输入和输出的参数(INOUT参数)还调用适当的setXXX方法(从PreparedStatement继承而来)。setXXX方法将参数值设置为输入参数,而registerOutParameter方法将其JDBC类型注册为输出参数。SetXXX方法提供了一个Java值,驱动程序先把这个值转换成JDBC值,然后发送给数据库。此IN值的JDBC类型应与提供给registerOutParameter方法的JDBC类型相同。然后,要检索输出值,请使用相应的getXXX方法。例如,具有Java类型byte的参数应该使用setByte方法来分配输入值。RegisterOutParameter应提供JDBC类型的TINYINT,getByte应用于检索输出值。
以下示例有一个存储过程reviseTotal,其参数是INOUT参数。SetByte方法将此参数设置为25,驱动程序会将其作为JDBC TINYINT类型发送到数据库。然后,registerOutParameter将此参数注册为JDBC TINYINT。存储过程执行后,将返回一个新的JDBC TINYINT值。getByte方法将以Java字节类型检索这个新值。
callable statement cstmt = con . prepare call(" { call revise total(?)}");
cstmt.setByte(1,25);
cstmt . registeroutparameter(1,Java . SQL . types . tinyint);
cs TMT . execute update();
byte x = cstmt . get byte(1);
4.首先检索结果,然后检索OUT参数。
由于部分DBMS的限制,为了实现的可移植性,建议先检索执行CallableStatement对象生成的结果,再用CallableStatement.getXXX方法检索OUT参数。如果CallableStatement对象返回多个ResultSet对象(通过调用execute方法),则应该在检索OUT参数之前检索所有结果。在这种情况下,为了确保访问所有结果,必须调用语句方法getResultSet、getUpdateCount和getMoreResults,直到不再有结果。
检索所有结果后,可以使用CallableStatement.getXXX方法检索OUT参数中的值。
5.检索空值作为输出参数
返回给OUT参数的值可能是JDBC空值。当这种情况发生时,JDBC空值将被转换,以便getXXX方法返回的值为NULL、0或false,这取决于getXXX方法的类型。对于ResultSet对象,知道0或false是否源自JDBCNULL的方法是使用wasNull方法来检测它。如果getXXX方法读取的最后一个值是JDBC NULL,则返回true,否则返回flase。
0条评论