在 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,它还包含一个带有嵌套函数和一个带有游标的匿名块实现。