【问题标题】:Using cursors in loop in PL/SQL在 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;

【问题讨论】:

    标签: plsql cursor


    【解决方案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,它还包含一个带有嵌套函数和一个带有光标的匿名块实现。

    【讨论】:

    • 不客气。如果答案已解决或大大有助于解决您的问题,请接受答案。这极大地帮助了将来可能遇到相同问题的其他人。请不要将已成功回答的问题置于未回答/未解决状态。
    猜你喜欢
    • 2012-03-27
    • 2012-04-28
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多