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
子句未按预期工作的原因。
(顺便说一句,不清楚为什么您没有在问题的代码中声明connection
或rowsUpdated
。它们绝对应该是局部变量...)
【讨论】:
见鬼,只需针对您的数据库运行您的预期调用,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的主要内容,如果未能解决你的问题,请参考以下文章