java.sql.SQLException: ORA-24335: 無法支援 1000 列以 問題解決
阿新 • • 發佈:2018-12-16
前言:前段時間做了個批量插入功能,資料庫用的Oracle當時只寫了10來個測試資料沒問題就沒管,但是今天轉正式資料時(正式資料804條)發現批量插入報錯java.sql.SQLException: ORA-24335: 無法支援 1000 列以上,以下為問題復現、原因、解析和解決,特此記錄。 復現:mybatis語句如下
<insert id="insertSeats" parameterType="java.util.List"> insert all <iterate conjunction=" "> into CONFERENCE_SEAT (ID, CONFERENCEID, SEQ, SEATNO, NAME, OFFICE, TYPE) values <![CDATA[ (#list[].ID:VARCHAR#, #list[].CONFERENCEID:VARCHAR#, #list[].SEQ:VARCHAR#, #list[].SEATNO:VARCHAR#, #list[].NAME:VARCHAR#, #list[].OFFICE:VARCHAR#, #list[].TYPE:VARCHAR#) ]]> </iterate> select * from dual </insert>
原因:插入的引數或語句欄位超長。 解釋:首先導致報錯的原因跟mybatis無關,而是跟資料庫有關,再看報錯資訊“無法支援 1000 列以上”,這裡的“列”並不是值得資料庫中表的列,不同資料庫不一樣,以下列出三種為例:
1.Oracle:該資料庫大多規定所執行批量插入的引數不能超過1000(這個限制不同版本可能不同);可以看出復現sql中一次插入了7個,所以其實再插入第143條資料的時候就超過限制丟擲異常。 2.SQLServer:該資料庫規定同Oracle一樣,也是對引數個數進行了限制,引數限制基本上也是1000,超過個數SQLServer的JDBC包會丟擲異常。 3.Mysql:該資料庫為最常用資料庫,對批量插入也有限制,但是限制跟以上兩個資料不同,該資料庫限制的是字元大小,以我目前用的mysql5.0版本為例,可以用select @@max_allowed_packet 查詢一下,我的顯示1048576 也就是1M,也就是說假設執行批量插入一條資料的語句的sql如果字元長度達到1024,在執行第1025次迴圈插入時就會丟擲異常。
解決:這裡說下Oracle 和Mysql的解決辦法;
-
對於oracle來說,本人採取的解決辦法並沒有去對資料庫配置進行修改,修改是肯定有辦法修改的,但是這個沒有太過研究,只是修改了sql進行單條插入,後臺執行了迴圈遍歷呼叫,為了提升使用者體驗把迴圈方法做成了非同步處理,可能會犧牲一些效能吧,但是考慮本身不是高併發專案也就不用那麼顧慮了。
-
對於mysql來說,就可以進行資料庫配置修改,語句:set GLOBAL max_allowed_packet = 4194304 修改完畢重啟客戶端即可。
附:網上很多人說換高版本資料庫,不得不說這個方法有時候靈,有時候不靈,原因是高版本資料庫可能限制不會那麼高,這種解決辦法純屬僥倖!!