【问题标题】:Comparing the output of 2 cursors in Oracle PL SQL比较 Oracle PL SQL 中 2 个游标的输出
【发布时间】:2020-02-28 11:13:53
【问题描述】:

我有 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;

我不确定,如何比较这些字段。这些游标有复杂的查询,为了便于理解,我进行了简化。

提前感谢您的时间和帮助。

【问题讨论】:

  • 是否需要使用显式游标,您是否对结果进行了其他操作?您可能已经简化到看起来您使用了错误的方法;或者实际上可能是这种情况,您根本不需要这些游标/循环(甚至 PL/SQL)。
  • 您的代码也缺少BEGIN 并且最后一行是错误的;当你尝试这样做时,你没有包括你得到的错误。样本数据和预期结果也会有所帮助。

标签: oracle plsql oracle11g oracle-sqldeveloper


【解决方案1】:

您可以使用 MINUS 运算符

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

或检查 student_id 是否像这样在学校

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】:

    如果您必须使用这两个游标来执行此操作,那么您将需要嵌套循环和一个布尔标志来跟踪:

    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 游标提供一个参数以将其查找限制为单个学生会稍有改进,但您不妨使用本地查询而不是游标循环。

    如@hotfix 所示,在单个 SQL 语句中完成整个操作会更有效率,或者作为这两个查询的替代方案;

    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 显示所有这些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      相关资源
      最近更新 更多