在 PL/SQL 中循环使用游标
Using cursors in loop in PL/SQL
我有 table 包含 3 column.First 列名称是 id ,第二列的名称是 parent_id 第三列是 expression.What 我想做的是搜索id.For 示例的表达式列我发送 id 值然后如果 parent_id 列有一个值我想发送 parent_id 值并想检查表达式列有 'E' 或 not.If 它有空值,结果有 parent_id 然后我想发送 parent_id 值,我想再次检查表达式列有 'E' 或 not.If 表达式列有一个值像那样 'E',我将变量 resultValue 更新为 1 并结束循环。
我的table答:应该returnresultValue=1
id |parent_id|expression
123 |null | null
45 |123 | 'E'
22 |45 | null
我的 table B:它应该 return resultValue = 0
id |parent_id|expression
30 |null | null
20 |30 | null
10 |20 | null
我的 table C : 它应该 return 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 变量应该 return 1.
我在第一次使用 cursor.I 时用 cursor.For 创建了一个代码块我不确定使用游标解决这类问题是个好主意还是 not.My 代码是 运行 但是打开游标然后关闭游标然后再次打开游标是个好主意吗?
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;
如果我对您的描述的理解正确,您希望看到它的父系中任何行的指定 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,它还包含一个带有嵌套函数和一个带有游标的匿名块实现。
我有 table 包含 3 column.First 列名称是 id ,第二列的名称是 parent_id 第三列是 expression.What 我想做的是搜索id.For 示例的表达式列我发送 id 值然后如果 parent_id 列有一个值我想发送 parent_id 值并想检查表达式列有 'E' 或 not.If 它有空值,结果有 parent_id 然后我想发送 parent_id 值,我想再次检查表达式列有 'E' 或 not.If 表达式列有一个值像那样 'E',我将变量 resultValue 更新为 1 并结束循环。
我的table答:应该returnresultValue=1
id |parent_id|expression
123 |null | null
45 |123 | 'E'
22 |45 | null
我的 table B:它应该 return resultValue = 0
id |parent_id|expression
30 |null | null
20 |30 | null
10 |20 | null
我的 table C : 它应该 return 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 变量应该 return 1.
我在第一次使用 cursor.I 时用 cursor.For 创建了一个代码块我不确定使用游标解决这类问题是个好主意还是 not.My 代码是 运行 但是打开游标然后关闭游标然后再次打开游标是个好主意吗?
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;
如果我对您的描述的理解正确,您希望看到它的父系中任何行的指定 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,它还包含一个带有嵌套函数和一个带有游标的匿名块实现。