PL/SQL 为员工分配等级的程序
PL/SQL procedure to assign grades to the employees
create or replace procedure p2
as
CURSOR c1 IS
SELECT salary
FROM employee1
FOR UPDATE;
BEGIN
FOR employee_rec IN c1 LOOP
exit when c1%notfound;
if salary>20000 then
update employee1 set grade='A' WHERE CURRENT OF c1;
if salary>15000 then
update employee1 set grade='B' WHERE CURRENT OF c1;
if salary>10000 then
update employee1 set grade='C' WHERE CURRENT OF c1;
if salary<10000 then
update employee1 set grade='D' WHERE CURRENT OF c1;
end if;
end if;
end if;
end if;
END LOOP;
END p2;
错误显示为薪水未申报我怎样才能使这段代码更好以获得所需的输出???
不是
if salary>20000 then
但是
if employee_rec.salary>20000 then
您编写的代码可以简化 - 最多只需要一个 UPDATE
语句。但是,如果您使用 PL/SQL 进行学习,CASE
可能是比嵌套 IF
更好的选择。类似于此示例的内容基于 Scott EMP
table.
的子集
测试数据:
SQL> create table test as
2 select empno, ename, sal, 'x' grade
3 from emp
4 where deptno = 10;
Table created.
SQL> select * from test order by sal desc;
EMPNO ENAME SAL G
---------- ---------- ---------- -
7839 KING 5000 x
7782 CLARK 2450 x
7934 MILLER 1300 x
程序、测试和结果:
SQL> create or replace procedure p2 as
2 cursor c1 is select sal from test for update;
3 begin
4 for employee_rec in c1 loop
5 update test set
6 grade = case when employee_rec.sal > 3000 then 'A'
7 when employee_rec.sal > 2000 then 'B'
8 when employee_rec.sal > 1000 then 'C'
9 when employee_rec.sal <= 1000 then 'D'
10 end
11 where current of c1;
12 end loop;
13 end;
14 /
Procedure created.
SQL> exec p2;
PL/SQL procedure successfully completed.
SQL> select * From test order by sal desc;
EMPNO ENAME SAL G
---------- ---------- ---------- -
7839 KING 5000 A
7782 CLARK 2450 B
7934 MILLER 1300 C
SQL>
为什么不简单地这样:
update employee1 set grade=
case
when salary>20000 then 'A'
when salary>15000 then 'B'
when salary>10000 then 'C'
when salary<10000 then 'D'
ELSE grade -- keep existing grade value
end;
你的错误是因为没有变量salary
。您有一个名为 employee_rec
的游标,其中包含一个名为 salary
的列,但您需要使用 employee_rec.salary
.
来引用它
如果我们修复它(并缩进您的代码)然后它会编译:
CREATE PROCEDURE p2 AS
CURSOR c1 IS
SELECT salary
FROM employee1
FOR UPDATE;
BEGIN
FOR employee_rec IN c1 LOOP
EXIT WHEN c1%NOTFOUND;
IF employee_rec.salary>20000 THEN
update employee1 set grade='A' WHERE CURRENT OF c1;
IF employee_rec.salary>15000 THEN
update employee1 set grade='B' WHERE CURRENT OF c1;
IF employee_rec.salary>10000 THEN
update employee1 set grade='C' WHERE CURRENT OF c1;
IF employee_rec.salary<10000 THEN
update employee1 set grade='D' WHERE CURRENT OF c1;
END IF;
END IF;
END IF;
END IF;
END LOOP;
END p2;
/
但是,由于嵌套的 IF
语句,它不会为您提供所需的输出。如果将嵌套的 IF
语句替换为 ELSIF
:
CREATE OR REPLACE PROCEDURE p2 AS
CURSOR c1 IS
SELECT salary
FROM employee1
FOR UPDATE;
BEGIN
FOR employee_rec IN c1 LOOP
EXIT WHEN c1%NOTFOUND;
IF employee_rec.salary>20000 THEN
update employee1 set grade='A' WHERE CURRENT OF c1;
ELSIF employee_rec.salary>15000 THEN
update employee1 set grade='B' WHERE CURRENT OF c1;
ELSIF employee_rec.salary>10000 THEN
update employee1 set grade='C' WHERE CURRENT OF c1;
ELSIF employee_rec.salary<10000 THEN
update employee1 set grade='D' WHERE CURRENT OF c1;
END IF;
END LOOP;
END p2;
/
那你的程序就可以了(工资是10000的时候除外)。
但是,您仍然可以通过删除游标来提高效率:
CREATE OR REPLACE PROCEDURE p2 AS
BEGIN
UPDATE employee1
SET grade = CASE
WHEN salary > 20000 THEN 'A'
WHEN salary > 15000 THEN 'B'
WHEN salary > 10000 THEN 'C'
ELSE 'D'
END;
END p2;
/
create or replace procedure p2
as
CURSOR c1 IS
SELECT salary
FROM employee1
FOR UPDATE;
BEGIN
FOR employee_rec IN c1 LOOP
exit when c1%notfound;
if salary>20000 then
update employee1 set grade='A' WHERE CURRENT OF c1;
if salary>15000 then
update employee1 set grade='B' WHERE CURRENT OF c1;
if salary>10000 then
update employee1 set grade='C' WHERE CURRENT OF c1;
if salary<10000 then
update employee1 set grade='D' WHERE CURRENT OF c1;
end if;
end if;
end if;
end if;
END LOOP;
END p2;
错误显示为薪水未申报我怎样才能使这段代码更好以获得所需的输出???
不是
if salary>20000 then
但是
if employee_rec.salary>20000 then
您编写的代码可以简化 - 最多只需要一个 UPDATE
语句。但是,如果您使用 PL/SQL 进行学习,CASE
可能是比嵌套 IF
更好的选择。类似于此示例的内容基于 Scott EMP
table.
测试数据:
SQL> create table test as
2 select empno, ename, sal, 'x' grade
3 from emp
4 where deptno = 10;
Table created.
SQL> select * from test order by sal desc;
EMPNO ENAME SAL G
---------- ---------- ---------- -
7839 KING 5000 x
7782 CLARK 2450 x
7934 MILLER 1300 x
程序、测试和结果:
SQL> create or replace procedure p2 as
2 cursor c1 is select sal from test for update;
3 begin
4 for employee_rec in c1 loop
5 update test set
6 grade = case when employee_rec.sal > 3000 then 'A'
7 when employee_rec.sal > 2000 then 'B'
8 when employee_rec.sal > 1000 then 'C'
9 when employee_rec.sal <= 1000 then 'D'
10 end
11 where current of c1;
12 end loop;
13 end;
14 /
Procedure created.
SQL> exec p2;
PL/SQL procedure successfully completed.
SQL> select * From test order by sal desc;
EMPNO ENAME SAL G
---------- ---------- ---------- -
7839 KING 5000 A
7782 CLARK 2450 B
7934 MILLER 1300 C
SQL>
为什么不简单地这样:
update employee1 set grade=
case
when salary>20000 then 'A'
when salary>15000 then 'B'
when salary>10000 then 'C'
when salary<10000 then 'D'
ELSE grade -- keep existing grade value
end;
你的错误是因为没有变量salary
。您有一个名为 employee_rec
的游标,其中包含一个名为 salary
的列,但您需要使用 employee_rec.salary
.
如果我们修复它(并缩进您的代码)然后它会编译:
CREATE PROCEDURE p2 AS
CURSOR c1 IS
SELECT salary
FROM employee1
FOR UPDATE;
BEGIN
FOR employee_rec IN c1 LOOP
EXIT WHEN c1%NOTFOUND;
IF employee_rec.salary>20000 THEN
update employee1 set grade='A' WHERE CURRENT OF c1;
IF employee_rec.salary>15000 THEN
update employee1 set grade='B' WHERE CURRENT OF c1;
IF employee_rec.salary>10000 THEN
update employee1 set grade='C' WHERE CURRENT OF c1;
IF employee_rec.salary<10000 THEN
update employee1 set grade='D' WHERE CURRENT OF c1;
END IF;
END IF;
END IF;
END IF;
END LOOP;
END p2;
/
但是,由于嵌套的 IF
语句,它不会为您提供所需的输出。如果将嵌套的 IF
语句替换为 ELSIF
:
CREATE OR REPLACE PROCEDURE p2 AS
CURSOR c1 IS
SELECT salary
FROM employee1
FOR UPDATE;
BEGIN
FOR employee_rec IN c1 LOOP
EXIT WHEN c1%NOTFOUND;
IF employee_rec.salary>20000 THEN
update employee1 set grade='A' WHERE CURRENT OF c1;
ELSIF employee_rec.salary>15000 THEN
update employee1 set grade='B' WHERE CURRENT OF c1;
ELSIF employee_rec.salary>10000 THEN
update employee1 set grade='C' WHERE CURRENT OF c1;
ELSIF employee_rec.salary<10000 THEN
update employee1 set grade='D' WHERE CURRENT OF c1;
END IF;
END LOOP;
END p2;
/
那你的程序就可以了(工资是10000的时候除外)。
但是,您仍然可以通过删除游标来提高效率:
CREATE OR REPLACE PROCEDURE p2 AS
BEGIN
UPDATE employee1
SET grade = CASE
WHEN salary > 20000 THEN 'A'
WHEN salary > 15000 THEN 'B'
WHEN salary > 10000 THEN 'C'
ELSE 'D'
END;
END p2;
/