为什么我们需要将()mdsy.st_ geometry视为st_linestring使用st_pointn(1)?

发布于 2025-02-08 12:48:20 字数 1053 浏览 1 评论 0原文

mdsys.st_geometry; Oracle 18C:


以下查询作品。它从mdsys.st_ geometry中提取第一个点:

--Source: https://www.spdba.com.au/using-oracles-st_geometry-type-hierarchy-with-sdo_geometry-st_pointn-and-st_numpoints/

with    cte as (
select  treat(mdsys.st_geometry.from_wkt('LINESTRING(10 10, 20 20)',26917) as mdsys.st_linestring) as shape
from    dual
)
select 
    (shape).st_pointn(1) as first_point
from 
    cte

Result:
MDSYS.ST_POINT(MDSYS.SDO_GEOMETRY(2001, 26917, MDSYS.SDO_POINT_TYPE(10, 10, NULL), NULL, NULL))

我不明白为什么我们需要treat() st_geometry supertype作为st_linestring subtype,以便使用st_pointn()要明白。

例如,如果我删除处理(...作为st_linestring),那么我会遇到一个错误:

with    cte as (
select  mdsys.st_geometry.from_wkt('LINESTRING(10 10, 20 20)',26917) as shape
from    dual
)
select 
    (shape).st_pointn(1) as first_point
from 
    cte

Error:
ORA-00904: "MDSYS"."ST_GEOMETRY"."ST_POINTN": invalid identifier

为什么删除treat()时,为什么会遇到该错误?

MDSYS.ST_GEOMETRY; Oracle 18c:


The following query works. It extracts the first point from an MDSYS.ST_GEOMETRY:

--Source: https://www.spdba.com.au/using-oracles-st_geometry-type-hierarchy-with-sdo_geometry-st_pointn-and-st_numpoints/

with    cte as (
select  treat(mdsys.st_geometry.from_wkt('LINESTRING(10 10, 20 20)',26917) as mdsys.st_linestring) as shape
from    dual
)
select 
    (shape).st_pointn(1) as first_point
from 
    cte

Result:
MDSYS.ST_POINT(MDSYS.SDO_GEOMETRY(2001, 26917, MDSYS.SDO_POINT_TYPE(10, 10, NULL), NULL, NULL))

I don't understand why we need to Treat() the ST_GEOMETRY supertype as an ST_LINESTRING subtype in order to use ST_PointN() to get the point.

For example, if I remove the Treat(... as ST_LINESTRING), then I get an error:

with    cte as (
select  mdsys.st_geometry.from_wkt('LINESTRING(10 10, 20 20)',26917) as shape
from    dual
)
select 
    (shape).st_pointn(1) as first_point
from 
    cte

Error:
ORA-00904: "MDSYS"."ST_GEOMETRY"."ST_POINTN": invalid identifier

Why do I get that error when I remove Treat()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

安人多梦 2025-02-15 12:48:21

当我删除Treat()

时,为什么我会收到该错误

  • ST_LINESTRINGst_curve的子类型,而ST_CURVE 又是st_geometry的子类型。
  • st_pointn是在子类型上声明的成员函数st_curvest_linestring继承此功能。
  • st_pointn在父级 st_geometry 上未声明为成员函数。
  • st_geometry.from_wkt()函数返回st_geometry实例,在这种情况下,实际上是st_linestring sub-type,但返回类型的返回类型该函数为st_ geometry,因为它可以返回任何子类子类型。

当您删除treat()时,您将尝试调用st_pointn在父级类型上st_geometry和,如错误消息陈述代码>“ mdsys”。“ st_geometry”。“ st_pointn” 是无效的标识符,因为该类型没有该成员函数。

当您包括Treat()时,将超级类型投放到子类型,然后在该子类型上调用成员函数,并且确实存在成员函数,以便它可以正常工作。


一个类似的示例是:

CREATE TYPE parent_type IS OBJECT (
 x NUMBER,
 y NUMBER
) NOT FINAL;

CREATE TYPE child_type UNDER parent_type (
  MEMBER FUNCTION get_x RETURN NUMBER
);

CREATE TYPE BODY child_type IS
  MEMBER FUNCTION get_x RETURN NUMBER
  IS
  BEGIN
    RETURN self.x;
  END;
END;
/

然后:

CREATE FUNCTION create_parent RETURN PARENT_TYPE
IS
BEGIN
  RETURN child_type(1, 2);
END;
/

如果使用:

SELECT create_parent().get_x() FROM DUAL;

然后函数声明其返回parent_type,则在该类型上调用成员函数,即使实际返回的值是child> child> child_type < /code>,因此提出错误:

  ora-00904:“ schema_name”。“ parent_type”。“ get_x”:无效的标识符
 

如果您使用治疗将返回的父送到其实际子类型:

SELECT TREAT(create_parent() AS child_type).get_x() FROM DUAL;

输出为:

treat(create_parent()aschild_type).get_x()
1

db&lt;

Why do I get that error when I remove Treat()?

  • ST_LINESTRING is a sub-type of ST_CURVE which, in turn, is a sub-type of ST_GEOMETRY.
  • ST_POINTN is a member function declared on the sub-type ST_CURVE and ST_LINESTRING inherits this function.
  • ST_POINTN is not declared as a member function on the parent type ST_GEOMETRY.
  • The ST_GEOMETRY.FROM_WKT() function returns an ST_GEOMETRY instance that, in this case is a actually a ST_LINESTRING sub-type but the return type of the function is ST_GEOMETRY as it could return any child sub-type.

When you remove TREAT() then you are trying to call the ST_POINTN member function on the parent type ST_GEOMETRY and, as the error message states "MDSYS"."ST_GEOMETRY"."ST_POINTN" is an invalid identifier because the type does not have that member function.

When you include TREAT() then you cast the super-type to the sub-type and then call the member function on that sub-type and the member function does exist so it works.


A similar example is:

CREATE TYPE parent_type IS OBJECT (
 x NUMBER,
 y NUMBER
) NOT FINAL;

CREATE TYPE child_type UNDER parent_type (
  MEMBER FUNCTION get_x RETURN NUMBER
);

CREATE TYPE BODY child_type IS
  MEMBER FUNCTION get_x RETURN NUMBER
  IS
  BEGIN
    RETURN self.x;
  END;
END;
/

Then:

CREATE FUNCTION create_parent RETURN PARENT_TYPE
IS
BEGIN
  RETURN child_type(1, 2);
END;
/

If you use:

SELECT create_parent().get_x() FROM DUAL;

Then the function declares it returns a PARENT_TYPE and so the member function is called on that type, even though the actual returned value is a CHILD_TYPE, so raises the error:

ORA-00904: "SCHEMA_NAME"."PARENT_TYPE"."GET_X": invalid identifier

If you use TREAT to cast the returned parent to its actual child type:

SELECT TREAT(create_parent() AS child_type).get_x() FROM DUAL;

Then the output is:

TREAT(CREATE_PARENT()ASCHILD_TYPE).GET_X()
1

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文