废话不多说,直接上演示代码:
create or replace procedure community_constriction
as
id number(20);
addr varchar2(100);
--地址游标
CURSOR addrs_cursor is
select i.address_id from gis_no_up i;
begin
--对多个地址进行收敛,得到号级别的地址
for addr_record in addrs_cursor loop
begin
select addr_full,id
into addr,id
from c_address c
where c.subtype>4270 and c.subtype<4275 and rownum=1
start with c.id=addr_record.address_id
connect by prior c.parentaddress_id=c.id;
--处理异常
exception
when NO_DATA_FOUND then
DBMS_OUTPUT.put_line('1');
end;
--将得到的结果更新到表gis_no_up 中,
update gis_no_up i set i.c_id= id,i.c_addr_full=addr where i.address_id=addr_record.address_id;
commit;
end loop;
end community_constriction;
(此代码可以复用,如果复用,只需要改表名gis_no_up 为自己需要的表名)
解释一下, start with connect by prior可以查询父辈及以上所有的祖宗,也可以查询字辈及所有的子孙,本身可以理解是个循环
至于是查询父辈还是字辈,关键在与prior的位置,像上面这种prior c.parentaddress_id=c.id;就是已知某子类的parentid去找id和该parentid相等的父类,所以是找父辈
如果是c.parentaddress_id=prior c.id就是已知父类id,去找子类parentid与之相等的子类,简单理解为已知parentid就是找父辈,已知id就是找子类,因为该树形关系中
只有子类才有parentid,父类只有id,父类的parentid是对应父类的父类,但是如果有childid 那情况就刚好相反了。
子类 父类
parentid →→ id
这里c_address 表有id和parentid,gis_no_up 表里有id,但没有parentid,所以需要通过
c_address来查询父辈及爷爷辈,最后将查询得到的结果,更新到gis_no_up 表中事先准备好的两列id和addr。
gis_no_up 表结构如下:
create table GIS_NO_UP
(
crm_id VARCHAR2(20),
bureau_name VARCHAR2(10),
full_address VARCHAR2(200),
address_id NUMBER(19),
c_id NUMBER(19),
c_addr_full VARCHAR2(200)
)
c_address表结构如下:
create table C_ADDRESS
(
id NUMBER(19) not null,
parentaddress_id NUMBER(19),
addr_full VARCHAR2(3000),
subtype NUMBER(18)
)