JDBC查询没有返回行,但交互式查询呢?

问题描述:

我试图从SolarWinds网络性能数据库(MS SQL 2005)中检索数据,并且交互式工作的完美交互式查询(在Orion数据库管理器中)通过JDBC运行时不返回任何行。有任何想法吗?查询本身是一个令人震惊的(我不喜欢MS-SQL日期/时间处理,我相信强制按照日期/小时的连接查询这样的查询)。我可以通过println剪切并粘贴查询输出,它可以正常工作,但在我的程序中它不返回行(但不会引发异常)。JDBC查询没有返回行,但交互式查询呢?

我假设查询复杂性并不重要,因为JDBC不会尝试解析查询 - 它只会将其传递到后端。

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

谢谢大家的建议。我相信这个问题与日期/时间的解释有关。按照建议使用PreparedStatement,然后查询就可以工作。

+0

你可以尝试通过SQL松鼠(http://squirrel-sql.sourceforge.net/)上运行,以排除任何JDBC问题。 – 2009-11-03 21:57:58

+0

如果它现在在工作,那么最好的办法就是接受最接近的答案。在你的情况下,你应该接受一个建议你使用PreparedStatement的答案。否则,人们会试图给你一个答案,但你已经解决了这个问题。请节省时间。 – 2009-11-04 02:47:22

至于您的查询,日期/时间戳应使用PreparedStatement#setDate()/setTimestamp()设置。不仅要避免SQL注入,而且要防止日期的字符串表示形式中出现格式错误。

JDBC语法不会用分号终止SQL语句。

线将最后一句的SQL字符串应该阅读:

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

好点,但应该指出,接受终止分号取决于JDBC驱动程序。如果他不这样做,那确实会解释问题的原因。我从来没有使用MSSQL,但如果我没有记错,MySQL JDBC驱动程序不会在Oracle和PostgreSQL中接受它。对DB2不太确定,这是我上次使用DB2的时间太久了。 – BalusC 2009-11-03 23:36:36

+0

我用分号尝试,没有变化。我还尝试了一个更简单的查询,其中包含相同的症状 作为响应,round(avg(PercentLoss),0)选择nodeid,DATEPART(hh,DateTime)作为hr,round(avg(AvgResponseTime),0)作为ResponseTime_Detail 其中DateTime> ='2009-11-03'和DateTime Mike 2009-11-04 00:29:53

+0

事实证明,迈克的问题是别的,但这里有更多的分号。 我相信分号在技术上并不是SQL语句的一部分。它是一个通常由命令行界面使用的语句终止符或分隔符。 JDBC 4.0规范没有提到分号,但在其示例SQL中没有包含分号。 我用过Oracle和SQLServer。 Oracle提供了一个错误: ORA-00911无效字符 我的理论是SQL Server返回一个空的结果集,因为SQL字符串包含两个语句,最后一个是空的。我不确定这一点。 – richj 2009-11-04 11:07:23