I'm stanqued in sequence of PL/SQL procedure I need to do a procedure that receives as parameters a department number, a salary, and a percentage; and to raise the salary of all employees of the department indicated in the call. The increase will be the percentage or salary indicated in the call (whichever is more beneficial for the employee in each case). I have this code but doesn't work.
CREATE OR REPLACE PROCEDURE pujarSalari (numdept number,diners number,percentatge number)
AS
souapujar number(10);
CURSOR buscarnoms IS SELECT codi_emp FROM empleats WHERE codi_dept=numdept;
BEGIN
OPEN buscarnoms;
FETCH buscarnoms INTO souapujar;
WHILE buscarnoms%FOUND LOOP
IF (empleats.sou*(1+percentatge/100))>=(empleats.sou+diners) THEN
UPDATE empleats set empleats.sou=empleats.sou*(1+percentatge/100) where codi_emp=souapujar;
ELSE
UPDATE empleats set empleats.sou=empleats.sou+diners where codi_emp=souapujar;
END IF;
FETCH buscarnoms INTO souapujar;
END LOOP;
CLOSE buscarnoms;
END;
And the error code is
Procedure PUJARSALARI compilado
LINE/COL ERROR
--------- -------------------------------------------------------------
9/1 PL/SQL: Statement ignored
9/14 PLS-00357: Table,View Or Sequence reference 'EMPLEATS.SOU' not allowed in this context
Errores: comprobar log de compilador
Your IF statements are referencing table columns . In PL/SQL we can only reference variables (including implicit cursors). (That is outside of embedded SQL statements.)
You have a cursor buscarnoms
which selects from empleats
but doesn't include all the columns you need. So you must change the cursor projection then reference the cursor in your code.
CREATE OR REPLACE PROCEDURE pujarSalari
(numdept number,
diners number,
percentatge number)
AS
CURSOR buscarnoms IS
SELECT *
FROM empleats
WHERE codi_dept = numdept;
souapujar buscarnoms%rowtype; -- inherits the projection of the cursor
BEGIN
OPEN buscarnoms;
FETCH buscarnoms INTO souapujar;
WHILE buscarnoms%FOUND LOOP
IF (souapujar.sou*(1+percentatge/100)) >= (souapujar.sou+diners) THEN
UPDATE empleats
set empleats.sou = empleats.sou*(1+percentatge/100)
where codi_emp = souapujar.codi_emp;
ELSE
UPDATE empleats
set empleats.sou = empleats.sou+diners
where codi_emp = souapujar.codi_emp;
END IF;
FETCH buscarnoms INTO souapujar;
END LOOP;
CLOSE buscarnoms;
END;
There are several ways to simplify this code, for instance by replacing the explicit cursor with an implicit cursor. Or even replacing the cursor loop with a set-based update statement. But I have left the code as close to the original as possible, to highlight the solution to the problem as presented.
You say that are several ways to simplify the code. How can i simplify my code?
Implicit cursor:
CREATE OR REPLACE PROCEDURE pujarSalari
(numdept number,
diners number,
percentatge number)
AS
BEGIN
FOR buscarnoms in (SELECT *
FROM empleats
WHERE codi_dept = numdept)
LOOP
IF (souapujar.sou*(1+percentatge/100)) >= (souapujar.sou+diners) THEN
UPDATE empleats
set empleats.sou = empleats.sou*(1+percentatge/100)
where codi_emp = souapujar.codi_emp;
ELSE
UPDATE empleats
set empleats.sou = empleats.sou+diners
where codi_emp = souapujar.codi_emp;
END IF;
END LOOP;
END;
Set-based:
CREATE OR REPLACE PROCEDURE pujarSalari
(numdept number,
diners number,
percentatge number)
AS
BEGIN
UPDATE empleats
set sou = greatest(empleats.sou + diners,
empleats.sou * (1+percentatge/100) )
where codi_dept = numdept;
END;
Well that actually is a different question and should be posed that way. But how about max simplification. Reduce it to a single statement:
create or replace procedure pujarsalari
(numdept number,
diners number,
percentatge number)
as
begin
update empleats
set sou = greatest(sou*(1+percentatge/100), sou+diners)
where codi_dept = numdept;
end pujarsalari;
Tip of the day: In SQL stop thinking in terms of individual rows. Think instead of the set of all rows at one time.
NOTE: Not tested as you did not see fit to post neither sample data not table definitions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.