2016-04-01 43 views
2

這是what myBATIS has on their own documentation for foreachmyBATIS foreach命中限制爲1000

<select id="selectPostIn" resultType="domain.blog.Post"> 
    SELECT * 
    FROM POST P 
    WHERE ID in 
    <foreach item="item" index="index" collection="list" 
     open="(" separator="," close=")"> 
     #{item} 
    </foreach> 
</select> 

但是,如果list包含超過1000個項目,你正在使用Oracle數據庫,你得到這個異常:

java.sql.SQLSyntaxErrorException: ORA-01795: maximum number of expressions in a list is 1000 

我能做些什麼來解決這個問題,以便它可以與超過1000元?

+0

[ora-01795](https://stackoverflow.com/questions/17842453/is-there-a-workaround-for-ora-01795-maximum-number-of-expressions-in-a-list-is )看看這個,可以幫助你。 – BobJiang

回答

3

我不知道這是否是最好的解決方法還是不行,但這裏是我所做的:

<select id="selectPostIn" resultType="domain.blog.Post"> 
    SELECT * 
    FROM POST P 
    WHERE ID in 
    <trim suffixOverrides=" OR ID IN()"> 
     <foreach item="item" index="index" collection="list" 
       open="(" close=")"> 
      <if test="index != 0"> 
       <choose> 
        <when test="index % 1000 == 999">) OR ID IN (</when> 
        <otherwise>,</otherwise> 
       </choose> 
      </if> 
      #{item} 
     </foreach> 
    </trim> 
</select> 

說明

讓我們開始與foreach。我們想圍繞它在()。大多數元素我們都要逗號,除了每一千個元素我們想要停止列表和OR與另一個。這就是choose,when,otherwise構造句柄。除了我們不希望在第一個元素之前的那些,因此choose所在的if。最後,foreach以實際插入#{item}結束。

trim僅僅是這樣,如果我們恰好有1000個元素,例如,我們不OR ID IN()這將是無效的(()結束,具體而言,是無效的一部分。這是在SQL語法錯誤,不。一個空表像我希望的那樣)

+1

偉大的解決方案和解釋!謝謝,它幫助了很多。 –

0

我們試圖刪除查詢條款更多然後1000條記錄與上述參考:

<delete id="delete" parameterType="Map"> 

下面的查詢工作:

DELETE FROM Employee 
where 
emp_id = #{empId} 
    <foreach item="deptId" index= "index" collection="ids" open="AND DEPT_ID NOT IN (" close=")" > 
     <if test="index != 0"> 
     <choose> 
        <when test="index % 1000 == 999">) AND DEPT_ID NOT IN (</when> 
        <otherwise>,</otherwise> 
       </choose> 
      </if> 
    #{deptId} 
</foreach> 
</delete> 
+0

我想你錯過了一個'trim',因爲我的答案中有這個。如果沒有'trim',只要您的集合的長度是1000的精確倍數(查詢將以'AND DEPT_ID NOT IN()' - '()'結尾將引發語法錯誤在Oracle中)。 – ArtOfWarfare