2009-11-03 2 views
2

Je tente d'extraire des données d'une base de données de performances réseau SolarWinds (MS SQL 2005) et une requête qui fonctionne parfaitement bien (dans le gestionnaire de base de données Orion) ne renvoie aucune ligne lors de l'exécution via JDBC. Des idées?La requête JDBC ne renvoie aucune ligne, mais la requête interactive le fait?

La requête elle-même est un shocker (je n'aime pas la gestion de la date et de l'heure MS-SQL qui, selon moi, force les requêtes de ce type pour les jointures par date/heure). Je peux couper et coller la sortie de la requête par println et cela fonctionne bien, mais dans mon programme, il ne renvoie aucune ligne (mais ne lance aucune exception).

Je suppose que la complexité de la requête n'a pas d'importance, car JDBC n'essaiera pas d'analyser la requête - elle la transmettra simplement à l'arrière-plan.

String qtext = new String("select rd.nodeid, rd.hr, rd.response, rd.loss, cd.cpu, cd.mem, bd.nomem, bd.smmiss, bd.mdmiss, bd.bgmiss, bd.lgmiss, bd.hgmiss" + " from" + 
    " (select nodeid, DATEPART(hh, DateTime) as hr, round(avg(AvgResponseTime), 0) as response, round(avg(PercentLoss), 0) as loss" + 
    " from ResponseTime_Detail" + 
    " where DateTime >= " + today + " and DateTime < " + tomorrow + 
    " group by nodeid, DATEPART(hh, DateTime)" + 
    ") as rd" + 
    " left outer join" + 
    " (select nodeid, DATEPART(hh, DateTime) as hr, round(avg(AvgLoad), 0) as cpu, bound(avg(AvgPercentMemoryUsed), 0) as mem" + 
    "  from CPULoad_Detail" + 
    " where DateTime >= " + today + " and DateTime < " + tomorrow + 
    "  group by nodeid, DATEPART(hh, DateTime)" + 
    ") as cd" + 
    " on rd.nodeid = cd.nodeid and rd.hr = cd.hr" + 
    " left outer join" + 
    " (select nodeid, DATEPART(hh, DateTime) as hr, round(avg(BufferNoMem), 0) as nomem, round(avg(BufferSmMiss), 0) as smmiss, round(avg(BufferSmMiss), 0) as mdmiss," + 
    "   round(avg(BufferBgMiss), 0) as bgmiss, round(avg(BufferLgMiss), 0) as lgmiss, round(avg(BufferHgMiss), 0) as hgmiss" + 
    "  from CiscoBuffers_Detail" + 
    " where DateTime >= " + today + " and DateTime < " + tomorrow + 
    "  group by nodeid, DATEPART(hh, DateTime)" + 
    ") as bd" + 
    " on rd.nodeid = bd.nodeid and rd.hr = bd.hr" + 
    " order by rd.nodeid, rd.hr;"); 
System.out.println("Query from hell = [" + qtext + "]"); 
st = sol.db.createStatement(); 
System.out.println("Created statement"); 
rs = st.executeQuery(qtext); 
System.out.println("Executed statement"); 
while (rs.next()) { 
    .... 
} 

Merci à tous pour vos suggestions. Je crois que le problème était avec l'interprétation des dates/heures. J'ai utilisé un PreparedStatement comme suggéré, et la requête a ensuite travaillé.

+0

Vous pouvez essayer d'exécuter à travers pour écarter tout problème jdbc SQL Écureuil (http://squirrel-sql.sourceforge.net/) . –

+0

Si cela fonctionne maintenant, alors la meilleure chose à faire est d'accepter la réponse la plus proche. Dans votre cas, vous devez accepter une réponse qui vous a suggéré d'utiliser PreparedStatement. Autrement, les gens essaieraient de vous donner une réponse, mais vous avez déjà résolu le problème. Gagnez du temps, s'il vous plaît. –

Répondre

1

En ce qui concerne votre requête, les dates/horodatages doivent être définis en utilisant PreparedStatement#setDate()/setTimestamp(). Non seulement pour éviter les injections SQL mais aussi pour éviter les erreurs de formatage dans la représentation String de la date.

1

La syntaxe JDBC ne termine pas l'instruction SQL avec un point-virgule.

La ligne en ajoutant la dernière clause de la chaîne SQL devrait lire:

" order by rd.nodeid, rd.hr"); 
+0

Bon point, mais il convient de noter que l'acceptation du point-virgule de terminaison dépend du pilote JDBC. Si ce n'est pas le cas, cela expliquerait en effet la cause du problème. Je n'ai jamais travaillé avec MSSQL, mais si je me souviens bien, le pilote MySQL JDBC ne l'accepte pas, contrairement à Oracle et PostgreSQL. Pas sûr de DB2, ça fait trop longtemps que j'ai utilisé DB2 pour la dernière fois. – BalusC

+0

J'ai essayé avec et sans point-virgule, sans changement. J'ai également essayé une requête plus simple, avec les mêmes symptômes sélectionnez nodeid, DATEPART (hh, DateTime) comme hr, round (avg (AvgResponseTime), 0) comme réponse, round (avg (PercentLoss), 0) comme perte de ResponseTime_Detail où DateTime> = '2009-11-03' et DateTime <'2009-11-04' groupe par nodeid, DATEPART (hh, DateTime); La connexion DB est valide (par exemple, isValid (10) renvoie true), mais je pense que la réponse est liée à la connexion. – Mike

+0

Il s'avère que le problème de Mike était autre, mais voici un peu plus sur le point-virgule. Je crois que le point-virgule ne fait pas techniquement partie de l'instruction SQL. C'est un terminateur ou un séparateur d'instructions, couramment utilisé par les interfaces de ligne de commande. La spécification JDBC 4.0 ne mentionne pas le point-virgule, mais n'en inclut pas dans son exemple SQL. J'ai utilisé à la fois Oracle et SQLServer. Oracle donne une erreur: ORA-00911 caractère non valide Ma théorie est que SQL Server renvoie un jeu de résultats vide car la chaîne SQL contient deux instructions, et la dernière est vide. Je ne suis pas sûr à ce sujet. – richj

Questions connexes