Сравнивая вывод 2 курсоров в Oracle PL SQL - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть 2 курсора, я хотел бы сравнить поле, которое возвращается как выход одного курсора, с другим полем, которое также возвращается как выход другого курсора.

Ниже приведен мой код:

    CREATE OR REPLACE PROCEDURE CHECK_STUDENT AS

        CURSOR SCHOOL_REG IS
          SELECT STUDENT_ID FROM SCHOOL WHERE CLASSROOM IN (1,2,3,4,5);

        CURSOR CLASS_REG IS
          SELECT STUDENT_ID, STUDENT_NAME FROM REGISTER WHERE CLASSROOM = 1;

        FOR X IN CLASS_REG LOOP
          IF X.STUDENT_ID <> SCHOOL_REG.STUDENT_ID THEN
            DBMS_OUTPUT.PUT_LINE(X.STUDENT_ID || ' IS NOT REGISTERED IN SCHOOL');
          END IF;
        END LOOP;

    CHECK_STUDENT END;

Я не уверен, как я могу сравнить эти поля. Эти курсоры имеют сложные запросы, я упростил их с целью понимания.

Заранее спасибо за ваше время и помощь.

Ответы [ 2 ]

4 голосов
/ 28 февраля 2020

вы можете использовать оператор МИНУС

SELECT STUDENT_ID FROM REGISTER WHERE CLASSROOM = 1
minus
SELECT STUDENT_ID FROM SCHOOL WHERE CLASSROOM IN (1,2,3,4,5);

или проверить, не учится ли ученик в школе, как это

SELECT STUDENT_ID FROM REGISTER WHERE CLASSROOM = 1
and STUDENT_ID not in (SELECT STUDENT_ID FROM SCHOOL WHERE CLASSROOM IN (1,2,3,4,5)) ;
2 голосов
/ 28 февраля 2020

Если у вас есть , чтобы сделать это с этими двумя курсорами, вам понадобятся вложенные циклы и логический флаг для отслеживания:

CREATE OR REPLACE PROCEDURE CHECK_STUDENT AS

  CURSOR SCHOOL_REG IS
    SELECT STUDENT_ID FROM SCHOOL WHERE CLASSROOM IN (1,2,3,4,5);

  CURSOR CLASS_REG IS
    SELECT STUDENT_ID, STUDENT_NAME FROM REGISTER WHERE CLASSROOM = 1;

  FOUND BOOLEAN;
BEGIN

  FOR X IN CLASS_REG LOOP
    FOUND := FALSE;
    FOR Y IN SCHOOL_REG LOOP
      IF Y.STUDENT_ID = X.STUDENT_ID THEN
        FOUND := TRUE;
        EXIT;
      END IF;
    END LOOP;
    IF NOT FOUND THEN
      DBMS_OUTPUT.PUT_LINE(X.STUDENT_ID || ' IS NOT REGISTERED IN SCHOOL');
    END IF;
  END LOOP;

END CHECK_STUDENT;
/

Но это довольно неэффективно; предоставление курсору school_reg параметра, ограничивающего его поиск для одного студента, было бы небольшим улучшением, но тогда вы могли бы также использовать локальный запрос вместо курсора l oop.

Это было бы гораздо эффективнее сделать все это в одном операторе SQL, как показал @hotfix, или в качестве альтернативы этим двум запросам;

select student_id || ' IS NOT REGISTERED IN SCHOOL'
from register r
where classroom = 1
and not exists (
  select null
  from school s
  where s.student_id = r.student_id
  and s.classroom in (1,2,3,4,5)
);

db <> fiddle , показывающий все из них.

...