start with connect by prior 用法演示及for循环异常处理演示
演示代码如下:
create or replace procedure community_constriction
as
id number(20);
addr varchar2(100);
--设备对应的所有地址表的游标
CURSOR addrs_cursor is
select i.address_id from oneAddr_twoGrid 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;
--将得到的结果插入表constriction_result中,此结果会有很多重复
update oneAddr_twoGrid i set i.c_id= id,i.c_addr_full=addr where i.address_id=addr_record.address_id;
commit;
--处理异常
exception
when NO_DATA_FOUND then
DBMS_OUTPUT.put_line('1');
end;
end loop;
end community_constriction;
(此代码可以复用,如果复用,只需要改表名gis_no_up 为自己需要的表名)
解释一下, start with connect by prior可以查询父辈及以上所有的祖宗,也可以查询字辈及所有的子孙,本身可以理解是个循环 至于是查询父辈还是字辈,关键在与prior的位置,像上面这种prior c.parentaddress_id=c.id;就是已知某子类的parentid去找id和该parentid相等的父类,所以是找父辈 如果是prior 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) )