I have two tables. A main table and a sort of "backup" table.
The main table looks like this:
id | name | a | b
int | text | int | int
-------+----------+-------+-------
1 | Joe | 100 | 10
2 | Bill | 200 | 40
3 | Frank | 200 | 20
4 | Jack | 100 | 10
and the backup table looks like this:
id | name1 | a1 | b1 | name2 | a2 | b2 | name3 | a3 | b3
int | text | int | int | text | int | int | text | int | int
-------+----------+-------+-------+--------+------+-----+--------+-----+----
1 | Joe | 100 | 10 | | | | | |
2 | Bill | 200 | 40 | | | | | |
3 | Frank | 200 | 20 | | | | | |
4 | Jack | 100 | 10 | | | | | |
What I would like here is if I update my main table (either the name
or a
or b
column), the values in the backup table should move to the "next" columns. Like name1
to name2
, a1
to a2
, b1
to b2
, name2
to name3
etc. So for example if I update Joe
to Don
, the backup table would look like this:
UPDATE myschema.maintable
SET name = 'Don'
WHERE id = 1;
id | name1 | a1 | b1 | name2 | a2 | b2 | name3 | a3 | b3
int | text | int | int | text | int | int | text | int | int
-------+----------+-------+-------+--------+------+-----+--------+-----+----
1 | Don | 100 | 10 | Joe | 100 | 10 | | |
2 | Bill | 200 | 40 | | | | | |
3 | Frank | 200 | 20 | | | | | |
4 | Jack | 100 | 10 | | | | | |
Now I know that this is a quite bad way to do a backup table, but unfortunately it is beyond my control, and this is how I have to do it.
What I have tried and expected to work is this:
CREATE OR REPLACE FUNCTION table_update_func()
RETURNS TRIGGER AS
$BODY$
BEGIN
UPDATE myschema.backuptable
SET
name3 = name2,
a3 = a2,
b3 = b2,
name2 = name1,
b2 = a1,
b2 = b1,
name1 = name,
a1 = a,
b1 = b
FROM myschema.maintable
WHERE maintable.id = backuptable.id;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
CREATE TRIGGER table_update_trig
BEFORE UPDATE
ON myschema.maintable
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE table_update_func();
If I update something in the maintale
it runs without an error, but it moves the columns in every row, not just the one I updated. Where did I go wrong? I am pretty sure my condition WHERE maintable.id = backup.id;
is not good, but I don't know how should I solve this problem.
You are joining the backup table with every row in the maintable that's why you always update all rows in the backup table. You don't need a FROM clause there, as you have the ID of the UPDATE row available in the new
record.
CREATE OR REPLACE FUNCTION table_update_func()
RETURNS TRIGGER AS
$BODY$
BEGIN
UPDATE myschema.backuptable
SET name3 = name2,
a3 = a2,
b3 = b2,
name2 = name1,
b2 = a1,
b2 = b1,
name1 = new.name, -- reference the values of the new record here
a1 = new.a,
b1 = new.b
WHERE backuptable.id = new.id; --<< no FROM clause necessary
RETURN new; --<< IMPORTANT for a BEFORE UPDATE trigger!
END;
$BODY$
LANGUAGE plpgsql VOLATILE
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.