Ваша ошибка из-за отсутствия переменной 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;
/
Тогда ваша процедура сработает (за исключением случаев, когда зарплата составляет 10 000).
Однако вы все равно можете сделать ее более эффективен, избавившись от курсора:
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;
/
дБ <> скрипка