【问题标题】:oracle exception: invalid table nameoracle 异常:无效的表名
【发布时间】:2013-07-09 07:20:31
【问题描述】:

我正在使用JDBC 连接到 Servlets 中的数据库 (Oracle10)。
以下是我想要动态设置三个参数的查询。

  1. 表名
  2. 列名
  3. 价值

查询:

query = "select ? from ? where ? = ?";
mypstmt = con.prepareStatement(query);
mypstmt.setString(1, tableName);
mypstmt.setString(2, columnName);
mypstmt.setString(3, columnName2);
mypstmt.setString(4, value);

但上面的查询给了我错误:

java.sql.SQLException: ORA-00903: invalid table name

我检查了表名。这是正确的,如果我这样写查询:

query = "select "+columnName+" from "+tableName+" where "+columnName2+" = ?";

然后它执行得很好。

那么如果我想将Table nameColumn Names设置为mypstmt.setString(1,tableName)该怎么办

编辑1 我之所以想parameterizeTable nameColumn name 是因为我允许用户选择/输入表名和列名,所以我想避免SQL Injection

【问题讨论】:

    标签: java oracle servlets jdbc


    【解决方案1】:

    我们不能将表名直接传递给PreparedStatement,因为表名不能是绑定变量。 PreparedStatement.

    表示预编译 SQL 语句的对象。

    SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用该对象多次有效地执行该语句。

    您必须使用字符串连接构造 sql。使用存储过程,您可以使用Dynamic SQL 动态传递表名。甚至可以查看this SO answer 以了解它为何受到限制。

    【讨论】:

    • 列名可以作为参数使用PreparedStatement?
    • @Polppan - 没有。只有值可以作为参数传递。 (否则,SQL 引擎将无法预编译/计划准备好的语句,并且您将拥有更大的注入攻击范围等)
    【解决方案2】:

    在 PreparedStatement 中,您只能替换值。您不能替换表名或列名。

    【讨论】:

      【解决方案3】:

      您只能在 SQL 查询中参数化 ? 列值。表/列参数化是不可能的,而是使用变量来构造这样的查询,例如:

      void query(String tableName, String columnName, String queryColumnName String val) {
      String query = "select "+columnName+" from "+tableName+" where "+queryColumnName+" = ?";
      mypstmt.setString(1, val);
      ..
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-05
        • 1970-01-01
        • 1970-01-01
        • 2015-03-22
        • 1970-01-01
        • 1970-01-01
        • 2021-10-16
        相关资源
        最近更新 更多