如何将游标添加到 PL/SQL 块中的过程中?

Posted

技术标签:

【中文标题】如何将游标添加到 PL/SQL 块中的过程中?【英文标题】:How do you add cursor into a procedure in PL/SQL block? 【发布时间】:2018-08-04 22:39:27 【问题描述】:

我需要创建一个程序,它接受一个人姓名的第一个和最后一个字母,并返回他购买的总成本和总物品。我不知道如何使用光标,我也在想我必须使用 for 循环和异常处理,因为可能有很多人具有相同的开始和结束字母。

到目前为止,我想出了这个:

    create or replace procedure total_spent(v_fname IN 
    saleinv.cname%TYPE,v_lname IN saleinv.cname%TYPE.v_netspend OUT 
    saleinv.net%TYPE,v_totalpurch OUT NUMBER) AS
    Begin
    select sum(net+tax),count(net) into v_netspend,v_totalpurch from saleinv 
    where cname LIKE '&v_fname%&v_lname';
    END;
    /

    ACCEPT p_fname PROMPT  'Enter The first letter of customer's name' 
    ACCEPT p_lname PROMPT 'Enter the last letter of customer's name'
    BEGIN
    totalspent('&p_fname',&'p_lname');

【问题讨论】:

对于输出,我将使用一个变量。 听起来基于集合的方法完全没问题,而且不需要光标。 (但您可能希望将查询的like 表达式重写为LIKE v_fname || '%' || v_lname。) 它说我必须使用光标。除了表达之外,其他一切都好吗? 因此,如果某人的名字是“SingH”,您必须提供“S”和“H”作为参数并返回一些与“他”相关的值(如您所说)。如果该表包含一个名为“SetH”的人,即他们都共享相同的第一个字母和最后一个字母,该怎么办。你会返回谁的数据? 为此我必须使用 for 循环为我认为具有相似字母的每个人提取数据 【参考方案1】:

提出了一种解决方案,稍作修改(顺便说一下,参数名称更具体,不会有任何解释):

procedure total_spent(
  p_fname_first_letter in varchar2,
  p_lname_last_letter in varchar2,
  p_netspend out number,
  p_totalpurch out number) as

  cursor c_net(
    p_fname_first_letter varchar2,
    p_lname_last_letter varchar2) is
  select
    sai.cname, 
    sum(sai.net + sai.tax) net_spend,
    count(sai.net) total_purch 
  from 
    saleinv sai
  where 
    upper(sai.cname) like upper(p_fname_first_letter) || '%' || upper(p_lname_last_letter)
  group by
    sai.cname;

  l_found_cust boolean := false;
  l_show_err boolean := false;
  l_cust_list varchar2(100);

Begin

  p_netspend := 0;
  p_totalpurch := 0;

  for l_sai_rec in c_net(
    p_fname_first_letter,
    p_lname_last_letter)
  loop

    if not l_found_cust then

      p_netspend := l_sai_rec.net_spend;
      p_totalpurch := l_sai_rec.total_purch;
      l_cust_list := l_sai_rec.cname;
      l_found_cust := true;

    else

      l_cust_list := l_cust_list || '; ' || l_sai_rec.cname;
      l_show_err := true;

    end if;

  end loop; 

  if l_show_err then
    raise_application_error(-20101, 'Found more customers with provided parameters. Customers: '||l_cust_list);
  end if;

end;

正如你提到的,它使用光标。当然,有一种更好的方法可以做到这一点,无需光标,也可以满足您的逻辑要求(更少的代码)。如果您愿意知道,请随时询问。

【讨论】:

以上是关于如何将游标添加到 PL/SQL 块中的过程中?的主要内容,如果未能解决你的问题,请参考以下文章

将修改后的表中的游标用于相同的 PL/SQL 过程

从 pl/sql 异常块中“一次”关闭所有游标

PL/SQL 打印出存储过程返回的引用游标

过程中的 PL/SQL 游标不起作用

过程中的PL/SQL游标问题

在pl sql中的单个变量中传递两个或多个参数[重复]