2017-08-09 49 views
0

需要一點幫助。在Exception中有一些問題,我在使用這個庫時很新穎。感謝提前:)用HashMap編寫語句,異常

錯誤:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''common_translations.name' as nm JOIN ('common_translations.name_id' as nid)

我的代碼:

private DatabaseConnection db; 
private final HashMap <String, String> statements; 

public DatabaseReader(DatabaseConnection db) { 
    statements = new HashMap<String, String>() { 
     private static final long serialVersionUID = -1827340576955092045L; 
    { 
     put("odds","vfl::%"); 
     put("common_translations", "vhc::%"); 
     put("common_translations","vdr::%"); 
     put("common_translations", "vto::%"); 
     put("common_translations","vbl::%"); 
     put("common_translations", "vf::%"); 
     put("odds","vsm::%"); 
     put("odds", "rgs::%"); 
     put("odds", "srrgs::%"); 
    }}; 

    this.db = db; 
} 

public void read() { 
    try { 
     Connection connection = db.connect(db.getUrl_common_translation()); 
     PreparedStatement ps = (PreparedStatement) connection.prepareStatement("SELECT nm.id, nid.key, nm.name FROM ? as nm JOIN (? as nid)\r\n" + 
       "     ON (nm.id = nid.id) where nid.key like ? and nm.typeId=8 and nm.sourceId=-1 and nm.languageCode='en'");   
     for(Entry <String,String> e : statements.entrySet()) { 
      ps.setString(1, e.getKey() + ".name"); 
      ps.setString(2, e.getKey() + ".name_id"); 
      ps.setString(3, e.getValue()); 
      ResultSet rs = ps.executeQuery(); 
      while(rs.next()) { 
       int id = rs.getInt("id"); 
       //String tag = rs.getString("tag"); 
       //String translation = rs.getString("translation");  
       System.out.println(id); 
      } 
     } 



    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 
} 
+3

您不能使用''佔位符系統來代替表名或列名,它僅適用於價值。 – Berger

+0

哦,好的,謝謝。你有沒有任何建議可以聰明地做到這一點? –

+2

也許你可以使用'StringBuilder'來根據目標表建立你的查詢字符串。 – Berger

回答

1

你用錯誤的方式設置列的名稱,這樣的:

ps.setString(1, e.getKey() + ".name"); 
ps.setString(2, e.getKey() + ".name_id"); 

威爾在引號之間輸入:

FROM "something.name" as 

這是一個錯誤的語法。

相反,你必須直接而不事先準備好的聲明這樣的設置名稱:

Connection connection = db.connect(db.getUrl_common_translation()); 
PreparedStatement ps = (PreparedStatement) connection.prepareStatement(); 
for (Entry<String, String> e : statements.entrySet()) { 
    String query = "SELECT nm.id, nid.key, nm.name FROM " + e.getKey() + ".name" +" as nm " 
      //----------------------------------------------^__________________^ 
      + "JOIN (" + e.getKey() + ".name_id" + " as nid) ON (nm.id = nid.id) " 
      //-----------^_____________________^ 
      + "where nid.key like ? and nm.typeId=8 " 
      + "and nm.sourceId=-1 and nm.languageCode='en'"; 
    ps.setString(1, e.getValue()); 
    ResultSet rs = ps.executeQuery(query); 
    //------------------------------^^ 

但是你要檢查的名稱在此之前不應該包含感染查詢事(避免語法錯誤,並SQL注入),所以你需要前

0

但從DB點,使某些控制器,你會試圖執行一個查詢:

SELECT nm.id, nid.key, nm.name 
    FROM :param1 as nm 
     JOIN (:param2 as nid) ON (nm.id = nid.id) 
where nid.key like :param3 and nm.typeId=8 and nm.sourceId=-1 and nm.languageCode='en' 

一些parame TER值。但是你不能傳遞表或視圖作爲參數。這個不成立。

來解決你的問題,你可以使用這個片段:

String sql = "SELECT nm.id, nid.key, nm.name FROM %s as nm JOIN (%s as nid)\r\n" + 
      "     ON (nm.id = nid.id) where nid.key like ? and nm.typeId=8 and nm.sourceId=-1 and nm.languageCode='en'" 
for(Entry <String,String> e : statements.entrySet()) { 
    PreparedStatement ps = (PreparedStatement) connection.prepareStatement(
      String.format(sql, e.getKey() + ".name", e.getKey() + ".name_id") 
    );   
    ps.setString(1, e.getValue()); 
     .... your code here .... 
} 
+0

好的,謝謝你,這正是我正在尋找的:)但問題是這段代碼被數據庫拒絕:/ –