报错:ORA-01461:仅能绑定要插入 LONG 列的 LONG 值

2019-08-29 00:00:00 报错 ora

需求:

  使用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 

 

    原文作者:磊磊哦
    原文地址: https://www.cnblogs.com/crius-dlz/p/11425310.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章