Oracle Spatial 问题:可以使用另一个 Oracle table 的查询结果填充 SDO_ORDINATE_ARRAY 吗?
Oracle Spatial question: can SDO_ORDINATE_ARRAY be populated using query results from another Oracle table?
我的业务发展目标是使用 Oracle Spatial 来存储我们的坐标数据。目前,我们从在海洋区域进行测量的科学家那里收到坐标,这些坐标作为点的数字对或多边形的长 varchar 数组存储在我们的 Oracle 数据库中。但是,我们希望通过使用 Oracle Spatial 改进我们对这些数据的管理。
我们从科学家那里获得的坐标信息通常以 CSV 文件的形式出现,附加数据并作为字段中的条目加载到 Oracle tables 中。
我知道我可以手动将顶点输入 SDO_ORDINATE_ARRAY,但我们通常会在一个 CSV 文件中提供数百个坐标对,这使得手动路线非常低效。
有人可以告诉我是否有办法通过从已存储的数据库中的其他 table 中提取信息来填充 SDO_ORDINATE_ARRAY 的内容?
下面是我尝试过的示例:
测试 table 称为 GEOMTEST
包含由...组成
名称 varchar2(50)
坐标 varchar2(4000)
COORD_GEOM SDO_GEOMETRY
我在名称中填入了英国威尔士的感兴趣区域 'Cardigan Bay'。
COORDS 是我的多边形,以数组形式存储在 varchar2 中。这是从 CSV 文件导入的。
COORD_GEOM是我想把COORDS的内容转进去的
我尝试 运行 这段代码但收到错误:
插入 geomtest (coord_geom) 值(SDO_GEOMETRY(2003,4326,null,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY 值(select 来自 geomtest 的坐标));
我正在使用 Toad 作为我的客户端,错误是“错误:第 18 行,第 120 列,第 18 行结束,第 125 列:找到 'values':保留字不能用作标识符。
我认为这与我在 INSERT 语句的 SDO_ORDINATE_ARRAY 部分中使用 select 语句有关,但不确定如何进行。
如有任何建议,我将不胜感激,
非常感谢
肖恩
不幸的是,您不能直接将包含数字的字符串传递给 SDO_ORDINATE_ARRAY
构造函数。一种解决方案是编写自定义字符串分词器函数,将坐标字符串解析为单独的数字,并构建一个 SDO_ORDINATE_ARRAY
对象。这是一个:
create or replace function tokenize (str clob)
return sdo_ordinate_array
is
s clob := str||',';
i number;
j number;
t sdo_ordinate_array := sdo_ordinate_array();
begin
i := 1;
loop
j := instr(s, ',', i);
exit when j = 0;
t.extend();
t(t.count) := to_number(substr(s,i,j-i));
i := j+1;
end loop;
return t;
end;
/
show errors
这是它的工作原理。首先让我们用几个例子创建一个简单的 table:
drop table geomtest purge;
create table geomtest (
id number,
name varchar2(50 char),
coords clob,
coord_geom sdo_geometry
);
insert into geomtest (id, name, coords)
values (
2686,
'TX/Mitchell',
'-101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592'
);
insert into geomtest (id, name, coords)
values (
2769,
'TX/Yoakum',
'-103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332'
);
commit;
然后让我们使用分词器函数来更新几何列:
update geomtest
set coord_geom = sdo_geometry(2003,4326,null,sdo_elem_info_array(1,1003,1),tokenize(coords));
commit;
查看结果:
SQL> select * from geomtest;
ID NAME COORDS COORD_GEOM(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
---- ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2686 TX/Mitchell -101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592 SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592))
2769 TX/Yoakum -103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332 SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332))
2 rows selected.
注释
我使用 CLOB
列来存储坐标。一个 4000 字节的字符串太小,无法容纳任何严肃的几何图形(除非你所有的形状都非常简单——只有几个点)。
如果进行这种字符串到几何的转换,有更有效的方法,但它们意味着您使用面向几何的字符串表示法:GeoJSON、WKT、GML。 Oracle 自然支持这些。它们还允许更复杂的结构,例如多边形或带孔的多边形。
编辑: 我将函数重写为直接 return 一个 SDO_GEOMETRY
对象。这使得它更容易使用:
create or replace function string_to_geom (str clob)
return sdo_geometry
is
s clob := str||',';
i number;
j number;
t sdo_ordinate_array := sdo_ordinate_array();
begin
i := 1;
loop
j := instr(s, ',', i);
exit when j = 0;
t.extend();
t(t.count) := to_number(substr(s,i,j-i));
i := j+1;
end loop;
return sdo_geometry (2003, 4326, null, sdo_elem_info_array (1,1003,1), t);
end;
/
show errors
这样使用它:
update geomtest
set coord_geom = string_to_geom(coords);
commit;
我的业务发展目标是使用 Oracle Spatial 来存储我们的坐标数据。目前,我们从在海洋区域进行测量的科学家那里收到坐标,这些坐标作为点的数字对或多边形的长 varchar 数组存储在我们的 Oracle 数据库中。但是,我们希望通过使用 Oracle Spatial 改进我们对这些数据的管理。
我们从科学家那里获得的坐标信息通常以 CSV 文件的形式出现,附加数据并作为字段中的条目加载到 Oracle tables 中。
我知道我可以手动将顶点输入 SDO_ORDINATE_ARRAY,但我们通常会在一个 CSV 文件中提供数百个坐标对,这使得手动路线非常低效。
有人可以告诉我是否有办法通过从已存储的数据库中的其他 table 中提取信息来填充 SDO_ORDINATE_ARRAY 的内容?
下面是我尝试过的示例:
测试 table 称为 GEOMTEST 包含由...组成 名称 varchar2(50) 坐标 varchar2(4000) COORD_GEOM SDO_GEOMETRY
我在名称中填入了英国威尔士的感兴趣区域 'Cardigan Bay'。 COORDS 是我的多边形,以数组形式存储在 varchar2 中。这是从 CSV 文件导入的。 COORD_GEOM是我想把COORDS的内容转进去的
我尝试 运行 这段代码但收到错误:
插入 geomtest (coord_geom) 值(SDO_GEOMETRY(2003,4326,null,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY 值(select 来自 geomtest 的坐标));
我正在使用 Toad 作为我的客户端,错误是“错误:第 18 行,第 120 列,第 18 行结束,第 125 列:找到 'values':保留字不能用作标识符。
我认为这与我在 INSERT 语句的 SDO_ORDINATE_ARRAY 部分中使用 select 语句有关,但不确定如何进行。
如有任何建议,我将不胜感激,
非常感谢
肖恩
不幸的是,您不能直接将包含数字的字符串传递给 SDO_ORDINATE_ARRAY
构造函数。一种解决方案是编写自定义字符串分词器函数,将坐标字符串解析为单独的数字,并构建一个 SDO_ORDINATE_ARRAY
对象。这是一个:
create or replace function tokenize (str clob)
return sdo_ordinate_array
is
s clob := str||',';
i number;
j number;
t sdo_ordinate_array := sdo_ordinate_array();
begin
i := 1;
loop
j := instr(s, ',', i);
exit when j = 0;
t.extend();
t(t.count) := to_number(substr(s,i,j-i));
i := j+1;
end loop;
return t;
end;
/
show errors
这是它的工作原理。首先让我们用几个例子创建一个简单的 table:
drop table geomtest purge;
create table geomtest (
id number,
name varchar2(50 char),
coords clob,
coord_geom sdo_geometry
);
insert into geomtest (id, name, coords)
values (
2686,
'TX/Mitchell',
'-101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592'
);
insert into geomtest (id, name, coords)
values (
2769,
'TX/Yoakum',
'-103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332'
);
commit;
然后让我们使用分词器函数来更新几何列:
update geomtest
set coord_geom = sdo_geometry(2003,4326,null,sdo_elem_info_array(1,1003,1),tokenize(coords));
commit;
查看结果:
SQL> select * from geomtest;
ID NAME COORDS COORD_GEOM(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
---- ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2686 TX/Mitchell -101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592 SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592))
2769 TX/Yoakum -103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332 SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332))
2 rows selected.
注释
我使用
CLOB
列来存储坐标。一个 4000 字节的字符串太小,无法容纳任何严肃的几何图形(除非你所有的形状都非常简单——只有几个点)。如果进行这种字符串到几何的转换,有更有效的方法,但它们意味着您使用面向几何的字符串表示法:GeoJSON、WKT、GML。 Oracle 自然支持这些。它们还允许更复杂的结构,例如多边形或带孔的多边形。
编辑: 我将函数重写为直接 return 一个 SDO_GEOMETRY
对象。这使得它更容易使用:
create or replace function string_to_geom (str clob)
return sdo_geometry
is
s clob := str||',';
i number;
j number;
t sdo_ordinate_array := sdo_ordinate_array();
begin
i := 1;
loop
j := instr(s, ',', i);
exit when j = 0;
t.extend();
t(t.count) := to_number(substr(s,i,j-i));
i := j+1;
end loop;
return sdo_geometry (2003, 4326, null, sdo_elem_info_array (1,1003,1), t);
end;
/
show errors
这样使用它:
update geomtest
set coord_geom = string_to_geom(coords);
commit;