[英]SQL Query Will Not Execute SQLite, Java
问题摘要:尝试在Java中使用SQLite数据库执行SQL查询时,SQL语句无法从execute()或executeQuery()方法返回。 换句话说,系统在执行此SQL语句时“挂起”。
问题:我在做错什么来解释为什么ResultSet永不“返回”?
TroubleShooting我试图缩小问题的范围,而问题似乎出在Java的execute()或executeQuery()上。 ResultSet似乎永远不会返回。 例如,我尝试直接在SQLite中执行完全相同的查询(即使用SQLite数据库管理器)。 该查询(Java外部)在大约5毫秒内执行并返回有效的结果集。
注意:不会引发任何异常。 该系统似乎只是“挂起”,在手动杀死之前一直没有响应。 (等待超过10分钟。)
代码:我对代码进行了大量编辑,以使问题更易于查看。 (在生产中,这使用Prepared Statements。但是,在这两种方法中都会发生错误,即直接Statement和Prepared Statement版本。)
基本上,SELECT返回单个DB项目,以便用户可以查看该项目。
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
更新次要修订版:随着我继续对此进行处理,在SQL语句的开头添加一个MIN(d1.id)至少返回一个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 ;") ;
SQL语句多么混乱(对不起)! 我不了解SQLite,但为什么不简化为:
SELECT DISTINCT md.id, md.sourcefullfilepath, md.sourcefilepath, md.sourcefilename,
dc.classificationid, dc.classid, dc.userid
FROM MatterDataset md
LEFT JOIN DocumentClassification dc
ON dc.documentid = md.id
AND (dc.classid = 1 OR dc.classid = 2 )
AND dc.userid < 0
LEFT JOIN PrivilegeLog pl
ON md.id = pl.documentparentid
AND md.matterid = pl.matterid
WHERE pl.privilegelogitemid IS NULL
AND md.matterid = \'100\'
ORDER BY md.id LIMIT 1 ;
我不确定您是要LEFT JOIN还是INNER JOIN进行DocumentClassification(我认为,使用LEFT JOIN然后在WHERE语句中对classid和userid提出要求是矛盾的)。 如果必须存在DocumentClassification,则更改为INNER JOIN并将对classid和userid的引用放入WHERE子句中,如果结果集中可能存在或可能不存在DocumentClassification,则按照我上面的建议保留查询。
我回去,重新开始。 SQL语法虽然可以在Java外部运行,但对于JDBC驱动程序来说似乎太复杂了。 此清理的修订版似乎可以正常工作:
SELECT DISTINCT
MatterDataset.id, MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath,
MatterDataset.sourcefilename
FROM MatterDataset , DocumentClassification
ON DocumentClassification.documentid = MatterDataset.id
AND MatterDataset.matterid = DocumentClassification.matterid
LEFT JOIN PrivilegeLog ON MatterDataset.id = PrivilegeLog.documentparentid
AND MatterDataset.matterid = PrivilegeLog.matterid
WHERE PrivilegeLog.privilegelogitemid IS NULL
AND MatterDataset.matterid = '100'
AND (DocumentClassification.classid = 1 OR DocumentClassification.classid = 2)
AND DocumentClassification.userid = -99
ORDER BY MatterDataset.id LIMIT 1;
一个不错的教训:仅仅因为您可以使用SQL并不意味着您应该这样做。
该语句的作用实际上是在MatterDataset表中找到不在PrivilegeLog表中的项目。 LEFT JOIN和IS NULL语法查找“丢失”的项目。 也就是说,我想查找位于MatterDataset中但尚未在PrivilegeLog中的项目并返回这些项目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.