[英]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.