Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PL/SQL循环计数?_Sql_Oracle_Plsql - Fatal编程技术网

PL/SQL循环计数?

PL/SQL循环计数?,sql,oracle,plsql,Sql,Oracle,Plsql,我有一个作业要求我重写我为上一个作业编写的PL/SQL代码: DECLARE -- Variables used to count a, b, c, d, and f grades: na integer := 0; nb integer := 0; nc integer := 0; nd integer := 0; nf integer := 0; BEGIN select count(*) into na from grad

我有一个作业要求我重写我为上一个作业编写的PL/SQL代码:

DECLARE
    -- Variables used to count a, b, c, d, and f grades:
    na integer := 0;
    nb integer := 0;
    nc integer := 0;
    nd integer := 0;
    nf integer := 0;
BEGIN
    select count(*) into na
    from   gradeReport1
    where  grade = 'A';

    select count(*) into nb
    from   gradeReport1
    where  grade = 'B';

    select count(*) into nc
    from   gradeReport1
    where  grade = 'C';

    select count(*) into nd
    from   gradeReport1
    where  grade = 'D';

    select count(*) into nf
    from   gradeReport1
    where  grade = 'F';

    if na > 0 then
        DBMS_OUTPUT.PUT_LINE('There are total ' || na || ' A''s');
    else
        DBMS_OUTPUT.PUT_LINE('There are no As');
    end if;

    if nb > 0 then
        DBMS_OUTPUT.PUT_LINE('There are total ' || nb || ' B''s');
    else 
        DBMS_OUTPUT.PUT_LINE('There are no Bs');
    end if;

    if nc > 0 then
        DBMS_OUTPUT.PUT_LINE('There are total ' || nc || ' C''s');
    else
        DBMS_OUTPUT.PUT_LINE('There are no Cs');
    end if;

    if nd > 0 then
        DBMS_OUTPUT.PUT_LINE('There are total ' || nd || ' D''s');
    else
        DBMS_OUTPUT.PUT_LINE('There are no Ds');
    end if;

    if nf > 0 then
        DBMS_OUTPUT.PUT_LINE('There are total ' || nf || ' F''s');
    else
        DBMS_OUTPUT.PUT_LINE('There are no Fs');
    end if;
END;
它所做的只是搜索我制作的一个名为gradeReport的表,该表存储学生ID并将其与成绩关联。PL/SQL统计从a级到F级的所有实例。问题希望我使用循环和varray重写此解决方案。谁能给我一个提示,帮我把事情搞清楚吗?我只使用PL/SQL几个星期,对语法只有基本的了解,所以我完全迷路了,不知道从哪里开始

这里没有寻找任何答案,只是一些想法


谢谢你

从医生开始怎么样

从文档开始怎么样

使用varray的解决方案可能如下所示:

DECLARE 
   type chararray IS VARRAY(6) OF CHAR(1); 
   type numarray IS VARRAY(6) OF INTEGER; 
   grades chararray; 
   cnt  numarray; 
BEGIN 
   select grade, count(*) 
     bulk collect into grades, cnt
     from gradeReport1
     group by grade
     order by grade;

   for i in 1..grades.count loop
     DBMS_OUTPUT.PUT_LINE('There are total ' || cnt(i) || ' ' ||grades(i)||'s');
   end loop;
END; 
/
但老实说,在这种情况下使用varray是没有意义的。只需使用光标循环:

BEGIN 
   for c in ( select grade, count(*) cnt 
                from gradeReport1
                group by grade
                order by grade ) loop    
     DBMS_OUTPUT.PUT_LINE('There are total ' || c.cnt || ' ' ||c.grade||'s');
   end loop;
END; 
/

但是,查找丢失的标记(计数为0的标记)有点困难。

使用varray的解决方案可能如下所示:

DECLARE 
   type chararray IS VARRAY(6) OF CHAR(1); 
   type numarray IS VARRAY(6) OF INTEGER; 
   grades chararray; 
   cnt  numarray; 
BEGIN 
   select grade, count(*) 
     bulk collect into grades, cnt
     from gradeReport1
     group by grade
     order by grade;

   for i in 1..grades.count loop
     DBMS_OUTPUT.PUT_LINE('There are total ' || cnt(i) || ' ' ||grades(i)||'s');
   end loop;
END; 
/
但老实说,在这种情况下使用varray是没有意义的。只需使用光标循环:

BEGIN 
   for c in ( select grade, count(*) cnt 
                from gradeReport1
                group by grade
                order by grade ) loop    
     DBMS_OUTPUT.PUT_LINE('There are total ' || c.cnt || ' ' ||c.grade||'s');
   end loop;
END; 
/
但是,查找缺失的标记(计数为0的标记)有点困难。

编辑:由于该要求专门针对varray,请参阅AmmoQ和MTO的回复。不过,正如他们都指出的那样,在实践中,这种类型的任务不太可能需要数组,即使需要,也会使用或而不是

你会想要一个类似于

for r in (
    select grade from gradereport1
)
loop
    ...
end loop;
在实际代码中,您可能会将其作为一个
分组查询,并让SQL为您进行计数

然后根据
r.grade
的值,有条件地增加循环中的计数器

您可以通过编写一个包含分数和总数的过程来合理化所有用于报告总数的
if
语句,因为所有语句的逻辑都是相同的

procedure showgrade
    ( p_grade gradereport1.grade%type
    , p_count integer )
is
begin
    ...
end showgrade;
我将把细节留作练习

为了好玩,这里有另一种方法,使用数组和循环(但不是varray-它们确实有点无用):

