需求:
使用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
