在 pl/sql 中使用嵌套循环但未显示正确的输出

Posted

技术标签:

【中文标题】在 pl/sql 中使用嵌套循环但未显示正确的输出【英文标题】:Working with nested loops in pl/sql but not displaying the proper output 【发布时间】:2021-12-31 06:18:00 【问题描述】:
SET SERVEROUTPUT ON SIZE 4000;
DECLARE 
call_id COURSE.CALL_ID%type;
sec_num COURSE_SECTION.SEC_NUM%type;
fname STUDENT.S_FIRST%TYPE ;
lname STUDENT.S_LAST%TYPE;

CURSOR c_info is 
SELECT CALL_ID , SEC_NUM 
FROM COURSE_SECTION ,COURSE,TERM
WHERE COURSE_SECTION.COURSE_ID = COURSE.COURSE_ID
AND TERM.TERM_ID = COURSE_SECTION.TERM_ID
AND TERM.TERM_DESC = 'Summer 2007' ;

CURSOR S_NAME IS 
SELECT DISTINCT S_FIRST, S_LAST    
FROM STUDENT,COURSE_SECTION,TERM,ENROLLMENT 
WHERE TERM.TERM_ID = COURSE_SECTION.TERM_ID
AND COURSE_SECTION.C_SEC_ID = ENROLLMENT.C_SEC_ID
AND COURSE_SECTION.TERM_ID=TERM.TERM_ID                             
AND ENROLLMENT.S_ID = STUDENT.S_ID
AND TERM.TERM_DESC LIKE 'Summer 2007';


   BEGIN
   OPEN c_info; 
  
   LOOP 
   FETCH c_info INTO call_id , sec_num ;
      EXIT WHEN c_info%notfound; 
      DBMS_OUTPUT.PUT_LINE('==================================');
      DBMS_OUTPUT.PUT_LINE(call_id || ' ' || 'Sec. ' || sec_num);
      DBMS_OUTPUT.PUT_LINE('==================================');   
      OPEN S_NAME;
      LOOP
        FETCH S_NAME INTO fname , lname ;
        EXIT WHEN S_NAME%notfound;
        DBMS_OUTPUT.PUT_LINE(fname || ' ' || lname );  
      END LOOP;
       CLOSE S_NAME ;
   END LOOP; 
  
   CLOSE c_info; 
  
END; 

-- 预期的输出 -- 我有一些问题,我无法显示正确的输出。我正在尝试使用嵌套循环,但在实现它时犯了一些错误。另外,我认为使用显式光标要好得多。

利用诺斯伍德大学的数据库。 https://drive.google.com/file/d/1M_g7FbgOUahoFtE943OK28UxIFbUFgRk/view?usp=sharing 脚本

【问题讨论】:

好的,你显示了预期的输出。你得到什么输出? “我有一些问题,我无法显示正确的输出”实际上是什么意思? 您在输出中遇到了哪些问题?我能够看到正确的输出 - dbfiddle.uk/… 【参考方案1】:

我在这里做了很多假设 - 我猜你在你的内部循环中获得所有课程的所有学生,但你真的只想让学生在你的外部循环中处理你正在处理的特定课程部分.

因此,您的第二个查询将需要引用正确的课程部分 ID,以将学生限制在该部分。

您不需要显式定义游标,除非出于某种原因需要它们 - 如果您只是迭代它们,最好直接在 FOR 循环中引用它们。

这让我想到了以下内容

set serveroutput on size 4000;
begin
   for c_info in ( 
      select call_id, 
             sec_num,
             SEC_ID       -- PK to link to enrollment later
      from   course_section,
             course,
             term
      where course_section.course_id = course.course_id
      and   term.term_id = course_section.term_id
      and   term.term_desc = 'Summer 2007' ;
   )
   loop 
      dbms_output.put_line('==================================');
      dbms_output.put_line(c_info.call_id || ' ' || 'Sec. ' || c_info.sec_num);
      dbms_output.put_line('==================================');   
      
      for s_name in (
        select distinct s_first, s_last    
        from student,
             course_section,
             term,
             enrollment 
        where term.term_id = course_section.term_id
        and   course_section.c_sec_id = enrollment.c_sec_id
        and   course_section.term_id=term.term_id                             
        and   enrollment.s_id = student.s_id
        and   term.term_desc like 'Summer 2007'
        AND   ENROLLMENT.C_SEC_ID = C_INFO.SEC_ID  -- get students just for THIS course section
      )
      loop
        dbms_output.put_line(s_name.s_first || ' ' || s_name.s_last );  
      end loop;
   end loop; 
end; 

我在 CAPS 中放置了查询更改。

由于我剪切/粘贴了您的 SQL,因此第一个查询中没有别名 - 我建议您更正这一点,因为别名列始终是一种好习惯。

同样,我在第二个查询中保留了 DISTINCT,但我怀疑它是多余的,因为我想一个学生不会为一个课程部分注册多次。 (实际上,如果您有两个名叫 Sue Smith 的不同学生,您可能希望将它们打印两次,不是吗?)

【讨论】:

你是最棒的,非常感谢。现在,我更好地理解了这种方式。

以上是关于在 pl/sql 中使用嵌套循环但未显示正确的输出的主要内容,如果未能解决你的问题,请参考以下文章

knockout.js 数据中的嵌套 foreach 显示但未正确显示

PL/SQL 匿名块已完成”但未显示结果

PL / SQL嵌套循环(循环内循环)

无输出,仅显示“PL/SQL 过程已成功完成”

PL/SQL用星号拼出金字塔

创建在循环内输出不同名称的 Oracle PL/SQL 过程