Oracle 18c中(SHAPE).SDO_ORDINATES(1)失败但ST_PointN(1)成功原因
Oracle 18c运行环境
在相关问题研究中已确认结论:
SQL不支持通过索引直接提取对象集合属性元素的语法。
因此使用集合索引语法编写的查询(shape).sdo_ordinates(1)会执行失败:
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
但涉及不同空间数据类型的相似查询中,形式看似相近的语法(shape).st_pointn(1)却可以成功执行:
select (shape).st_pointn(1) as startpoint from (select treat(st_geometry.from_wkt('Linestring(1 2, 3 4, 5 6)',26917) as st_linestring) as shape from dual) -- 返回结果: -- MDSYS.ST_POINT(MDSYS.SDO_GEOMETRY(2001, 26917, MDSYS.SDO_POINT_TYPE(1, 2, NULL), NULL, NULL))
现象的核心技术原因
两种写法外观高度相似,但本质是完全不同的操作,Oracle SQL解析器对二者的识别和处理逻辑完全不同:
(SHAPE).SDO_ORDINATES(1)执行失败的根因:SDO_ORDINATES是MDSYS.SDO_GEOMETRY类型的VARRAY集合类属性,本身不是成员方法。Oracle SQL引擎不支持直接通过属性名(索引)的格式访问集合属性的单个元素——这种带索引访问集合元素的写法仅在PL/SQL引擎中兼容。SQL解析器遇到括号传参的格式时,会默认判定这是成员方法调用,尝试查找SDO_GEOMETRY类型下名为SDO_ORDINATES的成员方法,查找不到就直接抛出ORA-00904无效标识符的报错。(SHAPE).ST_PointN(1)执行成功的根因:ST_POINTN根本不是属性,而是MDSYS.ST_LINESTRING类型(示例中已经通过TREAT函数将通用ST_GEOMETRY类型强转为了ST_LINESTRING子类型)自带的原生成员方法。对象实例.方法名(入参)是Oracle SQL原生支持的对象类型方法调用语法,SQL解析器可以正确识别该写法为合法的方法调用,将参数1传入方法执行后返回对应的ST_POINT类型结果,因此可以正常运行。
内容的提问来源于stack exchange,提问作者User1974
相关产品推荐
相关产品推荐