顺便说一句,在其他一些语言中,如果
,则不需要在后面加括号,除非该条件包含需要分隔的和和条件的混合体

也不需要用大写字母写任何东西。这很常见,而且一直都是这样,但他们在HTML/CSS世界中有过这样的争论,并决定使用小写字母以提高可读性。如果你想要一个大写规则,至少要始终如一地使用它。您的代码示例具有
end if
结束更不用说
选择
(我已经修复了)。有些人似乎能够阅读这样的代码而不会让他们发疯,但我恐怕不是他们中的一员。

编辑:由于这项要求是专门针对varray的,请参阅AmmoQ和MTO的回复。不过,正如他们都指出的那样,在实践中,这种类型的任务不太可能需要数组,即使需要,也会使用或而不是

DECLARE
  -- Need to ensure the array size will hold all the grades
  TYPE grade_tab IS VARRAY(200) OF gradeReport1.grade%TYPE;

  -- variable used to store the grades:
  t_grades grade_tab;

  -- Variables used to count a, b, c, d, and f grades:
  na INTEGER;
  nb INTEGER;
  nc INTEGER;
  nd INTEGER;
  nf INTEGER;
BEGIN
  -- Store the grades in an array:
  SELECT grade
  BULK COLLECT INTO t_grades
  FROM   gradeReport1
  WHERE  grade IN ( 'A', 'B', 'C', 'D', 'F' );

  -- Loop through the grades and count how many of each:
  FOR i IN 1 .. t_grades.COUNT LOOP
    IF    t_grades(i) = 'A' THEN na := na + 1;
    ELSIF t_grades(i) = 'B' THEN nb := nb + 1;
    ELSIF t_grades(i) = 'C' THEN nc := nc + 1;
    ELSIF t_grades(i) = 'D' THEN nd := nd + 1;
    ELSIF t_grades(i) = 'F' THEN nf := nf + 1;
    END IF;
  END LOOP;

  -- Output grade counts
END;
/
你会想要一个类似于

for r in (
    select grade from gradereport1
)
loop
    ...
end loop;
在实际代码中,您可能会将其作为一个
分组查询,并让SQL为您进行计数

然后根据
r.grade
的值,有条件地增加循环中的计数器

您可以通过编写一个包含分数和总数的过程来合理化所有用于报告总数的
if
语句,因为所有语句的逻辑都是相同的

procedure showgrade
    ( p_grade gradereport1.grade%type
    , p_count integer )
is
begin
    ...
end showgrade;
我将把细节留作练习

为了好玩,这里有另一种方法,使用数组和循环(但不是varray-它们确实有点无用):

顺便说一句,在其他一些语言中,如果
,则不需要在
后面加括号,除非该条件包含需要分隔的
条件的混合体

也不需要用大写字母写任何东西。这很常见,而且一直都是这样,但他们在HTML/CSS世界中有过这样的争论,并决定使用小写字母以提高可读性。如果你想要一个大写规则,至少要始终如一地使用它。您的代码示例具有
end if
结束更不用说
选择
(我已经修复了)。有些人似乎能够阅读这样的代码而不会让他们发疯,但我恐怕不是他们中的一员

DECLARE
  -- Need to ensure the array size will hold all the grades
  TYPE grade_tab IS VARRAY(200) OF gradeReport1.grade%TYPE;

  -- variable used to store the grades:
  t_grades grade_tab;

  -- Variables used to count a, b, c, d, and f grades:
  na INTEGER;
  nb INTEGER;
  nc INTEGER;
  nd INTEGER;
  nf INTEGER;
BEGIN
  -- Store the grades in an array:
  SELECT grade
  BULK COLLECT INTO t_grades
  FROM   gradeReport1
  WHERE  grade IN ( 'A', 'B', 'C', 'D', 'F' );

  -- Loop through the grades and count how many of each:
  FOR i IN 1 .. t_grades.COUNT LOOP
    IF    t_grades(i) = 'A' THEN na := na + 1;
    ELSIF t_grades(i) = 'B' THEN nb := nb + 1;
    ELSIF t_grades(i) = 'C' THEN nc := nc + 1;
    ELSIF t_grades(i) = 'D' THEN nd := nd + 1;
    ELSIF t_grades(i) = 'F' THEN nf := nf + 1;
    END IF;
  END LOOP;

  -- Output grade counts
END;
/
但是,更简单的解决方案是在单个SQL查询中进行计数(尽管这不符合使用
VARRAY
的评估要求):

但是,更简单的解决方案是在单个SQL查询中进行计数(尽管这不符合使用
VARRAY
的评估要求):


肯定非常感谢。是否特别要求您使用varray?它们在PL/SQL中通常不有用,因为只有一个功能受损的嵌套表版本,其中包含一个通常不需要的
limit
子句。非常感谢。是否特别要求您使用varray?它们在PL/SQL中通常没有用处,因为嵌套表中有一个功能受损的版本,带有一个通常不需要的
limit
子句。+1表示“也不需要用大写写任何东西”。我有一位同事一直这样做,几乎所有东西都是用大写写的,最后,我编写了一个实用程序,可以在不破坏文字、注释等的情况下消除这些垃圾。谢谢:)我希望Steven会在一分钟内解释为什么如果代码是PL/SQL,那么代码看起来像COBOL-77是可以的,但对于任何其他语言都不可以。与COBOL的相似性是我避免使用大写字母的主要原因,tooI刚决定使用小写字母表示所有内容,但我现在所在的公司有一个标准,其中包括关键字等大写字母。*叹气*OP声明:
问题希望我使用循环和varray重写此解决方案。
使用光标不符合此要求