tags:

views:

216

answers:

2

Hi all,

I'm attempting to retrieve data from a SolarWinds network performance database (MS SQL 2005) and a query that works perfectly fine interactively (in the Orion database manager) returns no rows when run via JDBC. Any ideas?

The query itself is a shocker (I dislike MS-SQL date/time handling which I believe forces queries like this for joins by date/hour). I can cut and paste the query output by println and it works fine, yet in my program it returns no rows (but throws no exceptions).

I assume that query complexity doesn't matter, on the basis that JDBC will not attempt to parse the query - it will just pass it through to the back end.

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()) {
   ....
 }

Thanks all for your suggestions. I believe the issue was with interpretation of dates/times. I used a PreparedStatement as suggested, and the query then worked.

+1  A: 

As to your query, dates/timestamps are to be set using PreparedStatement#setDate()/setTimestamp(). Not only to avoid SQL injections but also to prevent from formatting mistakes in the String representation of the Date.

BalusC
+1  A: 

JDBC syntax does not terminate the SQL statement with a semi-colon.

The line adding the last clause to the SQL string should read:

" order by rd.nodeid, rd.hr");
richj
Good point, but it should be noted that accepting the terminating semicolon is dependent on the JDBC driver. If his doesn't, it would indeed explain the cause of the problem. I have never worked with MSSQL, but if I recall correctly, the MySQL JDBC driver doesn't accept it while the Oracle and PostgreSQL ones did. Not sure about DB2, it's been too long ago I used DB2 for last time.
BalusC
I tried with and without semicolon, with no change. I also tried a simpler query, with the same symptomsselect nodeid, DATEPART(hh, DateTime) as hr, round(avg(AvgResponseTime), 0) as response, round(avg(PercentLoss), 0) as loss from ResponseTime_Detail where DateTime >= '2009-11-03' and DateTime < '2009-11-04' group by nodeid, DATEPART(hh, DateTime);The DB connection is valid (i.e. isValid(10) return true), but I expect the answer is something to do with the connection
Mike
It turns out that Mike's problem was something else, but here's some more on the semicolon.I believe that the semicolon is not technically part of the SQL statement. It is a statement terminator or separator, commonly used by command line interfaces. The JDBC 4.0 specification doesn't mention the semicolon, but doesn't include one in its example SQL.I've used both Oracle and SQLServer. Oracle gives an error: ORA-00911 invalid characterMy theory is that SQL Server returns an empty result set because the SQL string contains two statements, and the last is empty. I'm not sure on this.
richj
SQL Server with the jtds driver returns a valid result set even with a trailing semicolon. You can even put valid SQL after the semicolon and it will still give you the result set for the first query. Invalid SQL after the semicolon causes an error.
richj