【问题标题】:If condition in PL/SQL script with cursor and loop带有游标和循环的 PL/SQL 脚本中的 if 条件
【发布时间】:2015-07-17 09:11:10
【问题描述】:

我想在这种特殊情况下寻求一些帮助或建议。

我有一个名为“团队”的表。该表包含 3 列 - Issue、Responsible_team 和 More_Info(均为 varchar2)。

我有一个带有光标和循环的 PL/SQL 脚本,用于选择与您键入的问题描述一样多的团队(您认为它可能会帮助您找到负责的团队的一些随机词)。这部分对我很有用。

但我不知道如何编译那里的 IF 条件。如果根据输入的单词描述没有找到团队,我想得到一些基本的输出 dbms_output.put_line('Responsible team is not found')。 我编写脚本的方式有两种。经典循环和while循环。 我很乐意提供任何建议。

1.脚本

set verify off
DECLARE
    v_issue teams.issue%type; --variable for issue column from teams table
    v_respteam teams.responsible_team%type; --variable for responsible_team column from teams table
    v_info teams.more_info%type; --variable for more_info column from teams table

--cursor declaration
    CURSOR c_respteam
    RETURN teams%ROWTYPE
    IS
        SELECT issue, responsible_team, more_info
        FROM teams
        WHERE lower(issue) like '%&Describe_Issue%';
BEGIN
    OPEN c_respteam;
    LOOP
      FETCH c_respteam into v_issue, v_respteam, v_info;
      EXIT when c_respteam%NOTFOUND;
      dbms_output.put_line('Responsible team is '|| v_respteam || ' --> ' || v_info);        
    END LOOP;
    CLOSE c_respteam;
end;
/

2.脚本

-- cursor with while loop
set verify off
DECLARE
    v_issue teams.issue%type; --variable for issue column from teams table
    v_respteam teams.responsible_team%type; --variable for responsible_team column from teams table
    v_info teams.more_info%type; --variable for more_info column from teams table

CURSOR c_respteam
RETURN teams%ROWTYPE IS
    SELECT issue, responsible_team, more_info
    FROM teams
    WHERE lower(issue) like '%&Describe_Issue%';

BEGIN
OPEN c_respteam;
FETCH c_respteam INTO v_issue, v_respteam, v_info;
WHILE c_respteam%FOUND
LOOP
dbms_output.put_line('Responsible team is '|| v_respteam || ' --> ' || v_info);
FETCH c_respteam INTO v_issue, v_respteam, v_info;
END LOOP;
CLOSE c_respteam;
END;
/

【问题讨论】:

    标签: oracle loops if-statement plsql cursor


    【解决方案1】:

    你可以改写成:

    declare
       l_found boolean :=false;
    
       cursor c_respteam is
          select issue
                ,responsible_team
                ,more_info
            from teams
           where lower(issue) like '%&Describe_Issue%';
    begin
       for r in c_respteam
       loop
          l_found := true;
          dbms_output.put_line('Responsible team is ' || r.responsible_team || ' --> ' || r.more_info);
       end loop;
    
       if not l_found
       then
          dbms_output.put_line('No records found');
       end if;
    end;
    /
    

    【讨论】:

    • 非常感谢。我在考虑布尔值,但我不知道如何编译,因为我是新手。
    【解决方案2】:

    你需要有一个计数器变量 [ETA:哦,我喜欢 Rene 的布尔变量的想法;无论哪种方式,您都需要一个额外的变量!] 来确定是否返回了任何行。我不确定您为什么使用显式游标提取,而不是使用游标循环? Cursor-for-loops 不仅更易于编写、读取和维护,而且 Oracle 还进行了一些幕后优化以提高性能。

    当然,根据您对游标返回的数据实际执行的操作(dbms_output.put_line 是您在生产代码中永远不应该拥有的东西),您需要在全部。

    不管怎样,话虽如此,下面是一个示例,展示了我将如何处理您的要求以检查游标是否没有返回行:

    declare
      cursor cur (p_val varchar2)
      is
        select dummy
        from   dual
        where  dummy like '%'||p_val||'%';
    
      v_counter integer := 0;
    begin
      for rec in cur('Y')
      loop
        dbms_output.put_line('value of dummy = '||rec.dummy);
        v_counter := v_counter + 1;
      end loop;
      if v_counter = 0 then
        dbms_output.put_line('no rows returned');
      end if;
    end;
    /
    
    no rows returned
    
    declare
      cursor cur (p_val varchar2)
      is
        select dummy
        from   dual
        where  dummy like '%'||p_val||'%';
    
      v_counter integer := 0;
    begin
      for rec in cur('X')
      loop
        dbms_output.put_line('value of dummy = '||rec.dummy);
        v_counter := v_counter + 1;
      end loop;
      if v_counter = 0 then
        dbms_output.put_line('no rows returned');
      end if;
    end;
    /
    
    value of dummy = X
    

    为了扩展我在下面的评论中所说的内容,听起来您只需要一条 sql 语句,而不是使用 PL/SQL 并依赖 dbms_output。

    例如,假设您有以下语句:

    select lvl
    from   (select 'X'||level lvl from dual connect by level <= 10)
    where  lvl like '%&val%';
    

    如果 &val 为空,你会得到:

    LVL                                      
    -----------------------------------------
    X1                                       
    X2                                       
    X3                                       
    X4                                       
    X5                                       
    X6                                       
    X7                                       
    X8                                       
    X9                                       
    X10    
    

    使用 &val = 2 你会得到:

    LVL                                      
    -----------------------------------------
    X2                                       
    

    使用 &val = 100 你会得到:

    no rows selected.
    

    【讨论】:

    • 正如我在 Rene 的评论中提到的,我是新手。我仍在学习。该脚本并非专门针对生产环境,而是针对我的工作需要。简单地说,我工作的确切部分是负责获得有问题的票的所有权。我需要知道谁对确切的问题负责。我说的是很多问题和负责任的团队。因此,这仅适用于我,因为我创建了自己的表格,而脚本是如何找到团队的更快解决方案。无论如何,谢谢Boneist。很有帮助。
    • 在那种情况下,我会认为单个 select 语句会更好地满足您的需求,而不是 pl/sql!
    猜你喜欢
    • 2014-11-26
    • 2018-01-12
    • 2012-03-27
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多