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

📄 jdbctm 指南:入门4 - statement.htm

📁 写给JSP初级程序员的书
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<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 指南:入门4 - Statement 
      <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>4&nbsp;-&nbsp;Statement<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>4.1&nbsp;概述<BR>Statement&nbsp;对象用于将&nbsp;SQL&nbsp;语句发送到数据库中。实际上有三种&nbsp;Statement&nbsp;对象,它们都作为在给定连接上执行&nbsp;SQL&nbsp;语句的包容器:Statement、PreparedStatement(它从&nbsp;Statement&nbsp;继承而来)和&nbsp;CallableStatement(它从&nbsp;PreparedStatement&nbsp;继承而来)。它们都专用于发送特定类型的&nbsp;SQL&nbsp;语句:&nbsp;Statement&nbsp;对象用于执行不带参数的简单&nbsp;SQL&nbsp;语句;PreparedStatement&nbsp;对象用于执行带或不带&nbsp;IN&nbsp;参数的预编译&nbsp;SQL&nbsp;语句;CallableStatement&nbsp;对象用于执行对数据库已存储过程的调用。<BR><BR>Statement&nbsp;接口提供了执行语句和获取结果的基本方法。PreparedStatement&nbsp;接口添加了处理&nbsp;IN&nbsp;参数的方法;而&nbsp;CallableStatement&nbsp;添加了处理&nbsp;OUT&nbsp;参数的方法。<BR><BR><BR>4.1.1&nbsp;创建&nbsp;Statement&nbsp;对象<BR>建立了到特定数据库的连接之后,就可用该连接发送&nbsp;SQL&nbsp;语句。Statement&nbsp;对象用&nbsp;Connection&nbsp;的方法&nbsp;createStatement&nbsp;创建,如下列代码段中所示:&nbsp;<BR><BR>Connection&nbsp;con&nbsp;=&nbsp;DriverManager.getConnection(url,&nbsp;"sunny",&nbsp;"");<BR>Statement&nbsp;stmt&nbsp;=&nbsp;con.createStatement();<BR><BR>为了执行&nbsp;Statement&nbsp;对象,被发送到数据库的&nbsp;SQL&nbsp;语句将被作为参数提供给&nbsp;Statement&nbsp;的方法:&nbsp;<BR><BR>ResultSet&nbsp;rs&nbsp;=&nbsp;stmt.executeQuery("SELECT&nbsp;a,&nbsp;b,&nbsp;c&nbsp;FROM&nbsp;Table2");<BR><BR>4.1.2&nbsp;使用&nbsp;Statement&nbsp;对象执行语句<BR>Statement&nbsp;接口提供了三种执行&nbsp;SQL&nbsp;语句的方法:executeQuery、executeUpdate&nbsp;和&nbsp;execute。使用哪一个方法由&nbsp;SQL&nbsp;语句所产生的内容决定。<BR><BR>方法&nbsp;executeQuery&nbsp;用于产生单个结果集的语句,例如&nbsp;SELECT&nbsp;语句。<BR><BR>方法&nbsp;executeUpdate&nbsp;用于执行&nbsp;INSERT、UPDATE&nbsp;或&nbsp;DELETE&nbsp;语句以及&nbsp;SQL&nbsp;DDL(数据定义语言)语句,例如&nbsp;CREATE&nbsp;TABLE&nbsp;和&nbsp;DROP&nbsp;TABLE。INSERT、UPDATE&nbsp;或&nbsp;DELETE&nbsp;语句的效果是修改表中零行或多行中的一列或多列。executeUpdate&nbsp;的返回值是一个整数,指示受影响的行数(即更新计数)。对于&nbsp;CREATE&nbsp;TABLE&nbsp;或&nbsp;DROP&nbsp;TABLE&nbsp;等不操作行的语句,executeUpdate&nbsp;的返回值总为零。<BR><BR>方法&nbsp;execute&nbsp;用于执行返回多个结果集、多个更新计数或二者组合的语句。因为多数程序员不会需要该高级功能,所以本概述后面将在单独一节中对其进行介绍。<BR><BR>执行语句的所有方法都将关闭所调用的&nbsp;Statement&nbsp;对象的当前打开结果集(如果存在)。这意味着在重新执行&nbsp;Statement&nbsp;对象之前,需要完成对当前&nbsp;ResultSet&nbsp;对象的处理。<BR><BR>应注意,继承了&nbsp;Statement&nbsp;接口中所有方法的&nbsp;PreparedStatement&nbsp;接口都有自己的&nbsp;executeQuery、executeUpdate&nbsp;和&nbsp;execute&nbsp;方法。Statement&nbsp;对象本身不包含&nbsp;SQL&nbsp;语句,因而必须给&nbsp;Statement.execute&nbsp;方法提供&nbsp;SQL&nbsp;语句作为参数。PreparedStatement&nbsp;对象并不将&nbsp;SQL&nbsp;语句作为参数提供给这些方法,因为它们已经包含预编译&nbsp;SQL&nbsp;语句。CallableStatement&nbsp;对象继承这些方法的&nbsp;PreparedStatement&nbsp;形式。对于这些方法的&nbsp;PreparedStatement&nbsp;或&nbsp;CallableStatement&nbsp;版本,使用查询参数将抛出&nbsp;SQLException。<BR><BR><BR>4.1.3&nbsp;语句完成<BR>当连接处于自动提交模式时,其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时,即认为已完成。对于返回一个结果集的&nbsp;executeQuery&nbsp;方法,在检索完&nbsp;ResultSet&nbsp;对象的所有行时该语句完成。对于方法&nbsp;executeUpdate,当它执行时语句即完成。但在少数调用方法&nbsp;execute&nbsp;的情况中,在检索所有结果集或它生成的更新计数之后语句才完成。<BR><BR>有些&nbsp;DBMS&nbsp;将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用&nbsp;commit&nbsp;方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。<BR><BR><BR>4.1.4&nbsp;关闭&nbsp;Statement&nbsp;对象<BR>Statement&nbsp;对象将由&nbsp;Java&nbsp;垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要&nbsp;Statement&nbsp;对象时显式地关闭它们。这将立即释放&nbsp;DBMS&nbsp;资源,有助于避免潜在的内存问题。<BR><BR><BR>4.1.5&nbsp;Statement&nbsp;对象中的&nbsp;SQL&nbsp;转义语法&nbsp;<BR>Statement&nbsp;可包含使用&nbsp;SQL&nbsp;转义语法的&nbsp;SQL&nbsp;语句。转义语法告诉驱动程序其中的代码应该以不同方式处理。驱动程序将扫描任何转义语法,并将它转换成特定数据库可理解的代码。这使得转义语法与&nbsp;DBMS&nbsp;无关,并允许程序员使用在没有转义语法时不可用的功能。<BR><BR>转义子句由花括号和关键字界定:&nbsp;<BR><BR>{keyword&nbsp;.&nbsp;.&nbsp;.&nbsp;parameters&nbsp;.&nbsp;.&nbsp;.&nbsp;}<BR><BR>该关键字指示转义子句的类型,如下所示。<BR><BR><BR>escape&nbsp;表示&nbsp;LIKE&nbsp;转义字符&nbsp;<BR><BR><BR>字符“%”和“_”类似于&nbsp;SQL&nbsp;LIKE&nbsp;子句中的通配符(“%”匹配零个或多个字符,而“_”则匹配一个字符)。为了正确解释它们,应在其前面加上反斜杠(“\”),它是字符串中的特殊转义字符。在查询末尾包括如下语法即可指定用作转义字符的字符:&nbsp;<BR><BR>{escape&nbsp;'escape-character'}<BR><BR><BR>例如,下列查询使用反斜杠字符作为转义字符,查找以下划线开头的标识符名:&nbsp;<BR><BR>stmt.executeQuery("SELECT&nbsp;name&nbsp;FROM&nbsp;Identifiers<BR>WHERE&nbsp;Id&nbsp;LIKE&nbsp;`\_%'&nbsp;{escape&nbsp;`\'};<BR><BR><BR>fn&nbsp;表示标量函数<BR><BR><BR>几乎所有&nbsp;DBMS&nbsp;都具有标量值的数值、字符串、时间、日期、系统和转换函数。要使用这些函数,可使用如下转义语法:关键字&nbsp;fn&nbsp;后跟所需的函数名及其参数。例如,下列代码调用函数&nbsp;concat&nbsp;将两个参数连接在一起:&nbsp;<BR><BR>{fn&nbsp;concat("Hot",&nbsp;"Java")};<BR><BR><BR>可用下列语法获得当前数据库用户名:&nbsp;<BR><BR>{fn&nbsp;user()};<BR><BR><BR>标量函数可能由语法稍有不同的&nbsp;DBMS&nbsp;支持,而它们可能不被所有驱动程序支持。各种&nbsp;DatabaseMetaData&nbsp;方法将列出所支持的函数。例如,方法&nbsp;getNumericFunctions&nbsp;返回用逗号分隔的数值函数列表,而方法&nbsp;getStringFunctions&nbsp;将返回字符串函数,等等。<BR><BR>驱动程序将转义函数调用映射为相应的语法,或直接实现该函数。<BR><BR><BR>d、t&nbsp;和&nbsp;ts&nbsp;表示日期和时间文字<BR><BR><BR>DBMS&nbsp;用于日期、时间和时间标记文字的语法各不相同。JDBC&nbsp;使用转义子句支持这些文字的语法的&nbsp;ISO&nbsp;标准格式。驱动程序必须将转义子句转换成&nbsp;DBMS&nbsp;表示。<BR><BR>例如,可用下列语法在&nbsp;JDBC&nbsp;SQL&nbsp;语句中指定日期:&nbsp;<BR><BR>{d&nbsp;`yyyy-mm-dd'}<BR><BR><BR>在该语法中,yyyy&nbsp;为年代,mm&nbsp;为月份,而&nbsp;dd&nbsp;则为日期。驱动程序将用等价的特定于&nbsp;DBMS&nbsp;的表示替换这个转义子句。例如,如果&nbsp;'28-&nbsp;FEB-99'&nbsp;符合基本数据库的格式,则驱动程序将用它替换&nbsp;{d&nbsp;1999-02-28}。<BR><BR>对于&nbsp;TIME&nbsp;和&nbsp;TIMESTAMP&nbsp;也有类似的转义子句:&nbsp;<BR><BR>{t&nbsp;`hh:mm:ss'}<BR>{ts&nbsp;`yyyy-mm-dd&nbsp;hh:mm:ss.f&nbsp;.&nbsp;.&nbsp;.'}<BR><BR><BR>TIMESTAMP&nbsp;中的小数点后的秒(.f&nbsp;.&nbsp;.&nbsp;.)部分可忽略。<BR><BR><BR>call&nbsp;或&nbsp;?&nbsp;=&nbsp;call&nbsp;表示已存储过程<BR><BR><BR><BR>如果数据库支持已存储过程,则可从&nbsp;JDBC&nbsp;中调用它们,语法为:&nbsp;<BR><BR>{call&nbsp;procedure_name[(?,&nbsp;?,&nbsp;.&nbsp;.&nbsp;.)]}<BR><BR><BR>或(其中过程返回结果参数):&nbsp;<BR><BR>{?&nbsp;=&nbsp;call&nbsp;procedure_name[(?,&nbsp;?,&nbsp;.&nbsp;.&nbsp;.)]}<BR><BR><BR>方括号指示其中的内容是可选的。它们不是语法的必要部分。<BR><BR>输入参数可以为文字或参数。有关详细信息,参见&nbsp;JDBC&nbsp;指南中第&nbsp;7&nbsp;节,“CallableStatement”。<BR><BR>可通过调用方法&nbsp;DatabaseMetaData.supportsStoredProcedures&nbsp;检查数据库是否支持已存储过程。<BR><BR><BR><BR>oj&nbsp;表示外部连接<BR><BR><BR><BR>外部连接的语法为&nbsp;<BR><BR>{oj&nbsp;outer-join}<BR><BR><BR>其中&nbsp;outer-join&nbsp;形式为&nbsp;<BR><BR>table&nbsp;LEFT&nbsp;OUTER&nbsp;JOIN&nbsp;{table&nbsp;/&nbsp;outer-join}&nbsp;ON&nbsp;search-condition<BR><BR><BR>外部连接属于高级功能。有关它们的解释可参见&nbsp;SQL&nbsp;语法。JDBC&nbsp;提供了三种&nbsp;DatabaseMetaData&nbsp;方法用于确定驱动程序支持哪些外部连接类型:supportsOuterJoins、supportsFullOuterJoins&nbsp;和&nbsp;supportsLimitedOuterJoins。<BR><BR><BR>方法&nbsp;Statement.setEscapeProcessing&nbsp;可打开或关闭转义处理;缺省状态为打开。当性能极为重要时,程序员可能想关闭它以减少处理时间。但通常它将出于打开状态。应注意:&nbsp;setEscapeProcessing&nbsp;不适用于&nbsp;PreparedStatement&nbsp;对象,因为在调用该语句前它就可能已被发送到数据库。有关预编译的信息,参见&nbsp;PreparedStatement。<BR><BR><BR>4.1.6&nbsp;使用方法&nbsp;execute<BR>execute&nbsp;方法应该仅在语句能返回多个&nbsp;ResultSet&nbsp;对象、多个更新计数或&nbsp;ResultSet&nbsp;对象与更新计数的组合时使用。当执行某个已存储过程或动态执行未知&nbsp;SQL&nbsp;字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。例如,用户可能执行一个已存储过程(使用&nbsp;CallableStatement&nbsp;对象&nbsp;-&nbsp;参见第&nbsp;135&nbsp;页的&nbsp;CallableStatement),并且该已存储过程可执行更新,然后执行选择,再进行更新,再进行选择,等等。通常使用已存储过程的人应知道它所返回的内容。<BR><BR>因为方法&nbsp;execute&nbsp;处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法&nbsp;execute&nbsp;执行该过程后,必须调用方法&nbsp;getResultSet&nbsp;获得第一个结果集,然后调用适当的&nbsp;getXXX&nbsp;方法获取其中的值。要获得第二个结果集,需要先调用&nbsp;getMoreResults&nbsp;方法,然后再调用&nbsp;getResultSet&nbsp;方法。如果已知某个过程返回两个更新计数,则首先调用方法&nbsp;getUpdateCount,然后调用&nbsp;getMoreResults,并再次调用&nbsp;getUpdateCount。<BR><BR>对于不知道返回内容,则情况更为复杂。如果结果是&nbsp;ResultSet&nbsp;对象,则方法&nbsp;execute&nbsp;返回&nbsp;true;如果结果是&nbsp;Java&nbsp;int,则返回&nbsp;false。如果返回&nbsp;int,则意味着结果是更新计数或执行的语句是&nbsp;DDL&nbsp;命令。在调用方法&nbsp;execute&nbsp;之后要做的第一件事情是调用&nbsp;getResultSet&nbsp;或&nbsp;getUpdateCount。调用方法&nbsp;getResultSet&nbsp;可以获得两个或多个&nbsp;ResultSet&nbsp;对象中第一个对象;或调用方法&nbsp;getUpdateCount&nbsp;可以获得两个或多个更新计数中第一个更新计数的内容。<BR><BR>当&nbsp;SQL&nbsp;语句的结果不是结果集时,则方法&nbsp;getResultSet&nbsp;将返回&nbsp;null。这可能意味着结果是一个更新计数或没有其它结果。在这种情况下,判断&nbsp;null&nbsp;真正含义的唯一方法是调用方法&nbsp;getUpdateCount,它将返回一个整数。这个整数为调用语句所影响的行数;如果为&nbsp;-1&nbsp;则表示结果是结果集或没有结果。如果方法&nbsp;getResultSet&nbsp;已返回&nbsp;null(表示结果不是&nbsp;ResultSet&nbsp;对象),则返回值&nbsp;-1&nbsp;表示没有其它结果。也就是说,当下列条件为真时表示没有结果(或没有其它结果):&nbsp;<BR><BR>((stmt.getResultSet()&nbsp;==&nbsp;null)&nbsp;&amp;&amp;&nbsp;(stmt.getUpdateCount()&nbsp;==&nbsp;-1))<BR><BR>如果已经调用方法&nbsp;getResultSet&nbsp;并处理了它返回的&nbsp;ResultSet&nbsp;对象,则有必要调用方法&nbsp;getMoreResults&nbsp;以确定是否有其它结果集或更新计数。如果&nbsp;getMoreResults&nbsp;返回&nbsp;true,则需要再次调用&nbsp;getResultSet&nbsp;来检索下一个结果集。如上所述,如果&nbsp;getResultSet&nbsp;返回&nbsp;null,则需要调用&nbsp;getUpdateCount&nbsp;来检查&nbsp;null&nbsp;是表示结果为更新计数还是表示没有其它结果。<BR><BR>当&nbsp;getMoreResults&nbsp;返回&nbsp;false&nbsp;时,它表示该&nbsp;SQL&nbsp;语句返回一个更新计数或没有其它结果。因此需要调用方法&nbsp;getUpdateCount&nbsp;来检查它是哪一种情况。在这种情况下,当下列条件为真时表示没有其它结果:&nbsp;<BR><BR>((stmt.getMoreResults()&nbsp;==&nbsp;false)&nbsp;&amp;&amp;&nbsp;(stmt.getUpdateCount()&nbsp;==&nbsp;-1))<BR><BR>下面的代码演示了一种方法用来确认已访问调用方法&nbsp;execute&nbsp;所产生的全部结果集和更新计数:&nbsp;<BR><BR><BR>stmt.execute(queryStringWithUnknownResults);<BR>while&nbsp;(true)&nbsp;{<BR>int&nbsp;rowCount&nbsp;=&nbsp;stmt.getUpdateCount();<BR>if&nbsp;(rowCount&nbsp;&gt;&nbsp;0)&nbsp;{&nbsp;//&nbsp;它是更新计数<BR>System.out.println("Rows&nbsp;changed&nbsp;=&nbsp;"&nbsp;+&nbsp;count);<BR>stmt.getMoreResults();<BR>continue;<BR>}<BR>if&nbsp;(rowCount&nbsp;==&nbsp;0)&nbsp;{&nbsp;//&nbsp;DDL&nbsp;命令或&nbsp;0&nbsp;个更新<BR>System.out.println("&nbsp;No&nbsp;rows&nbsp;changed&nbsp;or&nbsp;statement&nbsp;was&nbsp;DDL<BR>command");<BR>stmt.getMoreResults();<BR>continue;<BR>}<BR><BR>//&nbsp;执行到这里,证明有一个结果集<BR>//&nbsp;或没有其它结果<BR><BR>ResultSet&nbsp;rs&nbsp;=&nbsp;stmt.getResultSet;<BR>if&nbsp;(rs&nbsp;!=&nbsp;null)&nbsp;{<BR>.&nbsp;.&nbsp;.&nbsp;//&nbsp;使用元数据获得关于结果集列的信息<BR>while&nbsp;(rs.next())&nbsp;{<BR>.&nbsp;.&nbsp;.&nbsp;//&nbsp;处理结果<BR>stmt.getMoreResults();<BR>continue;<BR>}<BR>break;&nbsp;//&nbsp;没有其它结果<BR><BR><BR>&nbsp;<BR>&nbsp;<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 + -