I have a table called assignments. I would like to be able to read/write to all the columns in this table using either assignments.column or homework.column, how can I do this?<
Building on your work in progress:
CREATE OR REPLACE FUNCTION trg_ia_insupdel()
RETURNS TRIGGER AS
$func$
DECLARE
_tbl CONSTANT regclass := 'iassignments_assignments';
_cols text;
_vals text;
BEGIN
CASE TG_OP
WHEN 'INSERT' THEN
INSERT INTO iassignments_assignments
VALUES NEW;
RETURN NEW;
WHEN 'UPDATE' THEN
SELECT INTO _cols, _vals
string_agg(quote_ident(attname), ', ') -- incl. pk col!
,string_agg('n.' || quote_ident(attname), ', ')
FROM pg_attribute
WHERE attrelid = _tbl -- _tbl converted to oid automatically
AND attnum > 0 -- no system columns
AND NOT attisdropped; -- no dropped (dead) columns
EXECUTE format('
UPDATE %s t
SET (%s) = (%s)
FROM (SELECT ($1).*) n
WHERE t.published_assignment_id
= ($2).published_assignment_id' -- match to OLD value of pk
, _tbl, _cols, _vals) -- _tbl converted to text automatically
USING NEW, OLD;
RETURN NEW;
WHEN 'DELETE' THEN
DELETE FROM iassignments_assignments
WHERE published_assignment_id = OLD.published_assignment_id;
RETURN OLD;
END CASE;
RETURN NULL; -- control should never reach this
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER insupbef
INSTEAD OF INSERT OR UPDATE OR DELETE ON assignments_published
FOR EACH ROW EXECUTE PROCEDURE trg_ia_insupdel();
Dynamic SQL (in the UPDATE
section) is not strictly necessary, only to cover future changes to the table layout automatically. The names of the table and the pk are still hard coded.
plpgsql assignment operator is :=
Simpler and probably cheaper without sub-block (like you had).
Using (SELECT ($1).*)
instead of the shorter VALUES $1
to preserve column names.
My naming convention: I prepend trg_
for trigger functions, followed by an abbreviation indicating the target table and finally one or more of the the tokens ins
, up
and del
for INSERT
, UPDATE
and DELETE
respectively. The name of the trigger is a copy of the function name, stripped of the first two parts. This is purely a matter of convention and taste but has proven useful for me since the names tell the purpose and are still short enough.
More explanation in the related answer that has already been mentioned:
Update multiple columns in a trigger function in plpgsql