web-dev-qa-db-fra.com

Java Java.sql.SQLException: index de colonne non valide lors de la préparation de l'instruction

mon code ci-dessous interroge la base de données pour un ensemble de lignes basé sur l'entrée utilisateur. J'ai essayé et testé la requête à l'intérieur de SQL Developer et cela fonctionne parfaitement bien en renvoyant les lignes correctes. Et un exemple d'entrée est: 2013-01-22

Mais pour une raison quelconque à l'intérieur de Java je reçois cette erreur:

Java.sql.SQLException: Invalid column index

La console indique qu'elle tire sur cette ligne ici:

preparedStatement.setString(1, to);

Le code de connexion complet:

ResultSet rs = null;
        PreparedStatement preparedStatement = null;
        try {
            String strQuery =
                    "SELECT homes.home_id, homes.title, homes.description, homes.living_room_count, homes.bedroom_count, homes.bathroom_count, homes.price, homes.sqft,"
                    + " listagg(features.feature_name, '\n') WITHIN GROUP(ORDER BY features.feature_name) features, home_type.type_name"
                    + " FROM homes"
                    + " INNER JOIN bookings ON bookings.home_id <> homes.home_id"
                    + " INNER JOIN home_feature ON homes.home_id = home_feature.home_id"
                    + " INNER JOIN home_type ON home_type.type_code = homes.type_code"
                    + " INNER JOIN features ON home_feature.feature_id = features.feature_id"
                    + " WHERE bookings.booking_end < date '?'"
                    + " OR bookings.booking_start > date '?'"
                    + " GROUP BY homes.home_id, homes.title, homes.description, homes.living_room_count, homes.bedroom_count, homes.bathroom_count, homes.price, homes.sqft, home_type.type_name";

            preparedStatement = conn.prepareStatement(strQuery);//prepare the statement
            preparedStatement.setString(1, to);//insert
            preparedStatement.setString(2, from);//insert
            rs = preparedStatement.executeQuery();//execute query

La trace de pile complète ressemble à ceci:

SEVERE: Java.sql.SQLException: Invalid column index
at Oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.Java:5317)
at Oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.Java:5305)
at Oracle.jdbc.driver.OraclePreparedStatementWrapper.setString(OraclePreparedStatementWrapper.Java:248)
at DB.DatabaseConnector.getPropertiesSearch(DatabaseConnector.Java:258)
at DB.SearchServlet.doPost(SearchServlet.Java:47)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:688)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:770)
at org.Apache.catalina.core.StandardWrapper.service(StandardWrapper.Java:1550)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:281)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:175)
at org.Apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.Java:655)
at org.Apache.catalina.core.StandardPipeline.invoke(StandardPipeline.Java:595)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:161)
at org.Apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.Java:331)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:231)
at com.Sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.Java:317)
at com.Sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.Java:195)
at com.Sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.Java:860)
at com.Sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.Java:757)
at com.Sun.grizzly.http.ProcessorTask.process(ProcessorTask.Java:1056)
at com.Sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.Java:229)
at com.Sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.Java:137)
at com.Sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.Java:104)
at com.Sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.Java:90)
at com.Sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.Java:79)
at com.Sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.Java:54)
at com.Sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.Java:59)
at com.Sun.grizzly.ContextTask.run(ContextTask.Java:71)
at com.Sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.Java:532)
at com.Sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.Java:513)
at Java.lang.Thread.run(Thread.Java:722)

SEVERE:     at Oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.Java:5317)
SEVERE:     at Oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.Java:5305)
SEVERE:     at Oracle.jdbc.driver.OraclePreparedStatementWrapper.setString(OraclePreparedStatementWrapper.Java:248)
SEVERE:     at DB.DatabaseConnector.getPropertiesSearch(DatabaseConnector.Java:258)
SEVERE:     at DB.SearchServlet.doPost(SearchServlet.Java:47)
SEVERE:     at javax.servlet.http.HttpServlet.service(HttpServlet.Java:688)
SEVERE:     at javax.servlet.http.HttpServlet.service(HttpServlet.Java:770)
SEVERE:     at org.Apache.catalina.core.StandardWrapper.service(StandardWrapper.Java:1550)
SEVERE:     at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:281)
SEVERE:     at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:175)
SEVERE:     at org.Apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.Java:655)
SEVERE:     at org.Apache.catalina.core.StandardPipeline.invoke(StandardPipeline.Java:595)
SEVERE:     at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:161)
SEVERE:     at org.Apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.Java:331)
SEVERE:     at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:231)
SEVERE:     at com.Sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.Java:317)
SEVERE:     at com.Sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.Java:195)
SEVERE:     at com.Sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.Java:860)
SEVERE:     at com.Sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.Java:757)
SEVERE:     at com.Sun.grizzly.http.ProcessorTask.process(ProcessorTask.Java:1056)
SEVERE:     at com.Sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.Java:229)
SEVERE:     at com.Sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.Java:137)
SEVERE:     at com.Sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.Java:104)
SEVERE:     at com.Sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.Java:90)
SEVERE:     at com.Sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.Java:79)
SEVERE:     at com.Sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.Java:54)
SEVERE:     at com.Sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.Java:59)
SEVERE:     at com.Sun.grizzly.ContextTask.run(ContextTask.Java:71)
SEVERE:     at com.Sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.Java:532)
SEVERE:     at com.Sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.Java:513)
SEVERE:     at Java.lang.Thread.run(Thread.Java:722)

Je ne sais pas trop pourquoi l'erreur serait levée car la requête fonctionne correctement est le développeur SQL. J'utilise Oracle

MODIFIER:

Le jeu de résultats est lu dans cette même méthode. L'objet homes est ensuite renvoyé:

HomeList homes = new HomeList();
homes = new HomeList(rs);

Le constructeur ressemble à ceci:

public HomeList(ResultSet rs) {
    this();
    try {
        while (rs.next()) {
               list.add(new Home(rs.getInt(1),   
                                 rs.getString(2),
                                 rs.getString(3),   
                                 rs.getInt(4),
                                 rs.getInt(5),
                                 rs.getInt(6),
                                 rs.getInt(7),
                                 rs.getInt(8),
                                 rs.getString(9),
                                 rs.getString(10)
                                     ));
        }//end while
    } catch (SQLException e) {
        e.printStackTrace();
    }//end try
}
19
user1851487

Partout dans la chaîne de requête, le caractère générique doit être ? Au lieu de '?'. Cela devrait résoudre le problème.

MODIFIER:

Pour ajouter à cela, vous devez remplacer date '?' Par to_date(?, 'yyyy-mm-dd'). Veuillez essayer et faites le moi savoir.

31
TechSpellBound

Comme @TechSpellBound l'a suggéré, supprimez les guillemets autour du? signes. Ajoutez ensuite un caractère espace à la fin de chaque ligne dans votre chaîne concaténée. Sinon, la requête entière sera envoyée en tant que (en n'utilisant qu'une partie de celle-ci comme exemple): .... WHERE bookings.booking_end < date ?OR bookings.booking_start > date ?GROUP BY ....

Le ? et le OR doivent être séparés par un espace. Faites-le là où vous en avez besoin dans la chaîne de requête.

2
giorashc

Dans date '?', Le '?' Est une chaîne littérale avec la valeur ?, Pas un espace réservé de paramètre, donc votre requête n'a pas de paramètres. date est une conversion abrégée de la chaîne (littérale) à ce jour. Vous devez remplacer date '?' Par ? Pour avoir réellement un paramètre.

De plus, si vous savez qu'il s'agit d'une date, utilisez setDate(..) et non setString(..) pour définir le paramètre.

0
Mark Rotteveel