ResultSet.getNext() 不适用于 PreparedStatement

Posted

技术标签:

【中文标题】ResultSet.getNext() 不适用于 PreparedStatement【英文标题】:ResultSet.getNext() not working with PreparedStatement 【发布时间】:2013-01-02 20:23:28 【问题描述】:

我试图弄清楚为什么 ResultSet.next() 在我编写的 Java 代码中永远不会为真,因为我执行了一个 SQL 查询,该查询将 Oracle 11g 表中的结果返回到该 ResultSet 中......看起来好像在 java.sql.Connection 中使用 PreparedStatement 时,代码无法正确获取返回的 ResultSet 的内容。任何帮助表示赞赏,以下是详细信息:

表:

  CREATE TABLE "SHANDB"."ABSCLOBS" 
   (    "ID" NUMBER, 
    "XMLVAL" "XMLTYPE", 
    "IDSTRING" VARCHAR2(20 BYTE)
   )

数据:

INSERT INTO absclobs VALUES ( 1, 
   xmltype('<?xml version="1.0"?>
               <EMP>
                  <EMPNO>221</EMPNO>
                  <ENAME>John</ENAME>
               </EMP>', '1'));

INSERT INTO absclobs VALUES (2, 
   xmltype('<?xml version="1.0"?>
               <PO>
                  <PONO>331</PONO>
                  <PONAME>PO_1</PONAME>
               </PO>', '2'));

我正在运行 Java 代码以从上面获取值来测试代码:

  public static void main(String[] args) throws Exception 
    try 
      String url = "jdbc:oracle:thin:@//localhost:1521/xe";
      String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
      String user = "shandb";
      String password = "test";
      Class.forName(driver);
      connection = DriverManager.getConnection(url,user, password);
      String selectID1 = "SELECT a.xmlval.getClobval() AS poXML FROM absclobs a where idstring=? and id=? ";      
      PreparedStatement preparedStatement = connection.prepareStatement(selectID1);

      preparedStatement.setString(1, "1"); 
      preparedStatement.setInt(2, 1); 

      rowsUpdated = preparedStatement.executeQuery(); 
      while(rowsUpdated.next())
          String clobxml = rowsUpdated.getString(1);
          System.out.println(clobxml);
      
     catch (ClassNotFoundException cnfe) 
      System.err.println(cnfe);
     catch (SQLException sqle) 
      System.err.println(sqle);
    
    finally
        System.out.println("Rows affected: " + rowsUpdated);
        connection.close();     
    

  

上面这部分代码从来没有运行过,看不懂:

  while(rowsUpdated.next())
      String clobxml = rowsUpdated.getString(1);
      System.out.println(clobxml);
  

...但是最后的打印语句显示 ResultSet 不为空:

Rows affected: oracle.jdbc.driver.OracleResultSetImpl@15f157b

有谁知道为什么我不能显示实际检索到的 XML clob 内容,和/或为什么上面的 while 块永远不会正确?

谢谢:)

【问题讨论】:

该行如何告诉您 ResultSet 不为空?即使是一个空的 ResultSet 也是一个驻留在内存地址的对象,它只是没有任何行。它与null 不同。 us2012 是对的。那么您是尝试另一个查询还是直接测试您的查询?它有任何行吗? 这个问题太复杂了......也许你应该首先删除所有不相关的细节(条件等)并检查是否按预期工作。这将帮助我们所有人更快地解决问题。 对不起...我的意思是该语句返回一个值,但上面运行的代码没有,我不明白: SELECT a.xmlval.getClobval() AS poXML FROM absclob a where idstring='1' and id=1; @fuzzyanalysis:那么您为什么要介绍关于“最终打印声明”的任何内容?您是否尝试过不使用 WHERE 子句?为什么您的 INSERT 语句不包含 IDSTRING 值? 【参考方案1】:

您的诊断不正确 - 这是:

Rows affected: oracle.jdbc.driver.OracleResultSetImpl@15f157b

不显示结果集是非空的。它只是表明rowsUpdated 的值是对oracle.jdbc.driver.OracleResultSetImpl 实例的引用,它不会覆盖toString()。这很容易为空。

我怀疑问题只是您的WHERE 子句与任何记录都不匹配。为了诊断起见,我建议您将其更改为:

String selectID1 = "SELECT a.xmlval.getClobval() AS poXML FROM absclobs a";

(当然,摆脱参数设置调用)。这样,您应该能够看到 all 表的值。然后,您可以努力找出您的 WHERE 子句未按预期工作的原因。

(顺便说一句,不清楚为什么您没有在问题的代码中声明connectionrowsUpdated。它们绝对应该是局部变量...)

【讨论】:

见鬼,只需针对您的数据库运行您的预期调用,SELECT a.xmlval.getClobval() AS poXML FROM absclobs a where idstring='1' and id=1,看看您是否得到任何回报。此外,如果您只是引用通过列索引(在本例中为 1)返回的列,则不需要查询的 AS poXML 部分。 没错,我不需要 AS 部分。我之前没有将 IDSTRING 值放入 INSERT 语句中,从而弄乱了这个问题,现在我已经修复了。问题仍然存在,SQL 正确运行以返回一行,但 ResultSet.next() 永远不会为真。 最后这是一个奇怪的解决方案......每当我删除对我在 Eclipse“表达式”选项卡中检查的 ResultSet 的任何引用时,上面的工作都很好。将涉及 ResultSet 的表达式添加到选项卡中,一切都会失败。真的很奇怪。 @fuzzyanalysis:嗯。如果toString() 可能用尽了ResultSet,那将是有道理的——但不是这样。奇怪的。哦,好吧 - 至少它现在已经修复了......

以上是关于ResultSet.getNext() 不适用于 PreparedStatement的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UITableViewAutomaticDimension 不适用于 sectionFooterHeight?

为啥排序不适用于矢量?

验证不适用于 saveMany

UipanGesture 不适用于 Uiswitch

jQuery 不适用于 Express

为啥 MultiBinding 不适用于 CornerRadius