Prepared Statement et requête
Solène
-
KX Messages postés 16761 Date d'inscription Statut Modérateur Dernière intervention -
KX Messages postés 16761 Date d'inscription Statut Modérateur Dernière intervention -
Bonjour, j'ai créer une fonction afin que l'utilisateur puisse modifier n'importe quelle valeur d'une table donnée. Cela implique alors que la colonne contenant la valeur à modifier est fournit par l'utilisateur, j'utilise pour cela un Prepared statement mais ça bloque j'ai une erreur me disant qu'il y a un problème de requête : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax
Ma requête est :
sql="UPDATE vehicules SET ?=? WHERE Immatriculation = ?;";
Je sais que c'est le nom de la colonne qui cloche, parce que quand je spécifie le nom de la colonne ça marche :
sql="UPDATE vehicules SET Kilometrage=? WHERE Immatriculation = ?;"; //fonctionne
D'autre part je me pose aussi une autre question mon tableau contient des entiers mais aussi des chaînes de caractères, et vu qu'il faut spécifier de quelle type est la valeur à modifier je me retrouve bloquée.
De l'aide serait la bienvenue,
Cordialement,
Ma requête est :
sql="UPDATE vehicules SET ?=? WHERE Immatriculation = ?;";
Je sais que c'est le nom de la colonne qui cloche, parce que quand je spécifie le nom de la colonne ça marche :
sql="UPDATE vehicules SET Kilometrage=? WHERE Immatriculation = ?;"; //fonctionne
D'autre part je me pose aussi une autre question mon tableau contient des entiers mais aussi des chaînes de caractères, et vu qu'il faut spécifier de quelle type est la valeur à modifier je me retrouve bloquée.
De l'aide serait la bienvenue,
Cordialement,
A voir également:
- Quelle requête écrire pour demander au moteur de recherche de présenter de préférence les pages web traitant de tennis mais pas de tennis de table
- Impossible de supprimer une page word - Guide
- Table ascii - Guide
- Creation de site web - Guide
- Table de matière word - Guide
- Google moteur de recherche page d'accueil - Guide
2 réponses
Bonjour,
Je pense que tu devrais lister exhaustivement les colonnes que tu peux manipuler, les associer au type de données qu'elle doit contenir, et éventuellement les alias avec lesquels les utilisateurs peuvent y accéder.
Pour faire tout ça je pense à un enum. Si tu veux un exemple merci d'indiquer dans quelle version de Java tu codes.
Je pense que tu devrais lister exhaustivement les colonnes que tu peux manipuler, les associer au type de données qu'elle doit contenir, et éventuellement les alias avec lesquels les utilisateurs peuvent y accéder.
Pour faire tout ça je pense à un enum. Si tu veux un exemple merci d'indiquer dans quelle version de Java tu codes.
Bonjour,
Quand je demandais la version de Java dans laquelle tu codes c'est en terme de fonctionnalités. Tu as une version Java 8 (la plus récente) donc tout ce que je te proposes fonctionnera, si tu programmais avec des versions plus anciennes (Java 7, Java 6...) certains codes ne compileraient pas à cause de nouvelles classes, nouvelles méthodes, ou même nouvelles syntaxes qui n'existaient pas dans les versions plus anciennes.
Comme tu es en Java 8, j'ai mis des expressions lambda car c'est très pratique dans ton cas, si tu n'es pas familière avec ça tu peux regarder cet article : Java - Les Structures fonctionnelles
Bref, un exemple. Voici une enum de paramétrage qui permet de définir toutes les colonnes qui t'intéresse et leur comportement.
Pour l'exemple j'ai mis deux colonnes : KILOMETRAGE qui impose d'avoir un entier positif dans le JTextField et fait un setInt pour le Statement et IMMATRICULATION qui autorise lettres et chiffres et fait un setString.
Et voici un petit code de test, qui remplit une ComboBox avec toutes les valeurs de l'enum, vérifie que le champ rentré dans le TextField correspond bien au format attendu, et effectue la requête quand on appuie sur le bouton. Le point le plus important à remarquer c'est qu'on appelle à chaque fois l'enum pour savoir quoi faire, c'est elle qui contient la connaissance sur le traitement à effectuer, donc il faut juste rajouter des valeurs dans l'enum pour enrichir ton programme.
Remarque : le code qui fait la requête est désactivé car je n'ai pas d'objet Connection dans mon code de test, ça va juste afficher une pop-up.

