当前位置: 首页 > 面试题库 >

Java中的参数化Oracle SQL查询?

姜烨伟
2023-03-14
问题内容

我一直在试图弄清楚为什么以下代码未在我的ResultSet中生成任何数据:

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),而“滑铁卢”只有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


 类似资料:
  • 问题内容: 我很难使用MySQLdb模块将信息插入到我的数据库中。我需要在表中插入6个变量。 有人可以帮我这里的语法吗? 问题答案: 提防对SQL查询使用字符串插值,因为它不能正确地转义输入参数,并使您的应用程序容易受到SQL注入漏洞的影响。 这种差异看似微不足道,但实际上它是巨大的 。 不正确(存在安全问题) 正确(带有转义符) 这增加了混乱,即用于绑定SQL语句中的参数的修饰符在不同的DB A

  • 问题内容: 我有一个查询,我试图填充我要参数化的CFChart: 这是我尝试过的: 当我将查询更改为此时,它将以某种方式破坏CFChart。屏幕上没有出现任何CFError,但是我的CFChart为空白。 我在查询中将其范围缩小到与此相关: 当我删除查询的此参数化部分并放入 有用。 谁能对此有所启发? 问题答案: 屏幕上没有出现任何CFError,但是我的CFChart为空白。 暂时忽略正确的方法

  • 问题内容: 关闭。 此问题不符合堆栈溢出准则。它当前不接受答案。 想改善这个问题吗? 更新问题,使其成为Stack Overflow 的主题。 6年前关闭。 谁能给我示例如何在MySQL / PHP中使用参数化查询的例子? 问题答案: 参数化查询本质上是抽象出所有输入的查询。这具有几个良好的副作用,例如使所有输入无害(即不可能进行有害注入),并且由于它是预先分析和编译的,因此在重复使用时使其更快,

  • 问题内容: 我已经使用了参数化查询次数,我知道它有助于防止SQL注入。但是,我想知道我是否可以知道在参数化查询中防止SQL注入的基本逻辑是什么,原因很简单,但我不知道。我试图搜索google的基本知识,但是每次我找到一个示例,说明如何在Asp.net中使用参数化查询。 我知道制作一个特殊类来停止SQL注入中使用的特殊字符,例如(’,-etc),但是仅停止特殊字符会完全阻止SQL注入吗? .net参

  • 问题内容: 我很难使用MySQLdb模块将信息插入到数据库中。我需要在表中插入6个变量。 有人可以帮我这里的语法吗? 问题答案: 提防对SQL查询使用字符串插值,因为它不能正确地转义输入参数,并使您的应用程序容易受到SQL注入漏洞的影响。这种差异看似微不足道,但实际上它是巨大的。 不正确(存在安全问题) 正确(带有转义符) 这增加了混淆,用于绑定SQL语句中的参数的修饰符在不同的DB API实现之

  • 在Java中,如何对url上的查询参数进行编码?我知道,这似乎是一个显而易见的问题。 有两个微妙之处我不确定: URL上的空格应该编码为"或"吗?在chrome中,如果我输入“http://google.com/foo=?bar我”chrome将其更改为编码 是否有必要/正确地将冒号":"编码为;?Chrome没有。 注意事项: 似乎不起作用,它似乎是用于编码要提交表单的数据。例如,它将空格编码为