I have an Oracle 18c table that has 15,000 rows. As a test, I’m trying to run the following query on it:
select --works for all rows: --sdo_util.to_wkbgeometry(sdo_geometry(replace(sde.st_astext(shape),'LINESTRING M','LINESTRING'))) --doesn't work for all rows (the problem is caused by: SDO_UTIL.FROM_WKBGEOMETRY() ): sdo_util.from_wkbgeometry(sdo_util.to_wkbgeometry(sdo_geometry(replace(sde.st_astext(shape),'LINESTRING M','LINESTRING')))) from my_table;
When I run that query in SQL Developer, it initially runs without errors, but that’s just because it’s only selecting the first 50 rows.
If I try to run the query on all rows (via CTRL+END), then it throws an error:
ORA-29532: Java call terminated by uncaught Java exception: java.lang.RuntimeException: oracle.spatial.util.GeometryExceptionWithContext: Byte order can only be either BIG_ENDIAN (encoded as 0) or LITTLE_ENDIAN (encoded as 1). Found encoding 65 ORA-06512: at "MDSYS.SDO_JAVA_STP", line 68 ORA-06512: at "MDSYS.SDO_UTIL", line 6244 29532. 00000 - "Java call terminated by uncaught Java exception: %s" *Cause: A Java exception or error was signaled and could not be resolved by the Java code. *Action: Modify Java code, if this behavior is not intended.
How can I determine what specific rows are causing that error?
I tried using SDO_UTIL.VALIDATE_WKBGEOMETRY() to find the problem blobs. But, surprisingly, it didn’t return any FALSE
values.
Advertisement
Answer
Create a function to wrap the call that is causing issues and catch the exception in the function:
CREATE FUNCTION test_from_wkbgeometry( v_data IN BLOB ) RETURN NUMBER IS temp SDO_GEOMETRY; BEGIN temp := sdo_util.from_wkbgeometry(v_data); RETURN 1; EXCEPTION WHEN OTHERS THEN RETURN 0; END; /
Then use it in your query:
SELECT * FROM my_table WHERE test_from_wkbgeometry( sdo_util.to_wkbgeometry( sdo_geometry(replace(sde.st_astext(shape),'LINESTRING M','LINESTRING')) ) ) = 0;
In later Oracle versions, you can define the function in the query:
WITH FUNCTION test_from_wkbgeometry( v_data IN BLOB ) RETURN NUMBER IS temp SDO_GEOMETRY; BEGIN temp := sdo_util.from_wkbgeometry(v_data); RETURN 1; EXCEPTION WHEN OTHERS THEN RETURN 0; END; SELECT * FROM my_table WHERE test_from_wkbgeometry( sdo_util.to_wkbgeometry( sdo_geometry(replace(sde.st_astext(shape),'LINESTRING M','LINESTRING')) ) ) = 0;