Tomislav Muic
Tomislav Muic

Reputation: 543

Updating multiple columns with function call

Supposing I have table with columns a, b, c, d, e

Is there a way/syntax to update columns d and e from out parameters of procedure/function that takes in parameters values of columns a, b and c. (procedure(a, b, c, out d, out e))

(other than using a cursor to iterate through all rows one by one)?

Upvotes: 2

Views: 12167

Answers (3)

V. Kaiser
V. Kaiser

Reputation: 1

Do as follows:

(1) Create and fill an example table:

CREATE TABLE TEST1
(
  a NUMBER(10), b number (10), s number (10)
);
INSERT INTO TEST1 (a, b, s) VALUES (2, 3, NULL);
INSERT INTO TEST1 (a, b, s) VALUES (3, 12, NULL);
INSERT INTO TEST1 (a, b, s) VALUES (-2, 8, NULL);

(2) Create a simple function for the using in an UPDATE command:

CREATE OR REPLACE FUNCTION GET_SUM (x IN NUMBER, y IN NUMBER)
RETURN NUMBER
IS
    x1 NUMBER(10) := x; y1 NUMBER (10):= y; s NUMBER(10) := NULL; 
BEGIN
    IF x1 IS NOT NULL AND y1 IS NOT NULL THEN s := x1 + y1; END IF;
    RETURN s; 
END;

(3) Use this function in the following UPDATE command:

UPDATE TEST1 SET s = GET_SUM (a, b);

(4) Check the updates:

select * from TEST1;

Upvotes: 0

Tomislav Muic
Tomislav Muic

Reputation: 543

With help of an Oracle expert I arrived at following solution:

CREATE TABLE testtable
 ( 
  a number,
  b number,
  c number,
  d number
 );

CREATE TYPE testobj AS OBJECT
(
 x number,
 y number
);


CREATE OR REPLACE FUNCTION testfun(a number, b number)
RETURN testobj IS
begin
    return new testobj(x=>a+b, y=> a*b);
end;


INSERT INTO testtable VALUES (1,2,null,null);
INSERT INTO testtable VALUES (5,6,null,null);


UPDATE 
 (SELECT  tt.*,
               testfun1(a,b) fun_ret FROM testtable tt) talias
 SET talias.c=talias.fun_ret.x,
 talias.d=talias.fun_ret.y
 ;

Upvotes: 0

Sathyajith Bhat
Sathyajith Bhat

Reputation: 21851

You could create a PL/SQL tables or user defined records, like so

Function to process records

FUNCTION Get_updated_recs(p_emp_id     emp.emp_id%TYPE,
                          p_manager_id emp.manager_id%TYPE)
RETURN EMP_REC_TYPE
IS
  p_emp_rec EMP_REC_TYPE;
BEGIN
    IF p_emp_id = 100 THEN
      p_emp_rec.salary := 50000;
      p_emp_rec.bonus := 10000;
    END IF;

    RETURN p_emp_rec;
END get_updated_recs; 

Main program unit

DECLARE
    TYPE emp_rec_type IS RECORD (
      salary employees.salary%TYPE,
      bonus employees.bonus );
    emp_rec EMP_REC_TYPE;
BEGIN
    FOR emp IN (SELECT *
                FROM   employees) LOOP
        emp_rec := Get_updated_recs(emp.emp_id, emp.manager_id);

        UPDATE employees
        SET    salary = emp_rec.salary,
               bonus = emp_rec.bonus
        WHERE  emp_id = emp.emp_id;
    END LOOP;
END; 

I haven't tested/compiled it, just wrote out of my memory but something like this should work

Upvotes: 3

Related Questions