使用准备好的语句设置表名称
我正在尝试使用准备好的语句来设置表名以从中选择数据,但在执行查询时不断收到错误。
错误和示例代码如下所示。
[Microsoft][ODBC Microsoft Access Driver] Parameter 'Pa_RaM000' specified where a table name is required.
private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [?]"; //?=date
public Execute(String reportDate){
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(Display.DB_MERC);
PreparedStatement st = conn.prepareStatement(query1);
st.setString(1, reportDate);
ResultSet rs = st.executeQuery();
有什么想法可能导致这种情况吗?
I'm trying to use prepared statements to set a table name to select data from, but I keep getting an error when I execute the query.
The error and sample code is displayed below.
[Microsoft][ODBC Microsoft Access Driver] Parameter 'Pa_RaM000' specified where a table name is required.
private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [?]"; //?=date
public Execute(String reportDate){
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(Display.DB_MERC);
PreparedStatement st = conn.prepareStatement(query1);
st.setString(1, reportDate);
ResultSet rs = st.executeQuery();
Any thoughts on what might be causing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我不确定您是否可以使用PreparedStatement 来指定表的名称,仅指定某些字段的值。 无论如何,您可以尝试相同的查询,但不带括号:
I'm not sure you can use a PreparedStatement to specify the name of the table, just the value of some fields. Anyway, you could try the same query but, without the brackets:
这可能有帮助:
This might help:
正如许多人所说,不能将语句参数用于表名,只能将变量用作条件的一部分。
基于您有一个带有(至少)两个表名的变量表名的事实,也许最好创建一个方法来获取您正在存储的实体并返回准备好的语句。
As a number of people have said, you can't use a statement parameter for a table name, only for variables as part of the condition.
Based on the fact you have a variable table name with (at least) two table names, perhaps it would be best to create a method which takes the entity you are storing and returns a prepared statement.
这在技术上可以通过解决方法实现,但是非常糟糕的做法。
然后,当您想从first_table中选择时,您可以设置参数,
或者如果没有,则将其设置为其他值。
This is technically possible with a workaround, but very bad practice.
And then when you want to select from first_table you set the parameter with
Or if not, you set it to something else.
您无法在准备好的语句中设置表名称
如前所述,不可能在准备好的语句中使用
设置表名称。 而且也不可能将部分 SQL 查询添加到准备好的语句中(例如preparedStatement.setString(1, tableName)
)。preparedStatement.addSql(" or xyz is null")
如何正确地做到这一点而不冒 SQL 注入的风险?
表名必须插入到要使用字符串操作执行的 SQL(或 JQL)查询中,例如
"select * from " + tableName
或String.format("select * from %s ", tableName)
但是如何避免SQL注入呢?
如果表名称不是来自用户输入,那么您可能安全。
例如,如果您做出如下决定,
如果表名称取决于用户输入,则您需要手动检查输入。
例如,使用包含所有有效表名称的白名单:
或使用枚举:
然后转换用户输入字符串,例如
ANIMAL
进入Table.ANIMAL
。 如果不存在合适的枚举值,则会引发异常。例如,
当然,这些示例也可以与选择、更新等一起使用,并且可以使用许多其他实现来检查用户输入。
You can't set table name in prepared statement
As said before, it is not possible to set the table name in a prepared statement with
. And it is also not possible to add parts of the SQL query to a prepared statement (egpreparedStatement.setString(1, tableName)
).preparedStatement.addSql(" or xyz is null")
How to do it right without risking SQL injections?
The table name must be inserted into the SQL (or JQL) query you want to execute with string operations like
"select * from " + tableName
orString.format("select * from %s", tableName)
But how to avoid SQL injections?
If the table name does not come from user input, you are probably safe.
For example, if you make a decision like here
If the table name depends on the users input, you need to check the input manually.
For example, with a white-list containing all valid table names:
or with an enum:
and then convert the user-input string like
ANIMAL
intoTable.ANIMAL
. An exception is thrown, if no fitting enumeration value does exist.eg
Of course these examples work with select, update, ... too and a lot of other implementations to check the user input are possible.
表名不能用作参数。 它必须是硬编码的。 所以你可以这样做:
A table name can't be used as a parameter. It must be hard coded. So you can do something like: