to beckhambobo(beckham) : 1.我没有认为这样实现性能差,只是不方便。:) 2.如果没有HelperCode,要实现我提到的like式查询,sql怎样写呢?我现在只能想到把所有的记录取出来,遍历这棵树,找到属于指定节点的所有子节点。
我用 HelperCode like '001%'就可以取出前4条记录已取了五条记录了, 001 001001 001001001 001001002 001002本人方法如下: SQL> select * from aa;ID FID -- --- 1 0 2 1 3 1 4 2 5 3 6 4 6 57 rows selectedSQL> SQL> select lpad(id,level*2+length(id),' ') id 2 from aa 3 connect by prior id = fid 4 start with fid = 0;ID -------------------------------------------------------------------------------- 1 2 4 6 3 5 67 rows selectedcreate function get_dept(p_id varchar2) return varchar2 as v_ret varchar2(20); cursor t_sor(v_id varchar2) is select distinct id from aa connect by prior id = fid start with fid =v_id; begin for v_sor in t_sor(p_id) loop v_ret:=v_ret||'/'||v_sor.id; end loop; return(v_ret); end; /SQL> select id,get_dept(id) from aa;ID GET_DEPT(ID) -- ------------------------------------------------------------------------------- 1 /2/3/4/5/6 2 /4/6 3 /5/6 4 /6 5 /6 6 6 这样就在查询语句中where ... 控制节点
to beckhambobo(beckham):你的这段代码对我非常有用!眼前豁然开朗!谢谢! 初步学会了使用connect by关键字。好东东!select distinct id from aa connect by prior id = fid start with fid =v_id;
to beckhambobo(beckham):我查了Oracle的connect by关键字的帮助,看到下面这一段:However, some part of the condition must use the PRIOR operator to refer to the parent row. The part of the condition containing the PRIOR operator must have one of the following forms: PRIOR expr comparison_operator expr expr comparison_operator PRIOR expr上面最后两个表达式有什么区别呢?(我试了,确实有区别,但不明白其中的规律)我再找prior关键字的帮助,找不到更多的信息了。
”是加锁,这样就避免重复。
ID是从一个Sequence里取出来的整数直接写到字段里的,Parent实际上也是一个整数。
如果ID和Parent改为HelperCode的编码方式,同样会遇到这样的问题啊to hqwang77(haiqing):
加锁的语法是怎样的?可否按照你的思路给个例子?谢谢!
先钻一个牛角尖:=======================================================================
现在我填写HelperCode的方法是:
1.用户在客户端为某个节点增加一个子节点时
2.取得该节点的直接子节点中HelperCode最大者
3.将该值增加1作为新增的子节点的HelperCode(如果最大数是999,怎么办?)
=======================================================================我的一个办法:
1、将HelperCode列置为Unique列,不允许重复
2、写一个函数取最大HelperCode值,如:getMaxCode(id in number)
3、向t_area表中插数据,同时进行异常捕捉,如果违背了唯一性,即dup_val_on_index异常,则循环调用getMaxCode(id)函数,直到可插入为止供参考:)
如果只用id不会造成重复问题。我还是不明白为什么要用helpercode??
谢谢你的建议。
1.我的应用中999够用了。:)
2.我的客户端是通过DataSet来提交的,我希望如果没有其它原因(比如主键冲突,违反其它约束),提交总是成功的。对于Oracle数据库来讲,两个客户端A、B同时新增数据,A没提交之前,B看不到A操作的结果,即B可能取得与A相同的最大HelperCode。这样A提交后B再提交,事务就会失败。我希望有个好的方法来解决这个问题。to zjhclf(寂寞撩人):
比如有如下节点的HelperCode
001
001001
001001001
001001002
001002
002
我用 HelperCode like '001%'就可以取出前4条记录,而没有该字段就比较麻烦了。
如果新增一个节点(假定它的HelperCode为001001003),我的Sql语句不变,仍能取到预期的结果。
其实:HelperCode这样实现一个树型结构,记录挺多的,而like操作符要进行全表检索,这样更不利于性能.
1.我没有认为这样实现性能差,只是不方便。:)
2.如果没有HelperCode,要实现我提到的like式查询,sql怎样写呢?我现在只能想到把所有的记录取出来,遍历这棵树,找到属于指定节点的所有子节点。
001
001001
001001001
001001002
001002本人方法如下:
SQL> select * from aa;ID FID
-- ---
1 0
2 1
3 1
4 2
5 3
6 4
6 57 rows selectedSQL>
SQL> select lpad(id,level*2+length(id),' ') id
2 from aa
3 connect by prior id = fid
4 start with fid = 0;ID
--------------------------------------------------------------------------------
1
2
4
6
3
5
67 rows selectedcreate function get_dept(p_id varchar2)
return varchar2
as
v_ret varchar2(20);
cursor t_sor(v_id varchar2) is
select distinct id
from aa
connect by prior id = fid
start with fid =v_id;
begin
for v_sor in t_sor(p_id) loop
v_ret:=v_ret||'/'||v_sor.id;
end loop;
return(v_ret);
end;
/SQL> select id,get_dept(id) from aa;ID GET_DEPT(ID)
-- -------------------------------------------------------------------------------
1 /2/3/4/5/6
2 /4/6
3 /5/6
4 /6
5 /6
6
6 这样就在查询语句中where ... 控制节点
初步学会了使用connect by关键字。好东东!select distinct id
from aa
connect by prior id = fid
start with fid =v_id;