Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UPDATE a whole row in PL/pgSQL

I have plpgsql function:

CREATE OR REPLACE FUNCTION test() RETURNS VOID AS
$$
DECLARE
    my_row my_table%ROWTYPE;
BEGIN
    SELECT * INTO my_row FROM my_table WHERE id='1';
    my_row.date := now();
END;
$$ LANGUAGE plpgsql;

I would like to know if it's possible to directly UPDATE my_row record.

The only way I've found to do it now is:

UPDATE my_table SET date=now() WHERE id='1';

Note this is only an example function, the real one is far more complex than this.

I'm using PostgreSQL 9.2.

UPDATE:

Sorry for the confusion, what I wanted to say is:

SELECT * INTO my_row FROM my_table INTO my_row WHERE id='1';
make_lots_of_complicated_modifications_to(my_row, other_complex_parameters);
UPDATE my_row;

I.e. Use my_row to persist information in the underlying table. I have lots of parameters to update.

like image 604
Jeroni Avatar asked Sep 21 '12 10:09

Jeroni


People also ask

Which command is used to modify the rows in PostgreSQL?

In PostgreSQL, the UPDATE command is used to change the present records in a table. To update the selected rows, we have to use the WHERE clause; otherwise, all rows would be updated.

How do you update a specific column in PostgreSQL?

Syntax. UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition]; You can combine N number of conditions using AND or OR operators.

How update works in Postgres?

PostgreSQL implements multiversioning by keeping the old version of the table row in the table – an UPDATE adds a new row version (“tuple”) of the row and marks the old version as invalid. In many respects, an UPDATE in PostgreSQL is not much different from a DELETE followed by an INSERT .


1 Answers

I would like to know if it's possible to directly update "my_row" record.

It is.
You can update columns of a row or record type in plpgsql - just like you have it. It should be working, obviously?

This would update the underlying table, of course, not the variable!

UPDATE my_table SET date=now() WHERE id='1';

You are confusing two things here ...


Answer to clarification in comment

I don't think there is syntax in PostgreSQL that can UPDATE a whole row. You can UPDATE a column list, though. Consider this demo:

Note how I use thedate instead of date as column name, date is a reserved word in every SQL standard and a type name in PostgreSQL.

CREATE TEMP TABLE my_table (id serial, thedate date);
INSERT INTO my_table(thedate) VALUES (now());

CREATE OR REPLACE FUNCTION test_up()
  RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
    _r my_table;
BEGIN
   SELECT * INTO _r FROM my_table WHERE id = 1;
   _r.thedate := now()::date + 5 ;

   UPDATE my_table t
    -- explicit list of columns to be to updated
   SET   (id, thedate) = (_r.id, _r.thedate)
   WHERE  t.id = 1;
END
$func$;

SELECT test_up();
SELECT * FROM my_table;

However, you can INSERT a whole row easily. Just don't supply a column list for the table (which you normally should, but in this case it is perfectly ok, not to).

As an UPDATE is internally a DELETE followed by an INSERT anyway, and a function automatically encapsulates everything in a transaction, I don't see, why you couldn't use this instead:

CREATE OR REPLACE FUNCTION x.test_ delins()
  RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
    _r my_table;
BEGIN
   SELECT * INTO _r
   FROM my_table WHERE id = 1;
   _r.thedate := now()::date + 10;

   DELETE FROM my_table t WHERE t.id = 1;
   INSERT INTO my_table SELECT _r.*;
END
$func$;
like image 70
Erwin Brandstetter Avatar answered Sep 29 '22 16:09

Erwin Brandstetter