1. 程式人生 > >java.sql.SQLException: ORA-24335: 無法支援 1000 列以 問題解決

java.sql.SQLException: ORA-24335: 無法支援 1000 列以 問題解決

前言:前段時間做了個批量插入功能,資料庫用的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的解決辦法;

  1. 對於oracle來說,本人採取的解決辦法並沒有去對資料庫配置進行修改,修改是肯定有辦法修改的,但是這個沒有太過研究,只是修改了sql進行單條插入,後臺執行了迴圈遍歷呼叫,為了提升使用者體驗把迴圈方法做成了非同步處理,可能會犧牲一些效能吧,但是考慮本身不是高併發專案也就不用那麼顧慮了。

  2. 對於mysql來說,就可以進行資料庫配置修改,語句:set GLOBAL max_allowed_packet = 4194304 修改完畢重啟客戶端即可。

附:網上很多人說換高版本資料庫,不得不說這個方法有時候靈,有時候不靈,原因是高版本資料庫可能限制不會那麼高,這種解決辦法純屬僥倖!!