es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Trabajando con bucles anidados en pl/sql pero no mostrando la salida adecuada.

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;

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Problema en bucle anidado en script PL/SQL

    El script PL/SQL dado recupera el call_id y sec_num de COURSE_SECTION y luego recupera los nombres de los estudiantes de la tabla STUDENT mediante un bucle anidado. El script tiene como objetivo producir una lista de cursos junto con los estudiantes inscritos en cada curso, como se muestra en la imagen de salida.

    Sin embargo, el script actualmente no produce la salida esperada debido a problemas en la implementación del bucle anidado. Además, se pueden reemplazar los cursores implícitos (declaraciones SELECT INTO) por cursores explícitos para una mejor legibilidad y mantenibilidad.

    Para resolver el problema del bucle y mejorar el script, se pueden seguir los siguientes pasos:

    1. Reemplazar los cursores implícitos por cursores explícitos para una mejor legibilidad y mantenibilidad. Por ejemplo, en lugar de usar SELECT CALL_ID , SEC_NUM INTO call_id , sec_num FROM..., definir un cursor c_info y usar FETCH c_info INTO call_id , sec_num.
    2. En el bucle anidado, eliminar la declaración OPEN S_NAME ya que el cursor S_NAME ya está definido anteriormente. En su lugar, usar OPEN S_NAME antes del bucle externo y CLOSE S_NAME después del bucle externo para mejorar el rendimiento.

    3. Usar DBMS_OUTPUT.NEW_LINE después del bucle interno para mostrar una nueva línea antes de que se muestre el siguiente curso.

    El script PL/SQL actualizado es el siguiente:

    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;
    
      -- Definir cursores explícitos
      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
      -- Abrir cursores explícitos
      OPEN c_info; 
      OPEN s_name; 
    
      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('==================================');   
    
        LOOP
          FETCH s_name INTO fname, lname;
          EXIT WHEN s_name%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE(fname || ' ' || lname);  
        END LOOP;
    
        DBMS_OUTPUT.NEW_LINE; -- Mostrar una nueva línea antes de que se muestre el siguiente curso
      END LOOP; 
    
      -- Cerrar cursores explícitos
      CLOSE c_info; 
      CLOSE s_name; 
    
    END;
    

    Con estos cambios, el script debería producir ahora el resultado esperado como se muestra en la imagen de salida.

Comments are closed.