你写的代码充满了错误(你已经知道了),我不知道我是否会全部抓住它们,但我会尝试:
- 光标选择
v_deptno < 25的数据。但是,v_deptno 看起来像一个本地声明的变量(您声明的第一个变量),所以 - 除非有一个名为 v_deptno 的列,否则它将失败。
- 此外,将
deptno 值硬编码为“25”根本无法扩展。我建议您切换到接受部门编号作为参数的存储过程
- 第一个可执行行是
FETCH,但它应该是OPEN(如果你选择做所有事情
- 手动:
- 声明一个游标
- 声明游标变量(或单独的变量,就像你做的那样)
- 打开光标
- 循环
- 从游标中获取
- 光标%未找到时退出
- 做某事
- 结束循环
- 关闭光标
- 或者,更好的是,使用游标
FOR 循环,Oracle 会为您完成所有 dirty 工作:
-
FOR 光标在(SELECT 语句)LOOP
- 做某事
- 结束循环
- 当您检查薪水时(在
IF),ELSE 是......非常奇怪。 v_deptno := v_deptno;(以及您设置的其他 3 个变量)的用途是什么?
-
INSERT 声明:它缺少您要插入的列列表。这不是一个错误(如果你做错了可能会失败),但是 - 它令人困惑,特别是当涉及到许多列时)。
- 但是,您插入的是
V_SAL。好的。那你为什么要计算V_BONUS?你从来没有使用过它(DBMS_OUTPUT 除外,但它只是显示值,就数据库中的数据而言,从来没有用它做任何事情)
好的,如果可以的话,现在我的尝试。
首先,您编写的代码,已修复(我正在插入 V_BONUS 值):
SQL> declare
2 v_bonus number;
3 begin
4 for cur_r in (select deptno, empno, sal
5 from empcopy
6 where deptno < 25
7 )
8 loop
9 if cur_r.sal < 3000 then
10 v_bonus := cur_r.sal * 1.1;
11 else
12 v_bonus := cur_r.sal * 1.12;
13 end if;
14
15 insert into emp3 (empno, deptno, sal)
16 values (cur_r.empno, cur_r.deptno, v_bonus);
17 end loop;
18 end;
19 /
PL/SQL procedure successfully completed.
SQL> select * From emp3;
EMPNO DEPTNO SAL
---------- ---------- ----------
7369 20 1100
7566 20 3272,5
7782 10 2695
7788 20 3360
7839 10 5600
7876 20 1210
7902 20 3360
7934 10 1430
8 rows selected.
SQL>
但是,这可以在 SQL 层使用单个 INSERT 语句来完成,您根本不需要 PL/SQL。所以,除非你只是在练习你的 PL/SQL 技能,否则我建议你使用这个选项:
SQL> rollback;
Rollback complete.
SQL> insert into emp3 (empno, deptno, sal)
2 select empno,
3 deptno,
4 case when sal < 3000 then sal * 1.1
5 else sal * 1.12
6 end
7 from empcopy
8 where deptno < 25;
8 rows created.
SQL> select * From emp3;
EMPNO DEPTNO SAL
---------- ---------- ----------
7369 20 1100
7566 20 3272,5
7782 10 2695
7788 20 3360
7839 10 5600
7876 20 1210
7902 20 3360
7934 10 1430
8 rows selected.
SQL>
最后,我在开始时建议的存储过程选项;而不是 where 子句中的 <,使用 =。
SQL> create or replace procedure p_bonus (par_deptno in empcopy.deptno%type)
2 is
3 v_bonus number;
4 begin
5 for cur_r in (select deptno, empno, sal
6 from empcopy
7 where deptno = par_deptno --> "=" instead of "<"
8 )
9 loop
10 if cur_r.sal < 3000 then
11 v_bonus := cur_r.sal * 1.1;
12 else
13 v_bonus := cur_r.sal * 1.12;
14 end if;
15
16 insert into emp3 (empno, deptno, sal)
17 values (cur_r.empno, cur_r.deptno, v_bonus);
18 end loop;
19 end;
20 /
Procedure created.
SQL> begin
2 p_bonus (par_deptno => 25);
3 end;
4 /
PL/SQL procedure successfully completed.