在 PL/SQL 中循环使用游标
Posted
技术标签:
【中文标题】在 PL/SQL 中循环使用游标【英文标题】:Using cursors in loop in PL/SQL 【发布时间】:2020-11-08 15:14:46 【问题描述】:我有一个包含 3 列的表。第一列的名称是 id,第二列的名称是 parent_id,第三列的名称是表达式。我想要做的是在表达式列中搜索 id。例如,我发送 id 值然后如果 parent_id列有一个值我想发送 parent_id 值并想检查表达式列是否有'E'。如果它有空值并且结果有 parent_id 那么我想发送 parent_id 值,我想再次检查表达式列有'E ' 与否。如果表达式列有一个像 'E' 这样的值,我将变量 resultValue 更新为 1 并结束循环。
我的表 A:它应该返回 resultValue =1
id |parent_id|expression
123 |null | null
45 |123 | 'E'
22 |45 | null
我的表 B:它应该返回 resultValue = 0
id |parent_id|expression
30 |null | null
20 |30 | null
10 |20 | null
我的表 C:它应该返回 resultValue = 0
id |parent_id|expression
30 |null | null
20 |30 | null
10 |null | null
如果第一次发送的 id(10) 不包含 parent_id(table C),resultValue 变量应该是 0。如果我找到 'E' 表达式,任何父行 resultValue 变量都应该返回 1。
我用游标创建了一个代码块。我第一次使用游标。我不确定使用游标解决这种问题是否是个好主意。我的代码正在运行,但要打开游标然后关闭游标再次打开光标是个好主意吗?
DECLARE
resultValue NUMBER := 0;
CURSOR c(v_id NUMBER )
IS
SELECT id_value, id_parent, expression FROM students WHERE id_value = v_id;
PROCEDURE print_overpaid
IS
id_value NUMBER;
id_parent NUMBER;
expression VARCHAR2(20);
BEGIN
LOOP
FETCH c INTO id_value, id_parent, expression;
EXIT
WHEN c%NOTFOUND;
IF id_parent IS NULL AND expression IS NULL THEN
EXIT;
END IF;
IF id_parent IS NOT NULL THEN
CLOSE c;
OPEN c(id_parent);
ELSIF id_parent <> NULL AND expression = 'X' OR id_parent IS NULL AND expression = 'X' THEN
resultValue := 1;
EXIT;
END IF;
END LOOP;
END print_overpaid;
BEGIN
OPEN c(22);
print_overpaid;
DBMS_OUTPUT.PUT_LINE(' My resultValue is : ' || resultValue);
CLOSE c;
END;
【问题讨论】:
【参考方案1】:如果我正确理解了您的描述,您正在寻找它,父系中任何行的指定 ID 在列表达式中包含“E”。您是正确的,关闭和重新打开游标并不是一个好主意。尽管我确实喜欢您使用嵌套过程。但是,这并不是真正必要的,因为这可以通过单个查询来解决。该方法将是一种递归 CTE,它会检查目标行中的“E”,直到某行包含它或该行没有父行。
with search_for_e(id, parent_id, e_cnt) as
( select id, parent_id, case when expression = 'E' then 1 else 0 end
from exp_tbl
where id = &id
union all
select t.id,t.parent_id, case when t.expression = 'E' then 1 else 0 end
from search_for_e s
join exp_tbl t on (t.id = s.parent_id)
where t.parent_id is not null
and s.e_cnt = 0
)
select max(e_cnt)
from search_for_e;
参见fiddle here,它还包含一个带有嵌套函数和一个带有光标的匿名块实现。
【讨论】:
不客气。如果答案已解决或大大有助于解决您的问题,请接受答案。这极大地帮助了将来可能遇到相同问题的其他人。请不要将已成功回答的问题置于未回答/未解决状态。以上是关于在 PL/SQL 中循环使用游标的主要内容,如果未能解决你的问题,请参考以下文章