PreparedStatement执行查询无结果求助(Oracle数据库)
看起来你在从Statement迁移到PreparedStatement时遇到了查询无结果的问题,而且没有抛出异常,这通常是数据匹配或者配置层面的问题,我给你列几个常见的排查方向:
1. 先确认数据库中确实存在这条数据
首先在Oracle客户端(比如SQL Developer、PL/SQL Developer)里手动执行这条查询:
select is_enabled, syllabus_id from ic_syllabus where syllabus_id='25AC1CFB7C1A2CF07F176BD3A296F229';
如果这条SQL也返回空,那问题不在PreparedStatement,而是数据库里确实没有这条数据;如果客户端能查到结果,再往下排查。
2. 检查字符串大小写匹配问题
Oracle默认对字符串是大小写敏感的(除非你给列设置了UPPER()函数索引或者修改了会话的大小写参数)。比如数据库里的syllabus_id是小写的25ac1cfb7c1a2cf07f176bd3a296f229,而你传的是大写值,就会匹配失败。可以试试把参数转成和数据库一致的大小写,或者修改查询语句:
select is_enabled, syllabus_id from ic_syllabus where UPPER(syllabus_id)=UPPER(?);
3. 排查数据类型不匹配的情况
如果syllabus_id字段的类型是CHAR而不是VARCHAR2,Oracle会自动在存储的字符串末尾补空格来填满列的长度。比如列定义是CHAR(40),而你的实际值是32位,数据库里存储的是25AC1CFB7C1A2CF07F176BD3A296F229 (后面带8个空格),这时候你传不带空格的参数就匹配不上。可以试试用TRIM()处理字段:
select is_enabled, syllabus_id from ic_syllabus where TRIM(syllabus_id)=?;
或者直接检查字段的类型定义,确认是否和你的参数类型匹配。
4. 确认连接的数据库和Schema是否正确
有时候代码里的数据库连接可能指向了测试环境或者其他Schema,导致你查询的表不是你预期的那张。可以检查连接URL里的数据库名称、Schema是否正确,或者在查询语句里加上Schema前缀:
select is_enabled, syllabus_id from YOUR_SCHEMA.ic_syllabus where syllabus_id=?;
5. 调试PreparedStatement的实际执行情况
你可以先临时用Statement执行相同的查询,看看能不能拿到结果:
String selectQuery = "select is_enabled, syllabus_id from ic_syllabus where syllabus_id='25AC1CFB7C1A2CF07F176BD3A296F229'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(selectQuery); // 遍历结果看是否有数据
如果Statement能查到结果,那问题可能出在PreparedStatement的参数绑定上,可以试试用setObject代替setString:
pstmt.setObject(1, "25AC1CFB7C1A2CF07F176BD3A296F229");
6. 检查事务隔离级别和未提交的数据
如果这条数据是刚插入的,但还没提交事务,而你的PreparedStatement所在的连接处于较高的隔离级别(比如可重复读),可能看不到未提交的数据。可以在客户端执行COMMIT之后再试代码里的查询,或者检查代码里的事务提交逻辑。
内容的提问来源于stack exchange,提问作者Vijay Natesan