La confiance n'exclut pas le contrôle
Quand je demandais la version de Java dans laquelle tu codes c'est en terme de fonctionnalités. Tu as une version Java 8 (la plus récente) donc tout ce que je te proposes fonctionnera, si tu programmais avec des versions plus anciennes (Java 7, Java 6...) certains codes ne compileraient pas à cause de nouvelles classes, nouvelles méthodes, ou même nouvelles syntaxes qui n'existaient pas dans les versions plus anciennes.
Comme tu es en Java 8, j'ai mis des expressions lambda car c'est très pratique dans ton cas, si tu n'es pas familière avec ça tu peux regarder cet article : Java - Les Structures fonctionnelles
Bref, un exemple. Voici une enum de paramétrage qui permet de définir toutes les colonnes qui t'intéresse et leur comportement.
Pour l'exemple j'ai mis deux colonnes : KILOMETRAGE qui impose d'avoir un entier positif dans le JTextField et fait un setInt pour le Statement et IMMATRICULATION qui autorise lettres et chiffres et fait un setString.
import java.sql.*; public enum VehiculeColonne { KILOMETRAGE("Kilométrage", "kilometrage", str -> Integer.parseInt(str) >= 0, (stmt, n, str) -> stmt.setInt(n, Integer.parseInt(str))), IMMATRICULATION("Immatriculation", "immatricution", str -> str.matches("\\w+"), (stmt, n, str) -> stmt.setString(n, str)); private final String description, colonne; private final Function<String, Boolean> validator; private final StatementSetter setter; private VehiculeColonne(String description, String colonne, Function<String, Boolean> validator, StatementSetter setter) { this.description = description; this.colonne = colonne; this.validator = validator; this.setter = setter; } public String getTableColonne() { return colonne; } public String getTableColonne(String tableId) { return tableId + "." + colonne; } public boolean isValid(String value) { try { return validator.apply(value); } catch (RuntimeException e) { return false; } } public void setParameter(PreparedStatement statement, int index, String param) throws SQLException { setter.accept(statement, index, param); } @Override public String toString() { return description; } }
import java.sql.*; @FunctionalInterface public interface StatementSetter { void accept(PreparedStatement statement, int index, String param) throws SQLException; }
Et voici un petit code de test, qui remplit une ComboBox avec toutes les valeurs de l'enum, vérifie que le champ rentré dans le TextField correspond bien au format attendu, et effectue la requête quand on appuie sur le bouton. Le point le plus important à remarquer c'est qu'on appelle à chaque fois l'enum pour savoir quoi faire, c'est elle qui contient la connaissance sur le traitement à effectuer, donc il faut juste rajouter des valeurs dans l'enum pour enrichir ton programme.
Remarque : le code qui fait la requête est désactivé car je n'ai pas d'objet Connection dans mon code de test, ça va juste afficher une pop-up.

import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.*; import java.sql.*; import javax.swing.*; public class Test { private static void validate(VehiculeColonne colonne, JTextField textField, JButton button) { if (colonne.isValid(textField.getText())) { textField.setBackground(Color.GREEN); button.setEnabled(true); } else { textField.setBackground(Color.RED); button.setEnabled(false); } } public static void main(String[] args) { JFrame frame = new JFrame(); JTextField textField = new JTextField(); JComboBox<VehiculeColonne> comboBox = new JComboBox<VehiculeColonne>(); JButton button = new JButton("Requête SQL"); for (VehiculeColonne colonne : VehiculeColonne.values()) { comboBox.addItem(colonne); comboBox.addItemListener(itemEvent -> { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { validate(colonne, textField, button); } }); } textField.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { validate((VehiculeColonne) comboBox.getSelectedItem(), textField, button); } public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { } }); button.addActionListener(actionEvent -> { VehiculeColonne colonne = (VehiculeColonne) comboBox.getSelectedItem(); String sql = "UPDATE vehicules SET " + colonne.getTableColonne() + " = ?"; JOptionPane.showMessageDialog(frame, sql); /* try (Connection con = null) { // TODO PreparedStatement stmt = con.prepareStatement(sql); colonne.setParameter(stmt, 1, textField.getText()); } catch (SQLException e) { e.printStackTrace(); } //*/ }); frame.add(comboBox, BorderLayout.NORTH); frame.add(textField, BorderLayout.CENTER); frame.add(button, BorderLayout.SOUTH); frame.setSize(200, 120); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
La confiance n'exclut pas le contrôle
Ma version c'est "Version 8 mise à jour 74" je sais pas si c'est ça que tu veux ?
build 1.8.0_74-b02