⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdbctm 指南:入门7 - callablestatement.htm

📁 写给JSP初级程序员的书
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0057)http://eps.www85.cn4e.com/java/article/devshow.asp?id=101 -->
<HTML><HEAD><title>csdn_JDBCTM 指南:入门7 - CallableStatement</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<STYLE type=text/css>TD {
	FONT-FAMILY: "Verdana", "Arial", "宋体"; FONT-SIZE: 9pt
}
A {
	COLOR: #660000; TEXT-DECORATION: underline
}
A:hover {
	COLOR: #660000; TEXT-DECORATION: none
}
.line {
	LINE-HEIGHT: 14pt
}
</STYLE>

<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff text=#000000>

  <table><tbody>
  <TR>
    <TD height=21>
      <DIV align=center><B><FONT size=3>JDBCTM 指南:入门7 - 
      CallableStatement <BR><FONT size=2> </FONT></FONT></FONT>
      <HR align=center color=#cccccc noShade SIZE=1>
      </DIV></TD></TR>
  <TR>
    <TD class=line><FONT 
      color=#333300>7&nbsp;-&nbsp;CallableStatement<BR>本概述是从《JDBCTM&nbsp;Database&nbsp;Access&nbsp;from&nbsp;JavaTM:&nbsp;A&nbsp;Tutorial&nbsp;and&nbsp;Annotated&nbsp;Reference&nbsp;》这本书中摘引来的。JavaSoft&nbsp;目前正在准备这本书。这本书是一本教程,同时也是&nbsp;JDBC&nbsp;的重要参考手册,它将作为&nbsp;Java&nbsp;系列的组成部份在&nbsp;1997&nbsp;年春季由&nbsp;Addison-Wesley&nbsp;出版公司出版。&nbsp;<BR><BR><BR>7.1&nbsp;概述<BR>CallableStatement&nbsp;对象为所有的&nbsp;DBMS&nbsp;提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是&nbsp;CallableStatement&nbsp;对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参数,另一种形式不带结果参数(有关换码语法的信息,参见第&nbsp;4&nbsp;节“语句”)。结果参数是一种输出&nbsp;(OUT)&nbsp;参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN&nbsp;参数)、输出(OUT&nbsp;参数)或输入和输出(INOUT&nbsp;参数)的参数。问号将用作参数的占位符。<BR><BR>在&nbsp;JDBC&nbsp;中调用已储存过程的语法如下所示。注意,方括号表示其间的内容是可选项;方括号本身并不是语法的组成部份。<BR><BR>{call&nbsp;过程名[(?,&nbsp;?,&nbsp;...)]}<BR><BR>返回结果参数的过程的语法为:&nbsp;<BR><BR>{?&nbsp;=&nbsp;call&nbsp;过程名[(?,&nbsp;?,&nbsp;...)]}<BR><BR>不带参数的已储存过程的语法类似:&nbsp;<BR><BR>{call&nbsp;过程名}<BR><BR>通常,创建&nbsp;CallableStatement&nbsp;对象的人应当知道所用的&nbsp;DBMS&nbsp;是支持已储存过程的,并且知道这些过程都是些什么。然而,如果需要检查,多种&nbsp;DatabaseMetaData&nbsp;方法都可以提供这样的信息。例如,如果&nbsp;DBMS&nbsp;支持已储存过程的调用,则&nbsp;supportsStoredProcedures&nbsp;方法将返回&nbsp;true,而&nbsp;getProcedures&nbsp;方法将返回对已储存过程的描述。<BR><BR>CallableStatement&nbsp;继承&nbsp;Statement&nbsp;的方法(它们用于处理一般的&nbsp;SQL&nbsp;语句),还继承了&nbsp;PreparedStatement&nbsp;的方法(它们用于处理&nbsp;IN&nbsp;参数)。CallableStatement&nbsp;中定义的所有方法都用于处理&nbsp;OUT&nbsp;参数或&nbsp;INOUT&nbsp;参数的输出部分:注册&nbsp;OUT&nbsp;参数的&nbsp;JDBC&nbsp;类型(一般&nbsp;SQL&nbsp;类型)、从这些参数中检索结果,或者检查所返回的值是否为&nbsp;JDBC&nbsp;NULL。<BR><BR><BR>7.1.1&nbsp;创建&nbsp;CallableStatement&nbsp;对象<BR>CallableStatement&nbsp;对象是用&nbsp;Connection&nbsp;方法&nbsp;prepareCall&nbsp;创建的。下例创建&nbsp;CallableStatement&nbsp;的实例,其中含有对已储存过程&nbsp;getTestData&nbsp;调用。该过程有两个变量,但不含结果参数:&nbsp;<BR><BR>CallableStatement&nbsp;cstmt&nbsp;=&nbsp;con.prepareCall(<BR>"{call&nbsp;getTestData(?,&nbsp;?)}");<BR><BR>其中&nbsp;?&nbsp;占位符为&nbsp;IN、&nbsp;OUT&nbsp;还是&nbsp;INOUT&nbsp;参数,取决于已储存过程&nbsp;getTestData。<BR><BR><BR>7.1.2&nbsp;IN&nbsp;和&nbsp;OUT&nbsp;参数<BR>将&nbsp;IN&nbsp;参数传给&nbsp;CallableStatement&nbsp;对象是通过&nbsp;setXXX&nbsp;方法完成的。该方法继承自&nbsp;PreparedStatement。所传入参数的类型决定了所用的&nbsp;setXXX&nbsp;方法(例如,用&nbsp;setFloat&nbsp;来传入&nbsp;float&nbsp;值等)。<BR><BR>如果已储存过程返回&nbsp;OUT&nbsp;参数,则在执行&nbsp;CallableStatement&nbsp;对象以前必须先注册每个&nbsp;OUT&nbsp;参数的&nbsp;JDBC&nbsp;类型(这是必需的,因为某些&nbsp;DBMS&nbsp;要求&nbsp;JDBC&nbsp;类型)。注册&nbsp;JDBC&nbsp;类型是用&nbsp;registerOutParameter&nbsp;方法来完成的。语句执行完后,CallableStatement&nbsp;的&nbsp;getXXX&nbsp;方法将取回参数值。正确的&nbsp;getXXX&nbsp;方法是为各参数所注册的&nbsp;JDBC&nbsp;类型所对应的&nbsp;Java&nbsp;类型(从&nbsp;JDBC&nbsp;类型到&nbsp;Java&nbsp;类型的标准映射见&nbsp;8.6.1&nbsp;节中的表)。换言之,&nbsp;registerOutParameter&nbsp;使用的是&nbsp;JDBC&nbsp;类型(因此它与数据库返回的&nbsp;JDBC&nbsp;类型匹配),而&nbsp;getXXX&nbsp;将之转换为&nbsp;Java&nbsp;类型。<BR><BR>作为示例,下述代码先注册&nbsp;OUT&nbsp;参数,执行由&nbsp;cstmt&nbsp;所调用的已储存过程,然后检索在&nbsp;OUT&nbsp;参数中返回的值。方法&nbsp;getByte&nbsp;从第一个&nbsp;OUT&nbsp;参数中取出一个&nbsp;Java&nbsp;字节,而&nbsp;getBigDecimal&nbsp;从第二个&nbsp;OUT&nbsp;参数中取出一个&nbsp;BigDecimal&nbsp;对象(小数点后面带三位数):&nbsp;<BR><BR>CallableStatement&nbsp;cstmt&nbsp;=&nbsp;con.prepareCall(<BR>"{call&nbsp;getTestData(?,&nbsp;?)}");<BR>cstmt.registerOutParameter(1,&nbsp;java.sql.Types.TINYINT);<BR>cstmt.registerOutParameter(2,&nbsp;java.sql.Types.DECIMAL,&nbsp;3);<BR>cstmt.executeQuery();<BR>byte&nbsp;x&nbsp;=&nbsp;cstmt.getByte(1);<BR>java.math.BigDecimal&nbsp;n&nbsp;=&nbsp;cstmt.getBigDecimal(2,&nbsp;3);<BR><BR>CallableStatement&nbsp;与&nbsp;ResultSet&nbsp;不同,它不提供用增量方式检索大&nbsp;OUT&nbsp;值的特殊机制。<BR><BR><BR>7.1.3&nbsp;INOUT&nbsp;参数<BR>既支持输入又接受输出的参数(INOUT&nbsp;参数)除了调用&nbsp;registerOutParameter&nbsp;方法外,还要求调用适当的&nbsp;setXXX&nbsp;方法(该方法是从&nbsp;PreparedStatement&nbsp;继承来的)。setXXX&nbsp;方法将参数值设置为输入参数,而&nbsp;registerOutParameter&nbsp;方法将它的&nbsp;JDBC&nbsp;类型注册为输出参数。setXXX&nbsp;方法提供一个&nbsp;Java&nbsp;值,而驱动程序先把这个值转换为&nbsp;JDBC&nbsp;值,然后将它送到数据库中。<BR><BR>这种&nbsp;IN&nbsp;值的&nbsp;JDBC&nbsp;类型和提供给&nbsp;registerOutParameter&nbsp;方法的&nbsp;JDBC&nbsp;类型应该相同。然后,要检索输出值,就要用对应的&nbsp;getXXX&nbsp;方法。例如,Java&nbsp;类型为&nbsp;byte&nbsp;的参数应该使用方法&nbsp;setByte&nbsp;来赋输入值。应该给&nbsp;registerOutParameter&nbsp;提供类型为&nbsp;TINYINT&nbsp;的&nbsp;JDBC&nbsp;类型,同时应使用&nbsp;getByte&nbsp;来检索输出值&nbsp;(第&nbsp;8&nbsp;节“JDBC&nbsp;和&nbsp;Java&nbsp;类型之间的映射”将给出详细信息和类型映射表)。<BR><BR>下例假设有一个已储存过程&nbsp;reviseTotal,其唯一参数是&nbsp;INOUT&nbsp;参数。方法&nbsp;setByte&nbsp;把此参数设为&nbsp;25,驱动程序将把它作为&nbsp;JDBC&nbsp;TINYINT&nbsp;类型送到数据库中。接着,registerOutParameter&nbsp;将该参数注册为&nbsp;JDBC&nbsp;TINYINT。执行完该已储存过程后,将返回一个新的&nbsp;JDBC&nbsp;TINYINT&nbsp;值。方法&nbsp;getByte&nbsp;将把这个新值作为&nbsp;Java&nbsp;byte&nbsp;类型检索。<BR><BR>CallableStatement&nbsp;cstmt&nbsp;=&nbsp;con.prepareCall(<BR>"{call&nbsp;reviseTotal(?)}");<BR>cstmt.setByte(1,&nbsp;25);<BR>cstmt.registerOutParameter(1,&nbsp;java.sql.Types.TINYINT);<BR>cstmt.executeUpdate();<BR>byte&nbsp;x&nbsp;=&nbsp;cstmt.getByte(1);<BR><BR>7.1.4&nbsp;先检索结果,再检索&nbsp;OUT&nbsp;参数<BR>由于某些&nbsp;DBMS&nbsp;的限制,为了实现最大的可移植性,建议先检索由执行&nbsp;CallableStatement&nbsp;对象所产生的结果,然后再用&nbsp;CallableStatement.getXXX&nbsp;方法来检索&nbsp;OUT&nbsp;参数。<BR><BR>如果&nbsp;CallableStatement&nbsp;对象返回多个&nbsp;ResultSet&nbsp;对象(通过调用&nbsp;execute&nbsp;方法),在检索&nbsp;OUT&nbsp;参数前应先检索所有的结果。这种情况下,为确保对所有的结果都进行了访问,必须对&nbsp;Statement&nbsp;方法&nbsp;getResultSet、getUpdateCount&nbsp;和&nbsp;getMoreResults&nbsp;进行调用,直到不再有结果为止。<BR><BR>检索完所有的结果后,就可用&nbsp;CallableStatement.getXXX&nbsp;方法来检索&nbsp;OUT&nbsp;参数中的值。<BR><BR><BR>7.1.5&nbsp;检索作为&nbsp;OUT&nbsp;参数的&nbsp;NULL&nbsp;值<BR>返回到&nbsp;OUT&nbsp;参数中的值可能会是&nbsp;JDBC&nbsp;NULL。当出现这种情形时,将对&nbsp;JDBC&nbsp;NULL&nbsp;值进行转换以使&nbsp;getXXX&nbsp;方法所返回的值为&nbsp;null、0&nbsp;或&nbsp;false,这取决于&nbsp;getXXX&nbsp;方法类型。对于&nbsp;ResultSet&nbsp;对象,要知道&nbsp;0&nbsp;或&nbsp;false&nbsp;是否源于&nbsp;JDBC&nbsp;NULL&nbsp;的唯一方法,是用方法&nbsp;wasNull&nbsp;进行检测。如果&nbsp;getXXX&nbsp;方法读取的最后一个值是&nbsp;JDBC&nbsp;NULL,则该方法返回&nbsp;true,否则返回&nbsp;flase。第&nbsp;5&nbsp;节“ResultSet”将给出详细信息。<BR>&nbsp;<BR>&nbsp;<BR><BR><BR>--------------------------------------------------------------------------------<BR></FONT></TD></TR>
  <TR>
    <TD height=5>
      <HR align=center color=#cccccc noShade SIZE=1>
    </TD></TR></TBODY></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -