如果PL / SQL脚本中的条件带有游标和循环

时间:2015-07-17 09:11:11

标签: oracle loops if-statement plsql cursor

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

我有一张名为" Teams"的桌子。该表包含3列 - Issue,Responsible_team和More_Info(all varchar2)。

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

但我不知道如何在那里编译IF条件。如果根据键入的单词描述找不到团队,我想获得一些基本输出dbms_output.put_line('未找到负责团队')。 我编写脚本有两种方法。经典循环和while循环。 我很乐意接受任何建议。

1.script

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.script

-- 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;
/

2 个答案:

答案 0 :(得分:1)

你需要一个计数器变量[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%';

&amp; val空白,你得到:

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

使用&amp; val = 2,你得到:

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

使用&amp; val = 100,你得到:

no rows selected.

答案 1 :(得分: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;
/