4

继我之前的一个与方法设计有关的问题之后,我被建议将我的 SQL 查询实现为参数化查询,而不是简单的字符串。

我以前从未使用过参数化查询,所以我决定从简单的东西开始,采用以下Select语句:

String select = "SELECT * FROM ? ";

PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "person");

这给了我以下错误:“[SQLITE_ERROR] SQL 错误或缺少数据库(靠近“?”:语法错误)”

然后我尝试了一个修改后的版本,它有额外的标准;

String select = "SELECT id FROM person WHERE name = ? ";

PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "Yui");

这个版本工作得很好,在我的第一个例子中,我错过了参数化查询的要点还是我错误地构造了它们?

谢谢!

4

3 回答 3

9

简单来说,SQL绑定不能绑定表,只能绑定where子句值。这有一些与“编译”准备好的 SQL 语句相关的技术原因。通常,参数化查询旨在通过防止 SQL 注入来使 SQL 更安全,并且它还有一个好处是使查询更加“模块化”,但不能动态设置表名(因为假设您已经知道该表将是什么)。

于 2011-03-30T19:18:50.627 回答
2

如果你想要 PERSON 表中的所有行,你应该这样做:

String select = "SELECT * FROM person";

PreparedStatement ps = connection.prepareStatement(select);

变量绑定不像上面提到的那样动态绑定表名。如果您将表名作为变量传入您的方法,则可以按如下方式构造整个查询:

String select = "SELECT * FROM " + varTableName;
PreparedStatement ps = connection.prepareStatement(select);

参数化查询用于查询字段名称 - 而不是表名称!

于 2011-03-30T19:35:18.550 回答
1

Prepared statements仍然是SQL,需要用适当的where子句构造;即其中x = y。它们的一个优点是它们在第一次被看到时由 RDMS 解析,而不是每次发送它们时都会解析它们,这加速了具有不同绑定值的相同查询的后续执行。

于 2011-03-30T19:21:47.933 回答