2015-09-20 1 views
0

J'essaie de récupérer les enregistrements de la table de base de données ORACLE en utilisant le pilote JDBC thin. La déclaration préparée J'utilise: (1)'select' preparedStatement avec l'horodatage retourne toujours vide RecordSet

SELECT (t1.LOGGED_TIME - ?) AS TDIFF, t1.ID, t1.STATUS, t1.LOGGED_TIME, t1.SERVER_TIME 
     FROM table_1 t1 
     WHERE (
      ((t1.LOGGED_TIME - ?) <= INTERVAL '10' DAY) 
      AND ((t1.LOGGED_TIME - ?) >= INTERVAL '-10' DAY)) 
     ORDER BY t1.LOGGED_TIME DESC 

où t1.LOGGED_TIME représente une colonne d'horodatage. Tous les trois paramètres sont des horodatages identiques réglés avec

java.sql.Timestamp controlTime = Timestamp.valueOf("2014-08-15 03:52:00"); 

lookupTime.setTimestamp(1, controlTime); 
lookupTime.setTimestamp(2, controlTime); 
lookupTime.setTimestamp(3, controlTime); 

L'exécution du code fonctionne correctement - aucune exception ou avertissement n'est affiché. Néanmoins, le résultat retourné par

rs = lookupTime.executeQuery(); 

est vide.

Réglage de la requête à (2)

SELECT (t1.LOGGED_TIME - TO_TIMESTAMP('2014-08-15 03:52', 'yyyy-mm-dd hh24:mi')) AS TDIFF, t1.ID, t1.STATUS, t1.LOGGED_TIME, t1.SERVER_TIME 
FROM table_1 t1 
WHERE (
    ((t1.LOGGED_TIME - TO_TIMESTAMP('2014-08-15 03:52', 'yyyy-mm-dd hh24:mi')) <= INTERVAL '10' DAY) 
    AND ((t1.LOGGED_TIME - TO_TIMESTAMP('2014-08-15 03:52', 'yyyy-mm-dd hh24:mi')) >= INTERVAL '-10' DAY)) 
ORDER BY t1.LOGGED_TIME DESC 

renvoie les données attendues. Lorsque j'interroge par ex. chaînes d'une autre colonne de la même table avec une instruction préparée le résultat est ok.

Qu'est-ce qui me manque ici? Où est le point? Une idée? Pour dire les choses clairement: il ne s'agit pas d'identifier un type de conversion de format date/heure incorrect dans (2). Cela conduira toujours à un message d'erreur Oracle et peut être corrigé facilement.

La question est: pourquoi le RecordSet retourné par prepareStatement (1) est-il vide (= pas un seul enregistrement) sans notification d'erreur? Si le format Timestamp est erroné, pourquoi n'y a-t-il pas d'erreur ou d'avertissement?

+0

'TO_TIMESTAMP ('15/08/2014 03:52 ',' dd.mm.yy hh24: mi ') ': cela n'a pas beaucoup de sens. Le motif ne correspond pas à la chaîne. –

+0

Comment peut-on vous croire que la deuxième requête renvoie quelque chose, alors que cette requête ne peut pas exécuter l'événement en raison d'erreurs? ==> le motif ne correspond pas à la valeur de 'TO_TIMESTAMP ('2014-08-15 03:52', 'dd.mm.yy hh24: mi ') '? – krokodilko

+0

Vous avez raison. Copier et coller l'erreur. Je l'ai corrigé ... –

Répondre

0

Vérifiez votre format TO_TIMESTAMP:

TO_TIMESTAMP('2014-08-15 03:52', 
       'dd.mm.yy hh24:mi') 

Aug. 14, 2015, non Aug. 15, 2014

Mise à jour

En fait, je reçois l'erreur suivante en essayant que l'on:

ORA-01843: not a valid month 
01843. 00000 - "not a valid month" 

Update2

A Les cartes Java Timestamp à un type de données Oracle DATE, pas TIMESTAMP. Je ne sais pas si cela fait une différence, mais vous pouvez essayer TO_TIMESTAMP(?).

Je voudrais cependant modifier la requête pour permettre l'utilisation d'un indice potentiel sur LOGGED_TIME:

SELECT ID, STATUS, LOGGED_TIME, SERVER_TIME 
    FROM table_1 
WHERE LOGGED_TIME BETWEEN ? AND ? 
ORDER BY LOGGED_TIME DESC 

faire alors toutes les mathématiques en Java:

Timestamp controlTime = Timestamp.valueOf("2014-08-15 03:52:00"); 
Calendar cal = Calendar.getInstance(); 
cal.setTime(controlTime); 
cal.add(Calendar.DAY_OF_MONTH, -10); 
lookupTime.setTimestamp(1, new Timestamp(cal.getTimeInMillis())); 
cal.setTime(controlTime); 
cal.add(Calendar.DAY_OF_MONTH, 10); 
lookupTime.setTimestamp(2, new Timestamp(cal.getTimeInMillis())); 
try (ResultSet rs = lookupTime.executeQuery()) { 
    while (rs.next()) { 
     long tdiffInSeconds = (rs.getTimestamp("LOGGED_TIME").getTime() - controlTime.getTime())/1000; 
     // other code 
    } 
} 
+0

Comme ci-dessus: vous avez raison ... l'instruction est corrigée ... –

+0

La raison du résultat vide était: le schéma utilisé par le programme était différent du schéma utilisé par SQL Developer. Parce que je ne suis pas le propriétaire de la base de données, je dois utiliser les noms fournis par l'administrateur DB. Donc le problème est résolu. Néanmoins, merci pour votre réponse. J'ai implémenté comme suggéré (aussi l'indice pour l'indexation) –

+0

Pas besoin de trop compliquer les choses en faisant de l'arithmétique de date en Java; passer deux fois la même variable à la requête et utiliser 'WHERE LOGGED_TIME BETWEEN? ET ? + 10' ou 'OERE LOGGED_TIME ENTRE? ET ? + INTERVAL '10' JOUR' devrait être suffisant. –