使用Prepared Statements设置表名

Bra*_*don 27 java sql prepared-statement

我正在尝试使用预准备语句来设置表名以从中选择数据,但是在执行查询时我一直收到错误.

错误和示例代码显示如下.

[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();
Run Code Online (Sandbox Code Playgroud)

关于可能导致这种情况的任何想法?

cam*_*ckr 32

表名不能用作参数.它必须是硬编码的.所以你可以这样做:

private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [" + reportDate + "?]";
Run Code Online (Sandbox Code Playgroud)

  • 不要使用`org.apache.commons.lang.StringEscapeUtils.escapeSql`.它在commons.lang3中已弃用,并且无论如何只用双引号替换单引号.它不会阻止SQL注入.请参阅https://commons.apache.org/proper/commons-lang/article3_0.html和http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang /StringEscapeUtils.html#escapeSql%28java.lang.String%29. (8认同)
  • 别!由于SQL注入,这是一个棘手的问题. (7认同)
  • 在表名上使用`org.apache.commons.lang.StringEscapeUtils.escapeSql`以确保您没有将架构置于风险之中. (7认同)
  • 不言而喻,如果你打算这样做,那么tablename必须列入白名单(你应该使用白名单中的值而不是输入值,只是为了确定; regexes等) (5认同)
  • @everyone建议表名的字符串连接:不要这样做.这让位于SQL注入 - OWASP排名前10的头号攻击(见https://www.owasp.org/index.php/Top_10_2013-Top_10) (4认同)