首批通过分布式安全可靠测评,为关键业务系统打造
查询计算函数
更新时间:2026-07-15 20:42:46
OceanBase 数据库 Oracle 模式支持通过 SDO_GEOMETRY 类型的四个成员函数查询 SDO_GEOMETRY 空间对象的维度、类型以及有效性信息;同时支持通过 SDO_GEOM 包中的函数 SDO_DISTANCE() 和其他函数 SDO_RELATE() 来计算空间对象的距离和关系信息。
SDO_GEOMETRY 类型
GET_DIMS() 和 ST_COORDDIM()
GET_DIMS() 和 ST_COORDDIM() 函数用于获取空间对象的维度(即几何对象的坐标数)。例如,对于二维对象,维度为 2;对于三维对象,维度为 3。
示例如下:
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).GET_DIMS() AS test_get_dims FROM dual;
返回结果如下:
+---------------+
| TEST_GET_DIMS |
+---------------+
| 2 |
+---------------+
1 row in set
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).ST_COORDDIM() AS test_st_coorddim FROM dual;
返回结果如下:
+------------------+
| TEST_ST_COORDDIM |
+------------------+
| 2 |
+------------------+
1 row in set
GET_GTYPE()
GET_GTYPE() 用于获取空间对象的几何类型代码。几何类型代码是一个整数值,表示特定类型的几何对象,例如点、线、多边形等。
示例如下:
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).GET_GTYPE() AS test_get_gtype FROM dual;
返回结果如下:
+----------------+
| TEST_GET_GTYPE |
+----------------+
| 1 |
+----------------+
1 row in set
ST_ISVALID()
ST_ISVALID() 用于检查空间对象是否是有效的几何对象。如果对象是有效的,函数将返回 1;否则,返回 0。
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).ST_ISVALID() AS test_st_isvalid FROM dual;
返回结果如下:
+-----------------+
| TEST_ST_ISVALID |
+-----------------+
| 1 |
+-----------------+
1 row in set
SDO_GEOM 包
SDO_DISTANCE()
SDO_DISTANCE() 用于计算两个空间几何对象之间的最小距离。例如二维参数 geom1 和二维参数 geom2 之间的最小距离。
SELECT SDO_GEOM.SDO_DISTANCE(SDO_GEOMETRY('POINT(0 0)', 4326), SDO_GEOMETRY('POINT(0.01 0)', 4326)) FROM dual;
返回结果如下:
+-----------------------------------------------------------------------------------------+
| SDO_GEOM.SDO_DISTANCE(SDO_GEOMETRY('POINT(00)', 4326),SDO_GEOMETRY('POINT(0.010)',4326)) |
+-----------------------------------------------------------------------------------------+
| 1113.1949077920626 |
+-----------------------------------------------------------------------------------------+
1 row in set
SDO_AREA()
说明
该函数从 V4.3.5 BP5 版本开始支持。
SDO_AREA() 用于计算一个几何对象的平面面积,返回值单位与几何所处 SRS 的线性单位一致;不进行球面/椭球面换算。仅支持 2D 平面几何,3D 输入不支持。
语法如下:
SDO_GEOM.SDO_AREA(geom[, tolerance])
geom表示几何对象。tolerance可选项,默认值为NULL。表示面积计算的容差,用于控制计算精度。
返回值为 NUMBER 类型数据,表示几何对象的平面面积,单位与几何所处 SRS 的线性单位一致。
示例如下:
SELECT SDO_GEOM.SDO_AREA(
SDO_GEOMETRY('POLYGON((0 0, 3 0, 3 4, 0 4, 0 0))'),0.005)
) AS area FROM dual;
返回结果如下:
+------+
|| AREA |
+------+
|| 12 |
+------+
1 row in set
空间关系判断函数
SDO_CONTAINS()
说明
该函数从 V4.3.5 BP5 版本开始支持。
该函数用于判断一个几何对象是否严格包含另一个几何对象,例如 geomA 是否严格包含 geomB(边界点不视为包含)。等价于 SDO_RELATE(geomA, geomB, 'mask=CONTAINS'),逻辑等价关系:Contains(A, B) ⇔ Within(B, A)。
语法如下:
SDO_CONTAINS(geomA, geomB)
geomA表示几何对象 A。geomB表示几何对象 B。
返回值为 BOOLEAN 类型数据:TRUE/FALSE/NULL(空输入几何对象返回 NULL)。注意,SDO_CONTAINS 为严格包含,边界点返回 FALSE。
示例如下:
SELECT SDO_CONTAINS(
SDO_GEOMETRY('POLYGON((0 0,10 0,10 10,0 10,0 0))', 4326),
SDO_GEOMETRY('POINT(5 5)', 4326)
) AS res FROM dual;
返回结果如下:
+------+
|| RES |
+------+
|| TRUE |
+------+
1 row in set
SDO_ANYINTERACT()
说明
该函数从 V4.3.5 BP5 版本开始支持。
该函数用于判断一个几何对象是否与另一个几何对象有任何形式的空间交集,例如相交、接触、重叠等,边界接触视为交互。等价于 SDO_RELATE(..., 'mask=ANYINTERACT')。
语法如下:
SDO_ANYINTERACT(geomA, geomB)
geomA表示几何对象 A。geomB表示几何对象 B。
返回值为 BOOLEAN 类型数据:TRUE/FALSE/NULL(空输入几何对象返回 NULL)。
示例如下:
SELECT SDO_ANYINTERACT(
SDO_GEOMETRY('LINESTRING(0 0,10 10)', 4326),
SDO_GEOMETRY('LINESTRING(0 10,10 0)', 4326)
) AS res FROM dual;
返回结果如下:
+------+
|| RES |
+------+
|| TRUE |
+------+
1 row in set
SDO_RELATE()
SDO_RELATE() 用于确定对象是否符合指定空间关系。
注意事项如下:
- 空间关系运算目前仅支持
ANYINTERACT。 - 如果参数
geom1和geom2基于不同的坐标系,geom2则会报错。 - 当用作索引查询时,
SDO_RELATE()必须在WHERE子句中使用SDO_RELATE(geometry1, geometry2, 'mask = <some_mask_val>') = 'TRUE'形式的函数表达式,且geometry1必须是索引列。
索引查询示例如下:
-- 创建测试表 test_spatial_index
CREATE TABLE test_spatial_index (fid INTEGER NOT NULL PRIMARY KEY, g SDO_GEOMETRY NOT NULL SRID 4326 );
-- 插入几条测试数据
INSERT INTO test_spatial_index VALUES(1, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10 50, null), null, null));
INSERT INTO test_spatial_index VALUES(2, SDO_GEOMETRY(2001, 4326, null, SDO_ELEM_INFO_ARRAY (1,1,1), SDO_ORDINATE_ARRAY (10,50)));
INSERT INTO test_spatial_index VALUES(3, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234,50.567,null), null, null));
INSERT INTO test_spatial_index VALUES(4, SDO_GEOMETRY(2001, 4326, null, SDO_ELEM_INFO_ARRAY (1,1,1), SDO_ORDINATE_ARRAY (10.1234,50.567)));
INSERT INTO test_spatial_index VALUES(5, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234,50.567,null), null, null));
-- 创建空间索引 idx
CREATE INDEX idx ON test_spatial_index(g) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
-- 索引查询
SELECT * FROM test_spatial_index WHERE SDO_RELATE(g, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234,50.567,null), null, null), 'querytype=WINDOW mask=anyinteract') = 'TRUE';
返回结果如下:
+------+-----------------------------------------------------------------------------+
| FID | G |
+------+-----------------------------------------------------------------------------+
| 3 | SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234, 50.567, NULL), NULL, NULL) |
| 4 | SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234, 50.567, NULL), NULL, NULL) |
| 5 | SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234, 50.567, NULL), NULL, NULL) |
+------+-----------------------------------------------------------------------------+
3 rows in set
执行计划如下,使用了 idx 索引进行访问:
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| -------------------------------------------------------------------- |
| |0 |TABLE FULL SCAN|TEST_SPATIAL_INDEX(IDX)|1 |135 | |
| ====================================================================
SDO_UTIL 包
GETVERTICES()
说明
该函数从 V4.3.5 BP5 版本开始支持。
该函数用于获取一个几何对象的顶点坐标,支持 2D/3D:
- 2D 几何
Z=NULL。 - 3D 几何返回实际
Z值,W始终NULL。
语法如下:
TABLE(SDO_UTIL.GETVERTICES(geom))
- 调用时需使用
TABLE(...)形式展开嵌套表。 geom表示几何对象。
返回嵌套表 VERTEX_SET_TYPE,每行一个顶点,包含 X/Y/Z/W 及保留列:
# X,Y,Z,W 为顶点坐标,V1..V11 为保留列,用于后续扩展
# ID 为顶点 ID,从 1 开始递增
X,Y,Z,W,V1..V11,ID
示例如下:
SELECT v.id, v.x, v.y, v.z
FROM TABLE(
SDO_UTIL.GETVERTICES(
SDO_GEOMETRY(
3002, -- 3002 = 三维线 (3D LineString)
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,2,1),
SDO_ORDINATE_ARRAY(
10, 10, 5, -- 第一个点 X=10,Y=10,Z=5
20, 20, 6, -- 第二个点
30, 10, 7 -- 第三个点
)
)
)
) v;
返回结果如下:
+------+------+------+------+
|| ID | X | Y | Z |
+------+------+------+------+
|| 1 | 10 | 10 | 5 |
|| 2 | 20 | 20 | 6 |
|| 3 | 30 | 10 | 7 |
+------+------+------+------+
3 rows in set