IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

JDBC, PreparedStatement et quotes


Sujet :

JDBC Java

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Par défaut JDBC, PreparedStatement et quotes
    Bonjour,

    Ayant parcouru de nombreux tutoriaux et forums, j'en arrive à me poser la question suivante :

    Lorsqu'on compile et exécute ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import java.sql.*;
    import javax.sql.*;
     
    public class Test
    {
     
        public static void main(String[] args) throws Exception
        {
            String URL = "jdbc:postgresql://localhost:5432/blih";
            String driver ="org.postgresql.Driver";
            Connection      con = null;
            Class.forName(driver);
            con = DriverManager.getConnection(URL,"bluh","blah");
            String sql = "UPDATE Stocks SET prix = ? WHERE nom = ?";
            PreparedStatement preparedStatement = con.prepareStatement(sql);
            preparedStatement.setInt(1,256);
            preparedStatement.setString(2,"café");
            System.out.println(preparedStatement);
            con.close();
        }
     
    }
    Doit on avoir comme résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE Stocks SET prix = 256 WHERE nom = café
    ou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE Stocks SET prix = 256 WHERE nom = 'café'
    C'est à dire : est-ce que setString ne devrait pas mettre de lui même les quotes autour des chaînes passées en paramètre? Ou doit on les entourer à chaque fois par nous même?

    Dans de nombreux documents, les chaines ne sont pas entourées de quotes, or, dès qu'il y a un espace ou que la chaîne est vide, la requête devient invalide.

    Voir les url suivantes :
    http://java.sun.com/docs/books/tutor.../prepared.html
    http://java.developpez.com/faq/jdbc/...paredStatement

    Ce qui fait que dans mon application, je me retrouve avec des requêtes pareilles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update t_table set  id_cv=, id_bug=, id_bug_test=erv, dis_date=1970-01-01 +01:00:00,  dated=0,  last_update=2009-04-10 16:23:54.644000 +02:00:00, version=,[...]


    La requête est préparée ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
             sSQL = "update t_table set "
                + " id_cv=?,"
                + " id_bug=?,"
                + " id_bug_test=?,"
                + " dis_date=?, "
                + " dated=?, "
                + " last_update=?,"
                + " version=?, "
    [...]
    updatePS = p_conn.prepareStatement(sSQL);
     
             try {
                updatePS.setString(1, sIdCve);
                updatePS.setString(2, idBug);
                updatePS.setString(3, idBugTest);
                updatePS.setDate(4, oDisDate);
    [...]
    J'attends vos avis avant de me relancer dans un ajout massif de quotes!

  2. #2
    in
    in est déconnecté
    Membre Expert Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Par défaut
    Non il ne faut pas ajouter les quotes, les PreparedStatement sont là pour gérer les paramètres à ta place ...

    Comment affiches tu ta requête qui plante ?
    Quelle est l'erreur exactement ?

  3. #3
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Par défaut
    J'affiche l'erreur avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println(preparedStatement);
    dans mon premier exemple (ce qui donne le premier résultat indiqué), et dans mon application avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    logger.info(updatePS.toString());
    (logger étant un objet Log4J).

    Celà devrait pourtant fonctionner dans le premier cas non? Je suis passé de Java 6 à Java 5, même erreur... Dans le code du driver PostgreSQL on trouve pourtant bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public void setStringParameter(int index, String value, int oid) throws SQLException {
            StringBuffer sbuf = new StringBuffer(2 + value.length() * 11 / 10); // Add 10% for escaping.
     
            if (useEStringSyntax)
                sbuf.append(' ').append('E');
            sbuf.append('\'');
            Utils.appendEscapedLiteral(sbuf, value, false);
            sbuf.append('\'');
     
            setLiteralParameter(index, sbuf.toString(), oid);
        }
    J'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    dpkg -l | grep postgre
    ii  odbc-postgresql                            1:08.03.0200-1                          ODBC driver for PostgreSQL
    ii  postgresql-8.3                             8.3.7-0ubuntu8.10.1                     object-relational SQL database, version 8.3
    ii  postgresql-client-8.3                      8.3.7-0ubuntu8.10.1                     front-end programs for PostgreSQL 8.3
    ii  postgresql-client-common                   90                                      manager for multiple PostgreSQL client versi
    ii  postgresql-common                          90                                      PostgreSQL database-cluster manager
    Pour le test, compilation avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    blih@bluh:~/test$ javac *.java
    Et lancement avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    blih@bluh:~/test$ java -cp postgresql-8.3-604.jdbc3.jar:. Test 
    UPDATE Stocks SET prix = 256 WHERE nom = café
    L'erreur dans le log de l'application est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    2009-04-10 16:23:54,649  INFO [http-8080-2] (BlahEditSubmit.java:391) - update t_table set  id_cv=, id_bug=, id_bug_test=erv, dis_date=1970-01-01 +01:00:00,  dated=0,  last_update=2009-04-10 16:23:54.644000 +02:00:00, version=,[...]
    2009-04-10 16:23:54,653 ERROR [http-8080-2] (BlahEditSubmit.java:663) - 
    org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc
    de la transaction
    	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
    	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
    	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:337)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:236)
    	at com.bluh.blih.common.blahcorej.jdbc.JDBCBox.getIntArray(JDBCBox.java:238)
    	at com.bluh.blih.file.BlahEditSubmit.saveAsBlerg(BlahEditSubmit.java:426)
    	at com.bluh.blih.file.BlahEditSubmit.handleRequest(BlahEditSubmit.java:610)
    	at com.bluh.blih.Action.handleRequest(Action.java:162)
    	at com.bluh.blih.BlahAction.handleRequest(BlahAction.java:184)
    	at com.bluh.blih.ControllerServlet.doRequest(ControllerServlet.java:882)
    	at com.bluh.blih.ControllerServlet.doPost(ControllerServlet.java:614)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at CharsetFilter.doFilter(CharsetFilter.java:21)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:525)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    	at java.lang.Thread.run(Thread.java:619)

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    D'après la log, il semblerait que tu fasses un preparedStatment.executeQuery(...) à la place d'un preparedStatement.executeUpdate(...)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Par défaut
    Au temps pour moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    org.postgresql.util.PSQLException: ERREUR: l'opérateur n'existe pas : character varying = integer
    	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
    	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
    	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
    	at com.bluh.blih.file.BlahEditSubmit.saveAsBlerg(BlahEditSubmit.java:388)
    Trompage de ligne désolé...

    Note : en rajoutant des quotes partout dans ma requête, cela fonctionne! Mais le but de setString, setDate etc est de les mettre eux-même (ce me semble)! L'application tourne en production... et on m'a donné les dernières sources disponible. Je ne pense pas qu'ils se soient amusés à mettre des quotes dans tout le code...

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Ce n'est pas conçu pour fonctionner avec des quotes autour des ? ('?'), le principe même du PreparedStatement est de s'affranchir de ces problématiques...
    Peux-tu montrer le code (exact) qui ne fonctionne pas ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Par défaut
    Désolé pour le temps de réponse, je suis obligé de donner une version "éditée", je ne peux donner le code avec les noms de variables qui vont bien, sinon je vais me faire tapper sur les doigts!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    protected void save(Connection p_conn)
    throws  SQLException, NoRowSelectedException,
    	BlahException, InvalidParamInQueryException,
    	ParseException, InvalidParameterException, Exception {
     
    	String sSQL = null;
    	PreparedStatement updatePS = null;
     
    	String sId = FormBox.getNotEmptyParam(req, "id_blih");
     
    	// ids
    	String sIdBlah = FormBox.getParamForSQL(req, "id_blah");
    	if ( sIdBlah==null ) {
    		sIdBlah="";
    	} // if
     
    	String idBug = FormBox.getParamForSQL(req, "id_bug");
    	if ( idBug==null) {
    		idBug"";
    	} // if
     
    	String idBugTest = FormBox.getParamForSQL(req, "id_bug_test");
    	if ( idBugTest==null ) {
    		idBugTest="";
    	} // if
     
    	String version = FormBox.getParamForSQL(req, "version");
    	if ( version==null ) {
    		version = "";
    	} // if
     
    	// date
    	String sDisDate = FormBox.getParamForSQL(req, "dis_date");
    	if ( (sDisDate==null) || sDisDate.equals("") ) {
    		sDisDate = Constants.DEFAULT_DIS_DATE;
    	} // if
    	java.util.Date oDateTmp = FormatBox.getDateShort(sDisDate);
    	Date oDisDate = new Date(oDateTmp.getTime());
     
    	Timestamp oLastUpdate = new Timestamp(System.currentTimeMillis());
     
    	String dated = FormBox.getParamForSQL(req, "dated");
    	if ( (dated==null) || !dated.equals("1") ) {
    		dated = "0";
    	} // if
    	// changed status
    	String changed = FormBox.getParamForSQL(req, "changed");
    	if ( (changed==null) || !changed.equals("1") ) {
    		changed = "0";
    	} // if
     
    	String ex = FormBox.getParamForSQL(req, "ex");
    	if ( ex==null ) {
    		ex="";
    	} // if
     
    	// changelog
    	String changelog = FormBox.getParamForSQL(req, "changelog");
    	if ( changelog==null ) {
    		changelog="";
    	} // if
     
    	// last edition date
    	Timestamp oEditDate = oLastUpdate;
     
    	// --------------------------------------------------------------
    	p_conn.setAutoCommit(false);
     
    	int last = 0;
    	try {
    	    sSQL = "update t_table set "
    		+ " id_blah=?,"
    		+ " id_bug=?,"
    		+ " id_bug_test=?,"
    		+ " dis_date=?, "
    		+ " dated=?, "
    		+ " last_update=?,"
    		+ " version=?, "
    		+ " ex=?, "
    		+ " changelog=?, "
    		+ " changed=? "
    		+ " where id="+sId;
     
    		updatePS = p_conn.prepareStatement(sSQL);
     
    		try {
    			updatePS.setString(1, sIdCve);
    			updatePS.setString(2, idBugTraq);
    			updatePS.setString(3, idVendorBug);
    			updatePS.setDate(4, oDiscoveryDate);
                		if (dated == null) {
                   			updatePS.setNull(5, java.sql.Types.NULL);
                		} else {
                   			updatePS.setInt(5, (new Integer(dated)).intValue());
                		}
                		updatePS.setTimestamp(6, oLastUpdate);
    		        updatePS.setString(7, FormatBox.formatSQL((Object)vulnerableVersion, new Integer(java.sql.Types.VARCHAR)));
    		        updatePS.setString(8, exploit);
    		        updatePS.setString(9, changelog);
    		        updatePS.setInt(10, (new Integer(changed)).intValue());
    			updatePS.executeUpdate();
    		} catch (Exception e){
    			logger.error("erreur",e);		
    	        } finally {
    			updatePS.close();
    		}
    	} finally {
    		p_conn.rollback();
    		p_conn.setAutoCommit(true);
    	}
    }

  8. #8
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Par défaut
    Quelqu'un pourrait-il faire le test et me dire si mon cas est particulier? J'ai poursuivi mes recherches mais je n'ai rien trouvé de concluant...

Discussions similaires

  1. Debutant JDBC PreparedStatement
    Par _cheval_ dans le forum JDBC
    Réponses: 13
    Dernier message: 18/07/2007, 12h45
  2. [JDBC] PreparedStatement, interêt ?
    Par ohyes_ dans le forum JDBC
    Réponses: 5
    Dernier message: 12/07/2006, 12h10
  3. [JDBC] PreparedStatement arguments
    Par phoebe dans le forum JDBC
    Réponses: 8
    Dernier message: 29/05/2006, 17h05
  4. Réponses: 1
    Dernier message: 24/05/2006, 15h26
  5. Réponses: 1
    Dernier message: 08/11/2005, 15h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo