简体   繁体   中英

Convert MDSYS.ST_LINESTRING subtype value to MDSYS.ST_GEOMETRY supertype

This question pertains to Oracle 18c's MDSYS.ST_GEOMETRY datatype. Which is not to be confused with Esri's SDE.ST_GEOMETRY datatype).


The following query produces an MDSYS.ST_LINESTRING subtype value:

with data as (
select st_geometry.from_wkt('Linestring(1 2, 3 4, 5 6)',26917) as shape from dual)

select
    shape
from
    data
    
Result:
[MDSYS.ST_LINESTRING]

In a query, I want to convert the MDSYS.ST_LINESTRING subtype value to the MDSYS.ST_GEOMETRY supertype.

Reason: My GIS software can only handle MDSYS.ST_GEOMETRY supertype values (not MDSYS.ST_LINESTRING subtype values). I don't have control over this limitation.


I tried using the TREAT() function to make the covnersion, but it didn't seem to have an effect. The result is still the MDSYS.ST_LINESTRING subtype:

with data as (
select st_geometry.from_wkt('Linestring(1 2, 3 4, 5 6)',26917) as shape from dual)

select
    treat(shape as mdsys.st_geometry)
from
    data
  
The result is still:
[MDSYS.ST_LINESTRING] 

How can I convert the MDSYS.ST_LINSTRING subtype value to the MDSYS.ST_GEOMETRY supertype?

You do not need to as a sub-type is always an instance of a super-type (and will have all the attributes and methods inherited from the super-type).

with data (shape) as (
  select st_geometry.from_wkt('Linestring(1 2, 3 4, 5 6)',26917) from dual
)
select CASE WHEN shape IS OF(ST_GEOMETRY) THEN 'is' ELSE 'is not' END
         AS st_geometry,
       CASE WHEN shape IS OF(ST_CURVE) THEN 'is' ELSE 'is not' END
         AS st_curve,
       CASE WHEN shape IS OF(ST_LINESTRING) THEN 'is' ELSE 'is not' END
         AS st_linestring,
       CASE WHEN shape IS OF(ST_POLYGON) THEN 'is' ELSE 'is not' END
         AS st_polygon
from   data

Outputs:

ST_GEOMETRY ST_CURVE ST_LINESTRING ST_POLYGON
is is is is not

So if you have a function that takes a super-type then just pass the sub-type to it and it will accept it.

CREATE FUNCTION test_func(
  geom IN ST_GEOMETRY
) RETURN NUMBER
IS
BEGIN
  RETURN 42;
END;
/

Then:

with data (shape) as (
  select st_geometry.from_wkt('Linestring(1 2, 3 4, 5 6)',26917) from dual
)
SELECT test_func(shape) FROM data;

or:

with data (shape) as (
  select TREAT(
           st_geometry.from_wkt('Linestring(1 2, 3 4, 5 6)',26917)
           AS ST_LINESTRING
         )
  from   dual
)
SELECT test_func(shape) FROM data;

Both work as the function accepts the argument and output 42 .

db<>fiddle here

@SimonGreener pointed out that this works:

with data as (
select st_linestring.from_wkt('Linestring(1 2, 3 4, 5 6)',26917) as shape from dual)

select
    treat(st_geometry(a.shape.geom) as mdsys.st_geometry) as shape
from
    data a


SHAPE
--------------
[MDSYS.ST_GEOMETRY]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM