Plsql 在PL/SQL中使用两个游标

Plsql 在PL/SQL中使用两个游标,plsql,Plsql,我对光标有点困惑。在我的代码中,我会显示员工的姓名和工资。例如,如果用户在第一个光标中输入3,则仅显示3名员工(姓名和薪水)。第二个光标将执行相同的操作,但它将更改相同3名员工的工资并再次显示 DECLARE AA NUMBER; CURSOR S IS SELECT ENAME, SAL FROM EMP; CURSOR D IS SELECT ENAME, SAL FROM EMP; NAME EMP.ENAME%TYPE;

我对光标有点困惑。在我的代码中,我会显示员工的姓名和工资。例如,如果用户在第一个光标中输入3,则仅显示3名员工(姓名和薪水)。第二个光标将执行相同的操作,但它将更改相同3名员工的工资并再次显示

DECLARE
     AA NUMBER;
     CURSOR S IS SELECT ENAME, SAL
     FROM EMP;
     CURSOR D IS SELECT ENAME, SAL
     FROM EMP;
     NAME EMP.ENAME%TYPE;
     SALARY EMP.SAL%TYPE;
     C NUMBER;
BEGIN
   AA := :NUMBER_OF_EMP;
   SELECT COUNT(EMPNO) INTO C FROM EMP;
    OPEN S;
     FOR A IN 1..AA LOOP
        FETCH S INTO NAME, SALARY;
        DBMS_OUTPUT.PUT_LINE('NAME : '||NAME||'   SALARY :'||SALARY); 
     END LOOP;
CLOSE S;
  DBMS_OUTPUT.PUT_LINE('  ');
    OPEN D;
      FOR A IN 1..AA LOOP
        FETCH S INTO NAME, SALARY;
         UPDATE EMP
         SET SAL = SAL + 500;
        DBMS_OUTPUT.PUT_LINE('NAME : '||NAME||'   SALARY :'||SALARY); 
     END LOOP;
    CLOSE D;
END;

导致错误的直接原因是第二条FETCH语句。它从游标S获取,但您关闭了上面的游标。将其更改为从游标D获取将更正错误条件

但是,您的程序还有其他问题

  • “选择计数(empno)…”是多余的,因为您对结果不做任何处理

  • 光标S和D是相同的,不能同时打开,因此只需要其中一个。可以关闭然后重新打开同一个光标

  • 无论您使用2个游标还是仅重用1个游标,都不能保证返回相同的行

  • 您的更新不会执行您指示的操作。当执行循环编号时,它将更新表中每一行的sal列(在本例中为AA中的编号)。因此,如果AA为3,例如,每行sal将更新1500。这是因为更新中没有where子句。因此,Oracle会更新每一行

  • ORA-01001: invalid cursor