Oracle 打印Pl/sql中数字的偶数位数之和

Oracle 打印Pl/sql中数字的偶数位数之和,oracle,plsql,Oracle,Plsql,由于错误本身,我似乎无法解决此问题,这是因为您试图将整行temp(声明为游标变量-c_nm%rowtype)放入整数变量I中。虽然temp实际上只包含一列num,但它不会工作 那么,屏幕截图上的第15行: No : i := temp; Yes: i := temp.num; 一旦您修复了它,您的代码就可以工作了,但不幸的是,产生了错误的结果。在输入编号121974553中,偶数数字为2、9、4和5,其和等于20,而不是结果所示的6: SQL> set serveroutput on;

由于错误本身,我似乎无法解决此问题,这是因为您试图将整行temp(声明为游标变量-c_nm%rowtype)放入整数变量I中。虽然temp实际上只包含一列num,但它不会工作

那么,屏幕截图上的第15行:

No : i := temp;
Yes: i := temp.num;
一旦您修复了它,您的代码就可以工作了,但不幸的是,产生了错误的结果。在输入编号121974553中,偶数数字为2、9、4和5,其和等于20,而不是结果所示的6:

SQL> set serveroutput on;
SQL> declare
  2    ad int := 0;
  3    i int;
  4    b int;
  5    cursor c_nm is select * From numb;
  6    temp c_nm%rowtype;
  7  begin
  8    open c_nm;
  9    loop
 10      fetch c_nm into temp;
 11      exit when c_nm%notfound;
 12      i := temp.num;                  --> this
 13
 14      while i > 0 loop
 15        b := mod(i, 10);
 16        if mod(b, 2) = 0 then
 17           ad := b + ad;
 18        end if;
 19        i := trunc(i/10);
 20      end loop;
 21    end loop;
 22    dbms_output.put_line('ad = ' ||ad);
 23    close c_nm;
 24  end;
 25  /
ad = 6

PL/SQL procedure successfully completed.

SQL>
一个更简单的选项可能是这样的:将数字拆分为单独行中的每个数字,以便可以对其偶数数字应用求和函数:

SQL> select * from numb;

       NUM
----------
 121974553     --> sum of even digits = 2 + 9 + 4 + 5 = 20
 253412648     -->                    = 5 + 4 + 2 + 4 = 15

SQL> with
  2  split as
  3    -- split number into rows
  4    (select num,
  5            substr(num, column_value, 1) digit,
  6            case when mod(column_value, 2) = 0 then 'Y'
  7                 else 'N'
  8            end cb_odd_even
  9     from numb cross join table(cast(multiset(select level from dual
 10                                              connect by level <= length(num)
 11                                             ) as sys.odcinumberlist))
 12    )
 13  -- final result: summary of digits in even rows
 14  select num,
 15         sum(digit)
 16  from split
 17  where cb_odd_even = 'Y'
 18  group by num;

       NUM SUM(DIGIT)
---------- ----------
 253412648         15
 121974553         20

SQL>
如果它必须是PL/SQL,则稍微重写为

SQL> declare
  2    result number;
  3  begin
  4    for cur_r in (select num from numb) loop
  5      with
  6      split as
  7        -- split number into rows
  8        (select substr(cur_r.num, level, 1) digit,
  9                case when mod(level, 2) = 0 then 'Y'
 10                     else 'N'
 11                end cb_odd_even
 12         from dual
 13         connect by level <= length(cur_r.num)
 14        )
 15      -- final result: summary of digits in even rows
 16      select sum(digit)
 17      into result
 18      from split
 19      where cb_odd_even = 'Y';
 20
 21      dbms_output.put_line(cur_r.num || ' --> ' || result);
 22    end loop;
 23  end;
 24  /
121974553 --> 20
253412648 --> 15

PL/SQL procedure successfully completed.

SQL>

你可以这样做。注意:首先,您可以在select中为rec使用隐式光标。。。循环构造。您不需要声明rec的数据类型,也不需要打开游标-然后在完成时记得关闭它-等等。隐式游标非常方便,最好尽早了解它。第二,注意我的符号中的rec只是一个指针;要从中访问该值,必须引用表列,如中所示,rec.num-Littlefoot在其回复中已经显示了这一点。第三,尝试中的逻辑错误:如果表中有多行,则必须为每个新值将ad初始化为0-不能在程序开始时将其初始化为0一次

这么说吧,这里是一些样本数据,然后是过程及其输出

create table numb (num int);

insert into numb values(121975443);
insert into numb values(100030000);
insert into numb values(null);
insert into numb values(113313311);
insert into numb values(2020);

commit;

declare
  ad int;
  i  int;
begin
  for rec in (select num from numb) loop
    ad := 0;
    i  := rec.num;
    while i > 0 loop
      if mod(i, 2) = 0 then
        ad := ad + mod(i, 10);
      end if;
      i := trunc(i/10);
    end loop;
    dbms_output.put_line('num: ' || nvl(to_char(rec.num), 'null') || 
                                    '  sum of even digits: ' || ad);
  end loop;
end;
/

num: 121975443  sum of even digits: 10
num: 100030000  sum of even digits: 0
num: null  sum of even digits: 0
num: 113313311  sum of even digits: 0
num: 2020  sum of even digits: 4


PL/SQL procedure successfully completed.

我认为你把偶数和偶数顺序的数字混淆了。在OP的样本编号中,数字2和4是偶数;所有其他数字都是奇数。在数字13559中,所有数字都是奇数。我假设它必须是PL/SQL;这看起来很像家庭作业,我怀疑如果不是作业的一部分,OP会要求使用PL/SQL名称。使用显式游标是作业的一部分吗?他们不是教过你隐式游标吗?隐式游标非常容易使用?这是除了您当前尝试中的错误等。