我一直试图找出为什么以下代码没有在我的结果集中生成任何数据:

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo");
ResultSet rs = prepStmt.executeQuery();

另一方面,以下程序可以正常运行:

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = 'Waterloo' ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
ResultSet rs = prepStmt.executeQuery();

SCHOOL 的数据类型是 CHAR(9 字节)。除了 setString,我还尝试了:

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
String school = "Waterloo";
Reader reader = new CharArrayReader(school.toCharArray());
prepStmt.setCharacterStream(1, reader, 9);
prepStmt.setString(1, "Waterloo");
ResultSet rs = prepStmt.executeQuery();

我完全不知道接下来要调查什么;Eclipse 调试器表示,即使在 setString 或 setCharacterStream 之后,SQL 查询也不会更改。我不确定是否是因为设置参数不起作用,或者调试器根本无法获取PreparedStatement 中的更改。

任何帮助将不胜感激,谢谢!

有帮助吗?

解决方案

我认为问题在于您的数据类型是 CHAR(9) 而“Waterloo”只有 8 个字符。我假设这会返回预期的结果(LIKE 和 %)。或者添加缺少的空格。

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL LIKE ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo%");
ResultSet rs = prepStmt.executeQuery();

如果您的字符串具有灵活的长度,最好的方法是使用 varchar 而不是 char。然后PreparedStatement就会按预期工作。

解决方法是使用 Oracle 特定的 setFixedCHAR 方法(但如果可能,最好将数据类型更改为 varchar)。

以下内容来自Oracle的PreparedStatement JavaDoc:


数据库中的 CHAR 数据被填充到列宽。这导致使用 setCHAR() 方法将字符数据绑定到 SELECT 语句的 WHERE 子句时受到限制 — WHERE 子句中的字符数据还必须填充到列宽才能在 SELECT 语句中产生匹配。如果您不知道列宽,这尤其麻烦。

setFixedCHAR() 可以解决这个问题。此方法执行非填充比较。

笔记:

  • 请记住将准备好的语句对象转换为 OraclePreparedStatement 以使用 setFixedCHAR() 方法。
  • 无需对 INSERT 语句使用 setFixedCHAR()。数据库在插入数据时总是自动将数据填充到列宽。

以下示例演示了 setString()、setCHAR() 和 setFixedCHAR() 方法之间的区别。

// Schema is : create table my_table (col1 char(10));
//             insert into my_table values ('JDBC');
PreparedStatement pstmt = conn.prepareStatement
("select count() from my_table where col1 = ?");
ResultSet rs;

pstmt.setString (1, "JDBC");  // Set the Bind Value
rs = pstmt.executeQuery();    // This does not match any row
// ... do something with rs
CHAR ch = new CHAR("JDBC      ", null);
((OraclePreparedStatement)pstmt).setCHAR(1, ch); // Pad it to 10 bytes
rs = pstmt.executeQuery();     // This matches one row
// ... do something with rs
((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");
rs = pstmt.executeQuery();     // This matches one row
// ... do something with rs
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top