2014-10-06 70 views
0

我必須創建一個命名查詢,我需要按照字段對結果進行分組,並使用IN子句來限制結果。IN子句與OpenJpa中的大列表導致太複雜的語句

的,它看起來像這樣

SELECT new MyDTO(e.objID) FROM Entity e WHERE e.objId IN (:listOfIDs) GROUP BY e.attr1, e.attr2 

我使用的OpenJPA和IBM DB2。在某些情況下,我的ID列表可能會非常大(> 80.000的ID),然後將生成的SQL語句變成了DB2太複雜了,因爲最後生成的語句打印出所有的ID,像這樣:

SELECT new MyDTO(e.objID) FROM Entity e WHERE e.objId IN (1,2,3,4,5,6,7,...) GROUP BY e.attr1, e.attr2 

有任何處理這種查詢的好方法?可能的解決方法是將ID寫入臨時表中,然後在此表上使用IN子句。

+0

JPA確實是爲「少數」記錄設計的(它仍然可以是很多),並且該設置的大小不是它。你在做什麼,你一次搞亂了那麼多的記錄?你可能更適合批量加載到一個表中加入(類似於現有的答案,但有一些特殊的工具)。 – 2014-10-06 11:25:53

回答

0

您應該將所有值放在一個表中,並將查詢重寫爲聯接。這不僅能解決您的查詢問題,而且應該更有效率。

declare global temporary table ids (
    objId int 
) with replace on commit preserve rows; 

--If this statement is too long, use a couple of insert statements. 
insert into session.ids values 
    (1,2,3,4,....); 

select new mydto(e.objID) 
    from entity e 
    join session.ids i on 
     e.objId = i.objId 
group by e.attr1, e.attr2; 
+0

這可以工作,但我如何訪問我的JPQL語句中的臨時表?我無法直接訪問「會話」,因爲它不被識別爲實體。 – dako 2014-10-06 10:37:30

+0

所以這似乎是最好的解決方案。我無法使用全局臨時表,但我的方法可行。我使用的是「正常」表格,並根據需要使用ID列表進行填充。 – dako 2014-10-06 14:33:14