oracle 异常:无效的表名

Posted

技术标签:

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

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

    表名 列名 价值

查询:

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

【问题讨论】:

【参考方案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);
..

【讨论】:

以上是关于oracle 异常:无效的表名的主要内容,如果未能解决你的问题,请参考以下文章

oracle 中查询当前用户可以看到的表名表对应的所有字段 原

SQL Server2019数据库查询所有数据库名表名表结构表字段主键方法演示,执行sql提示对象名‘user_tab_columns‘ ‘user_cons_columns‘ 无效问题解决

SQLServer中获取所有数据库名表名字段名以及描述

datagrips oracle编写存储过程

SqlAdapter 无法识别我的表:异常“无效的对象名称”

授予授权的过程,无效的表名错误