2 votes

Comment attraper une violation de contrainte à l'intérieur de la boucle resultset ?

Je travaillais sur une servlet qui génère un code unique et le met à jour dans une base de données mySQL. Dans ce cas, je veux attraper toute exception lancée au cas où ce code unique existe déjà dans la table mySQL, générer un nouveau code et essayer de mettre à jour la base de données. Le problème est que je veux faire cela DANS la boucle for elle-même. Le code est le suivant :

    try
    {
    connection = datasource.getConnection();
    SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+unique_code+"','08-10-2011 04:48:48','0')";
      PreparedStatement ps1 = connection.prepareStatement(SQLUpdate);
      ps1.executeUpdate();
      ResultSet r = ps1.getResultSet(); // this is where I'm checking if it's a duplicate
      if(r==null)
          out.println("This is a duplicate");
      else out.println("Updated");
      trial12= "08-10-2011 04:48:480.03999855056924717a";
      SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+trial12+"','08-10-2011 04:48:48','0')";

      ps1 = connection.prepareStatement(SQLUpdate);
      ps1.executeUpdate();
      r = ps1.getResultSet();
      if(r==null)
          out.println("This is a duplicate");
      else out.println("Updated");

    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
    }

Je ne veux pas attendre la fin de la boucle entière pour attraper la SQLException (j'ai déjà défini cette clé dans mySQL comme primaire). Au moment où le résultat revient comme une entrée dupliquée, je veux re-générer cette clé et tenter à nouveau la mise à jour. Mon résultat pour ce code particulier est vide sur ma page de sortie (tous les autres paramètres s'affichent correctement). Le message "This is a duplicate" n'est pas affiché, ni le message "Updated". Peut-être que ResultSet n'est pas la meilleure façon de procéder. Pourriez-vous me donner quelques conseils sur la meilleure façon de procéder ?

3voto

Ryan Stewart Points 46960

Quelques conseils, sans ordre particulier :

  1. Fermez la connexion dans un bloc final.
  2. Fermez les déclarations individuellement si vous devez en créer plusieurs avant de fermer la connexion. ("Beaucoup" est défini par vos DBA).
  3. Formatez votre code.
  4. N'utilisez pas stdout et/ou stderr à partir du code réel. Choisissez un framework de journalisation.
  5. Envisagez d'utiliser des classes d'aide pour simplifier (et corriger) votre accès à la base de données, comme la classe d'aide Spring JdbcTemplate .
  6. Veillez à inclure le contexte pertinent lorsque vous publiez un exemple de code.

En raison du numéro 6, je ne sais pas ce que out mais je soupçonne que la raison pour laquelle vous ne voyez rien est que vous insérez une valeur en double avec la première déclaration, ce qui provoquera une SQLException à partir de cette ligne, et non à getResultSet() où vous semblez l'attendre. Puisque l'erreur est écrite sur stdout, elle apparaîtra quelque part dans les journaux de votre serveur, mais rien ne sera écrit dans le fichier out . Je ne suis pas sûr de savoir pourquoi vous pensez getResultSet() retournera null ou not null selon qu'il y a eu ou non une violation de contrainte. Jetez un coup d'œil à la javadoc pour cette méthode .

Mise à jour : 7. Comme le souligne BalusC, jamais, jamais concaténer une chaîne directement dans un statut JDBC. Utilisez l'élément PreparedStatment et set* méthodes . Pour plus d'informations sur l'injection SQL, voir Wikipedia y XKCD .

1voto

James Jithin Points 2573

Que pensez-vous de ce code ?

try {
            Class.forName(driver).newInstance();
            conn = DriverManager.getConnection(url + dbName);
            System.out.println("Connected to the database");
            int i = 1;                                     //get the unique code
            boolean isInserted = false;
            while (!isInserted) {
                try {
                    PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO test values (?)");
                    preparedStatement.setInt(1, i);
                    preparedStatement.executeUpdate();
                    isInserted = true;
                } catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) {   //Catch the particular exception which throws error on unique constraint. This may depend on Java/MySQL your version 
                    i++;                         //get the next unique code
                }
            }

            System.out.println("Disconnected from database");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
            }
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X