2013-07-11 96 views
1

我正在使用JDBC連接到Servlet中的數據庫(Oracle10)。
以下是我想要動態設置三個參數的查詢。oracle異常:表名無效

  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 Namesmypstmt.setString(1,tableName)

EDIT1 我爲什麼要parameterizeTable nameColumn name是我允許用戶選擇/輸入表的原因名稱和列名,所以我想避免SQL Injection

回答

4

我們無法直接將表名傳遞給PreparedStatement,因爲表名不能是綁定變量。 PreparedStatement

An object that represents a precompiled SQL statement.

A SQL statement is precompiled and stored in a PreparedStatement object. This object can then be used to efficiently execute this statement multiple times.

您必須構建帶字符串連接的sql。使用存儲過程,您可以使用Dynamic SQL動態地傳遞表名。甚至看看this SO answer瞭解爲什麼它受到限制。

+0

列名可以使用'PreparedStatement'作爲參數傳遞嗎? – user75ponic

+1

@Polppan - no。只有值可以作爲參數傳遞。 (否則,SQL引擎將無法預先編譯/計劃準備好的語句,並且您有更多的注入攻擊範圍等) –

+0

否................. ..... – NINCOMPOOP

2

您只能在SQL查詢中參數化?列值。表/列參數化是不可能的,而是使用變量來構造這樣的查詢,例如:

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

在的PreparedStatement只能替換值。你不能替換表名或列名。