0

我需要创建一个程序来接受一个人姓名的第一个和最后一个字母,并返回他购买的总成本和总物品。我不知道如何使用光标,我也在想我必须使用 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');
4

1 回答 1

0

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

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;

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

于 2018-08-06T08:02:26.543 回答