为什么会收到我的光标无效的错误消息?

问题描述 投票:0回答:2
SET SERVEROUTPUT ON
SET VERIFY OFF
DECLARE
v_deptno empcopy.deptno%TYPE;
v_empno empcopy.empno%TYPE;
v_sal empcopy.sal%TYPE;
v_bonus NUMBER(7,2);
CURSOR emp_cursor IS
SELECT deptno, empno, sal
FROM empcopy
WHERE v_deptno < 25;
BEGIN
FETCH emp_cursor INTO v_deptno, v_empno, v_sal;
FOR r_emp in emp_cursor LOOP
IF v_sal < 3000 THEN
v_bonus := v_sal * 1.1;
ELSE
v_bonus := v_sal * 1.12;
v_deptno := v_deptno;
v_empno := v_empno;
v_sal := v_sal;
END IF;
INSERT INTO emp3
VALUES(v_empno, v_deptno, v_sal);
FETCH emp_cursor INTO v_deptno, v_empno, v_sal;
END LOOP;
CLOSE emp_cursor;

DBMS_OUTPUT.PUT_LINE(v_deptno || v_empno || v_bonus);

END;
/
SET SERVEROUTPUT OFF
SET VERIFY ON

SQL> @ emp3
DECLARE
*
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 11

我想知道为什么它说我的光标无效。我试图更改必须小于25的值的名称,但是它没有用。

sql oracle sqlplus
2个回答
0
投票

EMP3显然比INSERT命令为(4)提供数据的列少。

检查EMP3表的定义,并确保该表和插入命令可以匹配。

在评论/讨论之后,这是代码更易读的形式(我添加了缩进):

SET SERVEROUTPUT ON
SET VERIFY OFF
DECLARE
    v_deptno empcopy.deptno%TYPE;
    v_empno empcopy.empno%TYPE;
    v_sal empcopy.sal%TYPE;
    v_bonus NUMBER(7,2);

    CURSOR emp_cursor IS
        SELECT deptno, empno, sal
        FROM empcopy
        WHERE v_deptno < 25;
BEGIN
    FETCH emp_cursor INTO v_deptno, v_empno, v_sal;

    FOR r_emp in emp_cursor LOOP

        IF v_sal < 3000 THEN
            v_bonus := v_sal * 1.1;
        ELSE
            v_bonus := v_sal * 1.12;
            v_deptno := v_deptno;
            v_empno := v_empno;
            v_sal := v_sal;
        END IF;

        INSERT INTO emp3
            VALUES(v_empno, v_deptno, v_sal);

        FETCH emp_cursor INTO v_deptno, v_empno, v_sal;
    END LOOP;

    CLOSE emp_cursor;

    DBMS_OUTPUT.PUT_LINE(v_deptno || v_empno || v_bonus);

END;
/
SET SERVEROUTPUT OFF
SET VERIFY ON

此代码显示要做的是:

  • 遍历表EMPCOPY中的每个“雇员”记录>
  • 对于每个记录,检查salary是否低于3000
  • ,并通过将salary乘以1.1来计算奖金
  • 如果salary不小于3000
  • ,则v_bonus1.12计算
  • 此后,应将新值INSERT放入表EMP3

  • 最后,最后插入的记录的值会打印出来。

  • 首先:收入不到3000美元的穷人也只能获得110%的奖金,而本来就比较富裕的员工还能再获得2%的奖金?我知道这是常见的做法,但我主张倡导建立一个更好,更公平的世界-至少在这样的简单编码示例中。

现在输入代码。这段代码应该做什么,根本不需要使用游标。实际上,在这种情况下,这不是一个好习惯。

相反,只需使用普通的SQL即可达到所需的效果:

INSERT INTO EMP3 
    (empno, deptno, sal, bonus)
    (SELECT 
        empno, deptno, sal
        , case 
            when sal < 3000 then sal * 1.1
            else sal * 1.12
          end as bonus 
     FROM 
        empcopy
     WHERE 
        deptno < 25);

这里的警告是目标表EMPCOPY需要具有BONUS的列。缺少此列很可能是原始问题的原因。

还应注意,这种方法不会打印出任何内容。如果这是解决方案的要求,则应在INSERT之后完成(应该在目标表上执行简单的FOR LOOP)。

我希望有帮助。


0
投票

您编写的代码中充满了错误(您已经知道了),在全部命名时都没有意义,但是我会尝试:

© www.soinside.com 2019 - 2024. All rights reserved.