【问题标题】:PreparedStatement: Can I supply the column name as parameter?PreparedStatement:我可以提供列名作为参数吗?
【发布时间】:2009-10-03 22:09:07
【问题描述】:

假设我有一个包含 3 列的表:C1、C2、C3

我根据 C1 列进行搜索。 我可以做类似这样的事情吗(这不起作用 - 因为这不是使用它的 prepareStatement 方式:))

String c;// the name of the column

...    
String sql = "select * from table where ?  = ?";
                pre = con.prepareStatement(sql);
                pre.setString(1, c);
                pre.setString(1, i);
                rs = pre.executeQuery();

主要思想,我不希望每列都有 3 个 if。一个优雅的解决方案?

【问题讨论】:

  • 不应该是...... pre.setString(1, 'c1'); pre.setString(2, i);

标签: mysql jdbc


【解决方案1】:

这行不通。 prepare 语句解析 SQL,发送到数据库进行验证和编译。如果问号可以替代部分 SQL,那么您将失去绑定变量的全部意义——速度和安全性。您将重新引入 SQL 注入,并且必须为所有参数重新编译语句。

不会像SELECT * FROM table WHERE c1 = ? OR c2 = ? OR c3 = ? 这样更好(当然取决于索引和表大小)。

【讨论】:

    【解决方案2】:

    您可以编写一组 sql 查询并将它们存储在地图中,然后根据相关列抓取一个。

    enum column { a, b, c}
    
    Map<column, string> str;
    
    static {
     str.put(a, "select * from tbl where a = ? ");
     ...
    }
    

    然后稍后根据枚举从地图中抓取一个。 sql语句中的字符串追加在未来有可能成为安全问题。

    【讨论】:

      【解决方案3】:

      使用动态查询和java.sql.Statement

      String whereClause = c + " = " + i;
      
      // Form the dynamic Query
      StringBuffer query = new StringBuffer( "SELECT * FROM TABLE" ); 
      // Add WHERE clause if any
      query.append(" WHERE " + whereClause);
      
      // Create a SQL statement context to execute the Query
      Statement stmt = con.createStatement();
      
      // Execute the formed query and obtain the ResultSet
      ResultSet resultSet = stmt.executeQuery(query.toString());
      

      【讨论】:

      • 这个要小心,因为它会导致sql注入
      【解决方案4】:

      你不能这样做吗:

      String c;// the name of the column
      
      ...    
      String sql = "select * from table where " + c + "  = ?";
                      pre = con.prepareStatement(sql);
                      pre.setString(1, i);
                      rs = pre.executeQuery();
      

      ?

      如果不是,那么这可能是一个解决方案:

      String c;// the name of the column
      
      ...    
      String sql = "select * from table where ('C1' = ? AND C1 = ?) 
                                           OR ('C2' = ? AND C2 = ?) 
                                           OR ('C3' = ? AND C3 = ?)"
                      pre = con.prepareStatement(sql);
                      pre.setString(1, c);
                      pre.setString(2, i);
                      pre.setString(3, c);
                      pre.setString(4, i);
                      pre.setString(5, c);
                      pre.setString(6, i);
                      rs = pre.executeQuery();
      

      【讨论】:

      • 我知道。我在问题中写道。 :)
      • 没有看到更新;我删除了关于将 col 名称传递给 PreparedStatement 的部分。
      猜你喜欢
      • 2017-01-28
      • 1970-01-01
      • 2010-12-15
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 1970-01-01
      相关资源
      最近更新 更多