通过.getRow()的ResultSet行计数给出了JDBC-ODBC和MS Access的错误答案

时间:2015-07-30 15:15:21

标签: java sql jdbc ms-access-2013 jdbc-odbc

我有一个HAM无线电数据库,我试图计算一个月内每个频段联系的国家数量(本例中为2014年3月)。我的SQL语句在MS Access数据库工具中运行得非常好,但是从我的Java程序中我得到的只是部分结果。 (我看到一个不正确的行数。)

我几天来一直在努力解决这个问题,无法让它发挥作用。

这是我的SQL:

SELECT count(*) AS cdxcc, dxcc, rfband 
FROM (SELECT  dxcc,ldate,rfband
FROM logbook) AS tmp 
where mid(logbook.ldate,4)='03.2014'
GROUP BY dxcc,rfband ORDER BY dxcc;

在MsAccess(Windows程序)中,我得到了正确的结果:

cdxcc   dxcc        rfband
5       Canada      15m
3       Canada      20m
2       England     40m
18      England     80m
1       Germany     80m
4       Poland      20m
1       Scotland    80m
1       Sweden      20m
1       USA         12m
12      USA         15m
1       Wales       60m

但是,在我的Java程序中,我只返回第一条记录中'cdxcc'计数的行数,在这种情况下为5,所以我只得到前5行,之后SQL / java错误('ResultSet已关闭')。

对于不同的月份,第一行的计数可能为1,而我只返回1条记录。作为调试,我在stackoverflow上找到了这个方便的代码,它确认了5,这是错误的。对于这个例子,正确的答案应该是11:

if (rs.last()) {
  rowcount = rs.getRow();
  rs.beforeFirst(); 
}

是否有人认识到这个问题并知道解决方案?

确实查询过于复杂,这也有效,但不幸的是结果相同:

  

SELECT count(*)AS cdxcc,dxcc,rfband,ldate FROM logbook AS tmp where   mid(ldate,4)='03.2014'GROUP BY dxcc,rfband,ldate ORDER BY dxcc;

不幸的是,同样的错误结果。

我的代码中有很多其他的SQL语句,它们都运行正常,就是这个。 java代码在这里(省略了try-catch和其他非必要代码):

private static final String accessDBURLPrefix = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=";
private static final String accessDBURLSuffix = ";DriverID=22;READONLY=false}";
String currdb=accessDBpath + logbookdb; // path and filename of .mdb file
private Statement stm = null;
private ResultSet rs=null;
private Connection dbconn = null;
String dbDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
Class.forName(dbDriver);
String dbURL = accessDBURLPrefix + currdb + accessDBURLSuffix;
dbconn = DriverManager.getConnection(dbURL,"","");
stm = dbconn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,     ResultSet.CONCUR_READ_ONLY);

// This function is called by a JSP page that contains the aforementioned query
public boolean dbQuery(String q) {
    rs = stm.executeQuery(q);

    int rowcount = 0;

    if (rs.last()) {
          rowcount = rs.getRow();
          rs.beforeFirst(); 
    }
    System.out.println("Rowcount="+ rowcount);
    return true;
}

我不是SQL专家,但我的代码中有大量的插入,更新和读取查询,访问同一个数据库,所有这些似乎都运行得很好。 不需要并发,仅限单个用户。

1 个答案:

答案 0 :(得分:1)

我能够使用JDBC-ODBC Bridge和Access ODBC驱动程序重新创建您的问题。它似乎是两者之间的不兼容,我使用UCanAccess JDBC驱动程序尝试完全相同的代码,我得到了正确的结果(" Rowcount = 11")。

JDBC-ODBC Bridge已过时,已从Java 8中删除,因此您应该考虑切换到UCanAccess。有关更多信息,请参阅

Manipulating an Access database from Java without ODBC