You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle18c列子查询取SDO_GEOMETRY第二坐标返回空原因咨询

原因说明

这是Oracle ROWNUM伪列的固有运行逻辑导致的,和SDO_GEOMETRY本身的坐标存储逻辑无关:

  • ROWNUM是Oracle逐行从结果集取数据时临时分配的序号,永远给当前取出的第一行分配1,只有第一行被保留、成功返回之后,才会给下一行分配2,后续序号以此类推。
  • 当你在子查询里写WHERE ROWNUM = 2时,执行逻辑是这样的:
    1. 取出坐标数组的第一个值,给它分配ROWNUM=1
    2. 判断ROWNUM=2条件不成立,这行被丢弃
    3. 继续取数组里的下一个值,这时候它成了当前结果集的第一行,还是被分配ROWNUM=1
    4. 条件依旧不成立,继续丢弃,循环到数组结束也没有符合条件的行,最终子查询返回空,外层拿到的就是null。
  • 而ROWNUM=1能正常运行,是因为取出第一个值时分配的行号刚好满足条件,直接返回即可,不会出现行号永远到不了2的问题。

你备注里提到的FETCH FIRST ROW ONLY行为不符合预期,也是同一个原因:没有额外嵌套子查询固定行号的话,优化器会直接把取数逻辑下推,不会按你预想的先展开全量坐标再偏移取数。

正确写法

要拿到固定位置的坐标值,需要先嵌套一层子查询,给展开后的所有坐标按顺序分配好连续行号,再按行号筛选,示例如下:

with cte as (
select sdo_geometry(2002, 26917, null, sdo_elem_info_array(1, 2, 1), sdo_ordinate_array( 1, 2,  3, 4              )) shape from dual union all
select sdo_geometry(2002, 26917, null, sdo_elem_info_array(1, 2, 1), sdo_ordinate_array( 5, 6,  7, 8,  9,10       )) shape from dual union all
select sdo_geometry(2002, 26917, null, sdo_elem_info_array(1, 2, 1), sdo_ordinate_array(11,12, 13,14, 15,16, 17,18)) shape from dual)

select 
    (select ord
     from (
        select column_value ord, rownum rn
        from table((shape).sdo_ordinates)
     )
     where rn = 2
    ) startpoint_y
from 
    cte

执行后会返回你预期的结果:

STARTPOINT_Y
------------
           2
           6
          12

补充说明:直接查询table((shape).sdo_ordinates)时,返回值的顺序和你写入SDO_ORDINATE_ARRAY时的顺序完全一致,不需要额外加排序字段,只要正确分配行号就能拿到对应位置的坐标。你提到的cross join table(sdo_util.getvertices(shape))的方案,本质也是先把全量顶点展开为行集再做筛选,和上面修正后的逻辑是一致的。


内容的提问来源于stack exchange,提问作者User1974

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:03:34