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 name
和Column Names
设置为mypstmt.setString(1,tableName)
该怎么办
编辑1
我之所以想parameterize
Table name
和Column 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‘ 无效问题解决