Question

I am using SQLFiddle for an assignment to learn about procedures and cursors. I know that cursors are not the best thing to use and there are better ways to accomplish what I am trying to do but I am required to use procedures and cursors.

I want the procedure to ultimately update the Total_sal of each department based on the employees that belong to that department.

Right now it is not doing that, and I don't really have enough knowledge or experience with Postgres to properly debug it.

The Total_sal's of the departments after the updateSalary() procedure should look like:

dept_no    total_sal

10          7000
20          7000
30          6000

Here is the Fiddle I am working with: http://sqlfiddle.com/#!15/140d5/3

And the updatSalary procedure looks like:

CREATE OR REPLACE FUNCTION updateSalary() RETURNS VOID AS
$BODY$
  DECLARE 
  sum INTEGER := 0;
  dep CURSOR FOR SELECT Dno FROM Department;
  dep_row Department%ROWTYPE;
  emp CURSOR(dept_Dno INTEGER) FOR
    SELECT Dno, Salary FROM Employee WHERE Dno = dept_Dno;
  emp_row Employee%ROWTYPE;
BEGIN
  open dep;
  LOOP
    FETCH dep into dep_row;
      exit when NOT FOUND;
    open emp( dep_row.Dno );
    LOOP
      FETCH emp into emp_row;
        exit when NOT FOUND;
         sum := sum + emp_row.salary;
     END LOOP;
    UPDATE department SET total_sal = sum WHERE department.dno = emp_row.dno;
    close emp;
    sum := 0;
  END LOOP;
  close dep;
END;
$BODY$
  LANGUAGE plpgsql;
Was it helpful?

Solution

You should use 'FOR ... IN ... LOOP' statement (Cursors in documentation, see 40.7.4.)

CREATE OR REPLACE FUNCTION updateSalary() RETURNS VOID AS
$BODY$
  DECLARE 
  total INTEGER := 0;
  dep CURSOR FOR SELECT Dno FROM Department;
  dep_row Department%ROWTYPE;
  emp CURSOR(dept_Dno INTEGER) FOR
    SELECT Dno, Salary FROM Employee WHERE Dno = dept_Dno;
  emp_row Employee%ROWTYPE;
BEGIN
    FOR dep_row IN dep
    LOOP
        FOR emp_row IN emp( dep_row.Dno )
        LOOP
            total := total + emp_row.salary;
        END LOOP;
        UPDATE department SET total_sal = total WHERE department.dno = dep_row.dno;
        total := 0;
    END LOOP;
END;
$BODY$ LANGUAGE plpgsql;

(sum is a name of aggregate function; better not to use as variable name)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top