2017-08-09 3 views
0

besoin d'un peu d'aide à ce sujet. Avoir quelques problèmes avec une exception et je suis très nouveau dans l'utilisation de cette bibliothèque. Merci d'avance :)Instruction préparée avec HashMap, Exception

Erreur:

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)

Mon code:

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

Vous ne pouvez pas utiliser le système '' placeholders pour remplacer un nom de table ou un nom de colonne, il ne fonctionne que pour les valeurs. – Berger

+0

Oh d'accord, merci. Avez-vous peut-être des conseils pour le faire de manière intelligente? –

+2

Eh bien peut-être que vous pourriez utiliser un 'StringBuilder' pour construire votre chaîne de requête en fonction des tables ciblées. – Berger

Répondre

1

Vous définissez le nom de colonnes d'une mauvaise façon, ceci:

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

Will faire la saisie entre guillemets:

FROM "something.name" as 

et ceci est une fausse syntaxe.

Au lieu de cela vous devez définir les noms directement, sans déclaration préparée comme ceci:

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); 
    //------------------------------^^ 

Mais avant cela, vous devez vérifier les noms ne devraient pas contient quelque chose qui infectent la requête (pour éviter les erreurs de syntaxe et injection sql), de sorte que vous devez faire quelques contrôleurs avant

0

du point de vue DB, vous essayez d'exécuter une requête:

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' 

avec quelques Paramé teurs. Mais vous ne pouvez pas passer une table ou une vue en paramètre. Cela n'a aucun sens.

pour vous fixer problème, vous pouvez utiliser cet extrait:

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

Eh bien merci, c'est exactement ce que je cherchais :) Mais le problème est que ce morceau de code est refusé par la base de données: / –