【问题标题】:Why does SHAPE.SDO_ORDINATES(1) work in PL/SQL, but not in SQL?为什么 SHAPE.SDO_ORDINATES(1) 在 PL/SQL 中有效,但在 SQL 查询中无效?
【发布时间】:2022-06-10 16:57:41
【问题描述】:

甲骨文 18c:

我可以在自定义 PL/SQL 函数中使用 SHAPE.SDO_ORDINATES(1) 从 SDO_GEOMETRY 中提取起点 X 坐标:

with 
function startpoint_x(shape in sdo_geometry) return number 
is
begin
  return 
  shape.sdo_ordinates(1); 
end;

select
  startpoint_x(shape) as startpoint_x
from
  (select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape 
   from dual)

STARTPOINT_X
------------
           1

但如果我尝试仅在 SQL 查询中执行此操作,则会收到错误:

select
  (shape).sdo_ordinates(1) as startpoint_x
from
  (select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape 
   from dual)

ORA-00904: "MDSYS"."SDO_GEOMETRY"."SDO_ORDINATES": invalid identifier

对于它的价值,如果我要删除 (1) 并选择整个 sdo_ordinates 属性,那么它会起作用:

select
  (shape).sdo_ordinates as ordinates 
from
  (select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape 
   from dual)

ORDINATES
------------------------
SDO_ORDINATE_ARRAY(1, 2)

db<>fiddle

当然,这不是我想要的。我想以数字形式获取起点 X 坐标。


为什么SHAPE.SDO_ORDINATES(1) 在 PL/SQL 中有效,但在 SQL 查询中无效?

【问题讨论】:

    标签: sql oracle attributes oracle18c oracle-spatial


    【解决方案1】:

    为什么SHAPE.SDO_ORDINATES(1) 在 PL/SQL 中有效,但在 SQL 查询中无效?

    因为 SQL 不支持按索引提取集合元素的语法。它不仅仅是 SDO 对象,而是任何集合:

    SELECT SYS.ODCIVARCHAR2LIST('a', 'b', 'c')(1) FROM DUAL;
    

    输出:

    ORA-03001: unimplemented feature
    

    和:

    SELECT l.list(1)
    FROM   (SELECT SYS.ODCIVARCHAR2LIST('a', 'b', 'c') AS list FROM DUAL) l;
    

    输出:

    ORA-00904: "L"."LIST": invalid identifier
    

    (我认为这意味着它正在尝试将其解析为函数,但错误消息的帮助/明显程度不如前一个。)


    有一些获取值的方法,但它更复杂,因为您需要使用表集合表达式取消引用整个集合,然后过滤以获取所需的行:

    SELECT (
             SELECT COLUMN_VALUE
             FROM   TABLE(s.shape.sdo_ordinates)
             FETCH FIRST ROW ONLY
           ) as startpoint_x
    FROM  (
      select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape from dual
    ) s
    

    db小提琴here

    【讨论】:

    【解决方案2】:

    看看这样的解决方法是否有帮助......

    这就是你所拥有的并且它有效:

    SQL> select
      2    (shape).sdo_ordinates as ordinates
      3  from
      4    (select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape
      5     from dual);
    
    ORDINATES
    ------------------------------------------------------------
    SDO_ORDINATE_ARRAY(1, 2, 3, 4, 5, 6)
    

    这是你尝试过的,但它不起作用:

    SQL> select
      2    (shape).sdo_ordinates(1) as startpoint_x
      3  from
      4    (select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape
      5     from dual);
      (shape).sdo_ordinates(1) as startpoint_x
                           *
    ERROR at line 2:
    ORA-00904: "MDSYS"."SDO_GEOMETRY"."SDO_ORDINATES": invalid identifier
    

    这是一个解决方法

    SQL> select
      2    sdo_geom.sdo_min_mbr_ordinate(shape, 1) as startpoint_x
      3  from
      4    (select sdo_geometry('linestring(1 2, 3 4, 5 6)') as shape
      5     from dual);
    
    STARTPOINT_X
    ------------
               1
    
    SQL>
    

    【讨论】:

      【解决方案3】:

      我的猜测是 varray 和表集合必须被视为表,而 SQL (3) 在原生 SQL 中不支持它们。

      【讨论】:

        猜你喜欢
        • 2015-08-22
        • 2013-01-24
        • 1970-01-01
        • 2019-12-06
        • 1970-01-01
        • 1970-01-01
        • 2013-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多