PL/SQL 循环“返回”记录
Posted
技术标签:
【中文标题】PL/SQL 循环“返回”记录【英文标题】:PL/SQL looping 'back' through the records 【发布时间】:2020-03-31 16:25:24 【问题描述】:我有一个问题希望你能帮忙解决。
我有一个名为 PRODUCT 的表:
Product_ID NOT NULL NUMBER(10)
TARGET_PRODUCT VARCHAR2(10)
SOURCE_PRODUCT VARCHAR2(10)
所以每个 target_product 都由 source_product 组成(第一个除外 - 第一个只有 target_product 并且 source_product 为空) 我需要为给定的 target_product 找到第一个 source_product。 我需要循环“返回”,直到源产品为空。 这种情况有解决方案吗?
提前致谢
【问题讨论】:
请分享示例数据并通过所需的输出解释问题,以便具体回答您的问题。 【参考方案1】:你需要的不是循环,而是分层查询。查看以下基于 Scott 的 EMP
表的示例。
这是它的内容;员工分层显示,显示谁是谁的老板:
SQL> select level,
2 lpad(' ', level * 2, ' ') || e.ename name
3 from emp e
4 start with e.mgr is null
5 connect by prior e.empno= e.mgr;
LEVEL NAME
---------- ---------------
1 KING
2 JONES
3 SCOTT
4 ADAMS
3 FORD
4 SMITH
2 BLAKE
3 ALLEN
3 WARD
3 MARTIN
3 TURNER
3 JAMES
2 CLARK
3 MILLER
14 rows selected.
SQL>
当你想从表格的中间开始(例如,从SMITH
开始),你可以“反转”它:
SQL> select level lvl,
2 lpad(' ', level * 2, ' ') || e.ename name
3 from emp e
4 start with e.ename = 'SMITH'
5 connect by prior e.mgr= e.empno;
LVL NAME
---------- ---------------
1 SMITH
2 FORD
3 JONES
4 KING
SQL>
最后,将该查询用作 CTE(或子查询,如果您的 Forms 版本不支持 CTE),获取名称具有***别的查询:
SQL> with temp as
2 (select level lvl,
3 lpad(' ', level * 2, ' ') || e.ename name
4 from emp e
5 start with e.ename = 'SMITH'
6 connect by prior e.mgr= e.empno
7 )
8 select trim(t.name) name
9 from temp t
10 where t.lvl = (select max(t1.lvl) from temp t1);
NAME
---------------
KING
SQL>
或者,更好的是,使用connect_by_isleaf
:
SQL> select e.ename name
2 from emp e
3 where connect_by_isleaf = 1
4 start with e.ename = 'SMITH'
5 connect by prior e.mgr= e.empno;
NAME
---------------
KING
SQL>
【讨论】:
【参考方案2】:您可以试试这个,它将返回给定 target_product 的基本 target_product:
select * from (
select PRODUCT_ID, TARGET_PRODUCT, SOURCE_PRODUCT
from PRODUCT
start with target_product = '<your target product>'
connect by prior SOURCE_PRODUCT = TARGET_PRODUCT
)
where SOURCE_PRODUCT is null;
【讨论】:
以上是关于PL/SQL 循环“返回”记录的主要内容,如果未能解决你的问题,请参考以下文章