2009-07-30 30 views
22

我想使用準備好的語句來設置一個表名來選擇數據,但是當我執行查詢時我總是收到一個錯誤。使用準備好的語句來設置表名

錯誤和示例代碼顯示在下面。

[Microsoft][ODBC Microsoft Access Driver] Parameter 'Pa_RaM000' specified where a table name is required. 



private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [?]"; //?=date 
public Execute(String reportDate){ 
    try { 

     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
     Connection conn = DriverManager.getConnection(Display.DB_MERC); 
     PreparedStatement st = conn.prepareStatement(query1); 
     st.setString(1, reportDate); 
     ResultSet rs = st.executeQuery(); 

想什麼可能會導致此?

+0

是的,輸入消毒,以防止SQL注入! – 2012-07-30 13:02:25

+1

如果您需要將不同的表名替換爲具有相同結構的查詢,則會指向數據庫設計中的缺陷。至少它指向具有相同關係屬性的多個表。將其標準化爲具有「主題」列的單個表格。 – 2015-11-12 21:43:43

回答

29

表名不能用作參數。它必須是硬編碼的。所以,你可以這樣做:

private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [" + reportDate + "?]"; 
+0

好的,謝謝,猜錯只是使用字符串替換 接受您的回答作爲回答 謝謝! – Brandon 2009-07-30 18:35:34

+4

不要!這是SQL注入造成的一個嚴重問題。 – Benvorth 2015-09-13 12:41:59

+7

在表名上使用`org.apache.commons.lang.StringEscapeUtils.escapeSql`來確保你不會讓你的模式面臨風險。 – Sebas 2015-10-26 23:46:12

-2

我不知道,你可以使用PreparedStatement指定表名,某些領域的只值。無論如何,你可以嘗試相同的查詢,但是,如果沒有括號:

"SELECT plantID, edrman, plant, vaxnode FROM ?" 
-2
String table="pass"; 

String st="select * from " + table + " "; 

PreparedStatement ps=con.prepareStatement(st); 

ResultSet rs = ps.executeQuery(); 
-3

沒有通過表名作爲一個變量

字符串NameOfTable =「test.Employee」的方式;

String Fquery =「SELECT * FROM」+ NameOfTable +「where Done ='No'」;

注: 應該有FROM和

隨後的「也與」何關鍵字
0

這樣多的人說,你不能使用語句參數表名之間的空間,僅用於變量作爲條件的一部分。

基於你有一個具有(至少)兩個表名的變量表名,也許最好創建一個方法,它接受你存儲的實體並返回一個準備好的語句。

PreparedStatement p = createStatement(table); 
1

這在技術上是可行的,但有一個解決方法,但是很糟糕的做法。

String sql = "IF ? = 99\n"; 
sql += "SELECT * FROM first_table\n"; 
sql += "ELSE\n"; 
sql += "SELECT * FROM second_table"; 
PreparedStatement ps = con.prepareStatement(sql); 

然後當你想從你first_table設定

ps.setInt(1, 99); 

或者,如果不是參數選擇,將它設置爲別的東西。