報錯:ORA-01461:僅能綁定要插入 LONG 列的 LONG 值


需求:

  使用JDBC運用 ArcGIS的ST_LineString 存取函數插入ArcGIS數據(空間數據)到Oracle數據庫。

前期工作:

  建表:CREATE TABLE lines_test ( id smallint, geometry sde.st_geometry ); //示例

  拼裝數據:

  通過ArcGIS的官方api 拼裝:sde.st_linestring (wkt clob, srid integer) 格式的數據。作為一個sql語句體的一部分存入到 geometry 字段中,也就是空間數據了。

問題:

  sde.st_linestring( string ,srid integer)當參數為string 時,

1     INSERT INTO LINES_TEST (id, geometry) VALUES (
2     1901,
3     sde.st_linestring ('linestring (750 150, 750 750)', 4326)
4     );

經過測試 'linestring (750 150, 750 750)' --string類型,即為通過生成的點坐標集合拼接所需格式。根據官方文檔,string 的 length() 是有限制的,但是官方並未說明大小限制。經測試,大約拼接的 string 數據長度超過3500左右,會報錯 ORA-01461:僅能綁定要插入 LONG 列的 LONG 值。所以當你插入的 string 的長度在3500以內時是可以正常插入的。

解決思路(百度大佬們的)

基本為以下幾種:

  1、插入到字符串長度大於4000字節。
  2、插入到表中的記錄的某個字段數據的實際長度大於2000個字節(如果是UTF-8,則是1333個字節);或者是插入的記錄中有兩個或兩個以上長度大於2000字節的字符串。
  3、數據庫與客戶端的JDBC驅動不匹配。

解決:

  因為我的驅動為ojdbc6.jar,所以驅動肯定沒問題。基本上就在長度過長的問題上了。

  采用預編譯sql操作:PrepareStatement,通過占位符插入參數插入空間數據:

1 //set sde.st_linestring ( ? ,4326)語句中的參數。
2 if (point.length() > 3500) {
3 //長度超過ArcGis函數sde.st_linestring限制,通過setCharacterStream方法,通過流的形式,寫入到數據庫。避免轉成oracle的CLOB的問題。
4      Reader clobReader = new StringReader(point); 
5      sm.setCharacterStream(11, clobReader);
6 }else {
7 //未超過限制,可以使用String類型插入,提高效率
8      sm.setString(11, point.toString());
9 }

注意:

 setCharacterStream是把給定的參數設置給Reader對象,當將一個非常大的Unicode值輸入Longvarchar參數時,通過java.io.Reader對象發送它可能更有效,這一過程將根據需要從流中讀取數據,一直讀取到文件末尾。JDBC驅動程序將執行從Unicode到數據庫char格式的任何必要轉換。

如果流長度與 length 參數指定的長度不同,則 JDBC 驅動程序將在更新或插入行時引發異常 。如下:

  測試1:剛開始我指定了流的長度 sm.setCharacterStream(11, clobReader,point.length()); 也會報錯 ORA-01461:僅能綁定要插入 LONG 列的 LONG 值。

  測試2:不考慮參數長度,改成 sm.setCharacterStream(11, clobReader,-1); 報錯:java.lang.NegativeArraySizeException 

  測試3:通過sm.setCharacterStream另一個重載的方法,無長度參數,測試,成功。

 

如有問題,歡迎指正。新人駕到,請多關照。滑稽.jpg 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM