为什么交叉加入横向分解阵列的SDO_GEOMETRY对象中的单个属性?
oracle 18c:
我的映射软件具有一个限制,在该软件中,每个表只能处理单个几何列。如果给定表中有多个几何列,则会丢弃错误。
因此,我想找到一种在表中添加其他几何列的方法,但是将其存储为映射软件无法识别的数据类型,因此它将忽略该列(TBD)。
一个想法是将sdo_geometry存储为 sdo_geometry_array datatype,因为该软件将无法识别SDO_GEOMETRY_ARRAY。我总是只存储一个几何形状。
类似于以下内容:
with data (geom_array) as (
select sdo_geometry_array(sdo_geometry('point(10 20)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(30 40)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(50 60)')) from dual
)
select geom_array from data
GEOM_ARRAY (SQL Developer)
----------------------------------------------
MDSYS.SDO_GEOMETRY_ARRAY([MDSYS.SDO_GEOMETRY])
MDSYS.SDO_GEOMETRY_ARRAY([MDSYS.SDO_GEOMETRY])
MDSYS.SDO_GEOMETRY_ARRAY([MDSYS.SDO_GEOMETRY])
毫不奇怪,当我从数组中选择时,它返回整个数组,而不是sdo_geometry(即使数组中只有一个值)。
因此,我想找到一个 简单/简洁 从数组中提取SDO_GEOMETRY的方法。
我可以使用一个自定义功能,该功能可以按预期工作:
with
function get_geom_from_array(geom_array sdo_geometry_array) return sdo_geometry is
begin
return geom_array(1);
end;
data (geom_array) as (
select sdo_geometry_array(sdo_geometry('point(10 20)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(30 40)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(50 60)')) from dual
)
select
get_geom_from_array(geom_array)
from
data
SDO_GEOM
---------------
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
或者我可以使用交叉加入外侧:
select
v.*
from
data d
cross join lateral (
select sdo_geometry(sdo_gtype, sdo_srid, sdo_point, sdo_elem_info, sdo_ordinates) as sdo_geom
from table(d.sdo_array)
) v
SDO_GEOM
---------------
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
那个交叉加入横向作品,但我不明白为什么它将sdo_geometry分配到其属性组件中:
select
v.*
from
data d
cross join lateral (
select *
from table(d.sdo_array)
) v
SDO_GTYPE SDO_SRID SDO_POINT SDO_ELEM_INFO SDO_ORDINATES
--------- -------- ---------------------- ------------- -------------
2001 null [MDSYS.SDO_POINT_TYPE] null null
2001 null [MDSYS.SDO_POINT_TYPE] null null
2001 null [MDSYS.SDO_POINT_TYPE] null null
因此,我需要从这些属性中重建几何形状,就像此:sdo_geometry(SDO_GTYPE,SDO_SRID,SDO_POINT,SDO_ELEM_INFO,SDO_ORDINATES)
。
重建SDO_DEOMETRY略有不便。但是,我想了解为什么在十字架上横向上会发生这种情况,而不是在自定义功能中。
问题:
为什么交叉连接到横向将数组的SDO_GEOMETRY对象分解为单个属性? (但是功能没有)
Oracle 18c:
I have mapping software that has a limitation where it can only handle a single geometry column per table. If there are multiple geometry columns in a given table, then it will throw an error.
So, I want to find a way to add an additional geometry column to a table, but store it as a datatype that the mapping software doesn't recognize — so it will ignore that column (TBD).
One idea is to store an SDO_GEOMETRY as an SDO_GEOMETRY_ARRAY datatype, since the software wouldn't recognize SDO_GEOMETRY_ARRAY. I would always only store a single geometry in the array.
Similar to this:
with data (geom_array) as (
select sdo_geometry_array(sdo_geometry('point(10 20)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(30 40)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(50 60)')) from dual
)
select geom_array from data
GEOM_ARRAY (SQL Developer)
----------------------------------------------
MDSYS.SDO_GEOMETRY_ARRAY([MDSYS.SDO_GEOMETRY])
MDSYS.SDO_GEOMETRY_ARRAY([MDSYS.SDO_GEOMETRY])
MDSYS.SDO_GEOMETRY_ARRAY([MDSYS.SDO_GEOMETRY])
Unsurprisingly, when I select from the array, it returns the entire array, not the SDO_GEOMETRY (even though there's only a single value in the array).
So, I want to find an easy/succinct way to extract the SDO_GEOMETRY from the array.
I could use a custom function, which works as expected:
with
function get_geom_from_array(geom_array sdo_geometry_array) return sdo_geometry is
begin
return geom_array(1);
end;
data (geom_array) as (
select sdo_geometry_array(sdo_geometry('point(10 20)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(30 40)')) from dual union all
select sdo_geometry_array(sdo_geometry('point(50 60)')) from dual
)
select
get_geom_from_array(geom_array)
from
data
SDO_GEOM
---------------
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
Or I could use a CROSS JOIN LATERAL:
select
v.*
from
data d
cross join lateral (
select sdo_geometry(sdo_gtype, sdo_srid, sdo_point, sdo_elem_info, sdo_ordinates) as sdo_geom
from table(d.sdo_array)
) v
SDO_GEOM
---------------
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
[MDSYS.SDO_GEOMETRY]
That CROSS JOIN LATERAL works, but I don't understand why it splits the SDO_GEOMETRY into it's attribute components:
select
v.*
from
data d
cross join lateral (
select *
from table(d.sdo_array)
) v
SDO_GTYPE SDO_SRID SDO_POINT SDO_ELEM_INFO SDO_ORDINATES
--------- -------- ---------------------- ------------- -------------
2001 null [MDSYS.SDO_POINT_TYPE] null null
2001 null [MDSYS.SDO_POINT_TYPE] null null
2001 null [MDSYS.SDO_POINT_TYPE] null null
As such, I need to reconstruct the geometry from those attributes, like this: sdo_geometry(sdo_gtype, sdo_srid, sdo_point, sdo_elem_info, sdo_ordinates)
.
Reconstructing the SDO_GEOMETRY is slightly inconvenient. But also, I want to understand why that happens in the CROSS JOIN LATERAL, but not in the custom function.
Question:
Why does the CROSS JOIN LATERAL break up the array's SDO_GEOMETRY object into individual attributes? (but the function doesn't)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
交叉加入横向
正在对待表收集表达式,就像它是一个对象衍生的表(有效的是),并使用集合的每个对象形成行表,然后列是对象的属性。该功能将一个对象返回到一行的一列中。它们是非常不同的操作。
如果要获取从表集合表达式组成每一行的对象,请使用
value
函数:db<>>
CROSS JOIN LATERAL
is treating the table collection expression as if it is an object-derived table (which it effectively is) and uses each object of the collection to form a row of a table and then the columns are the attributes of the object.The function is returning a single object into one column of one row. They are very different operations.
If you want to get the objects that comprise each row from the table collection expression then use the
VALUE
function:db<>fiddle here