问题概要: 当尝试在 Java 中使用 SQLite 数据库执行 SQL 查询时,SQL 语句无法从 execute() 或 executeQuery() 方法返回。换句话说,系统在执行这条 SQL 语句时“挂起”。
问题: 我在解释为什么 ResultSet 永远不会“返回”时做错了什么?
故障排除 我试图缩小问题范围,问题似乎出在 Java 的 execute() 或 executeQuery() 上。ResultSet 似乎永远不会返回。例如,我尝试直接在 SQLite 中执行完全相同的查询(即使用 SQLite DB 管理器)。查询(在 Java 之外)在大约 5 毫秒内执行并返回有效的结果集。
注意:不会引发异常。该系统似乎只是“挂起”并且在手动杀死之前变得无响应。(等待超过 10 分钟。)
代码: 我对这段代码进行了大量编辑,以使问题更易于查看。(在生产中,这使用准备好的语句。但是,错误发生在两种方法中——直接声明和准备好的声明版本。)
基本上,SELECT 返回单个数据库项目,以便用户可以查看该项目。
Statement st = conn.createStatement() ;
ResultSet rs = st.executeQuery("SELECT DISTINCT d1.id, d1.sourcefullfilepath, " +
"d1.sourcefilepath, d1.sourcefilename, d1.classificationid, d1.classid, " +
"d1.userid FROM MatterDataset, (SELECT MatterDataset.id, " +
"MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath, " +
"MatterDataset.sourcefilename, MatterDataset.matterid , " +
"DocumentClassification.classificationid, DocumentClassification.classid," +
" DocumentClassification.userid FROM MatterDataset " +
"LEFT JOIN DocumentClassification ON " +
"DocumentClassification.documentid = Matterdataset.id " +
"WHERE ( DocumentClassification.classid = 1 OR " +
"DocumentClassification.classid = 2 ) AND " +
"DocumentClassification.userid < 0 AND " +
"MatterDataset.matterid = \'100\' ) AS d1 " +
"LEFT JOIN PrivilegeLog ON " +
"d1.id = PrivilegeLog.documentparentid AND " +
"d1.matterid = PrivilegeLog.matterid " +
"WHERE PrivilegeLog.privilegelogitemid IS NULL " +
"AND MatterDataset.matterid = \'100\' " +
"ORDER BY d1.id LIMIT 1 ;") ;
配置: Java 6、JDBC 驱动程序 = Xerial sqlite-jdbc-3.7.2、SQLite 3、Windows
更新 次要修订:当我继续使用此功能时,将 MIN(d1.id) 添加到 SQL 语句的开头至少会返回一个 ResultSet(而不是“挂起”)。但是,这并不是我真正想要的,因为 MIN 消除了 LIMIT 函数。
Statement st = conn.createStatement() ;
ResultSet rs = st.executeQuery("SELECT DISTINCT MIN(d1.id), d1.id,
d1.sourcefullfilepath, " +
"d1.sourcefilepath, d1.sourcefilename, d1.classificationid, d1.classid, " +
"d1.userid FROM MatterDataset, (SELECT MatterDataset.id, " +
"MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath, " +
"MatterDataset.sourcefilename, MatterDataset.matterid , " +
"DocumentClassification.classificationid, DocumentClassification.classid," +
" DocumentClassification.userid FROM MatterDataset " +
"LEFT JOIN DocumentClassification ON " +
"DocumentClassification.documentid = Matterdataset.id " +
"WHERE ( DocumentClassification.classid = 1 OR " +
"DocumentClassification.classid = 2 ) AND " +
"DocumentClassification.userid < 0 AND " +
"MatterDataset.matterid = \'100\' ) AS d1 " +
"LEFT JOIN PrivilegeLog ON " +
"d1.id = PrivilegeLog.documentparentid AND " +
"d1.matterid = PrivilegeLog.matterid " +
"WHERE PrivilegeLog.privilegelogitemid IS NULL " +
"AND MatterDataset.matterid = \'100\' " +
"ORDER BY d1.id LIMIT 1 ;") ;