PreparedStatement.setString()方法没有引号

时间:2010-05-26 23:12:14

标签: java sql jdbc prepared-statement

我正在尝试使用类似于此的代码的PreparedStatement:

SELECT * FROM ? WHERE name = ?

显然,当我使用setString()设置表和名称字段时会发生什么:

SELECT * FROM 'my_table' WHERE name = 'whatever'

并且查询不起作用。有没有办法设置没有引号的字符串,所以行看起来像这样:

SELECT * FROM my_table WHERE name = 'whatever'

或者我应该放弃它并使用常规语句(参数来自系统的另一部分,这些都不是由用户输入的)?

4 个答案:

答案 0 :(得分:17)

参数不能用于参数化表,也不能参数化任何数据库对象。它们主要用于参数化WHERE / HAVING子句。

要做你想做的事,你需要自己做替换,并根据需要创建一个常规语句。

当您使用预准备语句时,这是数据库在语句上进行前处理的提示 - 例如解析字符串并可能确定执行计划。如果查询中使用的对象可以动态更改,那么数据库就无法做好太多准备工作。

答案 1 :(得分:3)

很遗憾,您无法为预准备语句参数化表名。如果需要,您可以构造一个String并将其作为动态SQL执行。

答案 2 :(得分:3)

我怀疑你的SQL是如此无限灵活。您只有有限数量的表,因此表达所需SQL的静态最终字符串的数量也是有限的。

继续使用PreparedStatement并绑定变量。这完全是值得的,在避免SQL注入问题时尤其有用。

答案 3 :(得分:3)

您所犯的错误是无法将表名作为参数传递。您应该只将值传递给SQL语句。

例: 如果你想要:

Select * from LoggedUsers where username='whatever' and privilege='whatever';

然后你要将PreparedStatement构建为:

Select * from LoggedUsers where username=? and privilege=?

setString(1, usernameObject);
setString(2, privilegeObject);

PreparedStatement的目的是降低数据库连接代码的难度和可读性。当开发人员必须在Statement实例中使​​用如此多的列值时,很难使用分号,逗号和加号(concat运营商)。

我认为你错误地想要利用它,而不是设计......