patternsqlModerate
Assign to NEW by key in a Postgres trigger
Viewed 0 times
triggernewpostgresassignkey
Problem
In the trigger body, how can I assign a value to
That's what I want to do:
NEW by it's field name?That's what I want to do:
some_key = "some_column";
NEW[some_key] = 5;Solution
First of all, there is no "trigger body" (unlike Oracle). In Postgres you have a trigger function (also, misleadingly, called "procedure") with a function body and 0-n triggers (without body) calling this function.
The special variable
Data type
unassigned in statement-level triggers and for
Assigning to a field (or column) of
What you seem to be looking for is to parameterize the column name, which isn't quite as simple.
The additional module
Then you can:
Sets the column
Related answer with details and an alternative solution:
Code example
Postgres 11 or later allows to replace the misleding term
The special variable
NEW in plpgsql trigger functions is neither a map nor an array; it's a record holding the new row:NEWData type
RECORD; variable holding the new database row forINSERT/UPDATE operations in row-level triggers. This variable isunassigned in statement-level triggers and for
DELETE operations.Assigning to a field (or column) of
NEW is simple. The documented assignment operator is :=. (Since Postgres 9.4 also =.)NEW.some_key := 5;What you seem to be looking for is to parameterize the column name, which isn't quite as simple.
The additional module
hstore provides the #= operator. (It's included in pretty much all standard distributions.) Install the module once per database with:CREATE EXTENSION hstore;Then you can:
NEW := NEW #= '"some_key"=>"5"'::hstore;Sets the column
some_key to '5' - if the column exists.- An explicit cast to
hstoreis optional. The operator#=coerces a string literal to the right data type automatically.
hstoreonly stores text strings, so a given literal for the value may have to be cast twice - a very minor drawback compared to alternative solutions.
- The given string literal has to fit the data type of the column, or an exception is raised.
- If no column with the given name exists, nothing is changed, no exception raised.
Related answer with details and an alternative solution:
- How to set value of composite variable field using dynamic SQL
Code example
CREATE OR REPLACE FUNCTION trg_tbl_ins_bef()
RETURNS trigger AS
$func$
BEGIN
NEW := NEW #= '"some_key"=>"5"';
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER ins_bef
BEFORE INSERT ON tbl
FOR EACH ROW EXECUTE PROCEDURE trg_tbl_ins_bef();Postgres 11 or later allows to replace the misleding term
PROCEDURE (the old syntax will keep working for the foreseeable future):...
FOR EACH ROW EXECUTE FUNCTION trg_tbl_ins_bef();Code Snippets
NEW.some_key := 5;CREATE EXTENSION hstore;NEW := NEW #= '"some_key"=>"5"'::hstore;CREATE OR REPLACE FUNCTION trg_tbl_ins_bef()
RETURNS trigger AS
$func$
BEGIN
NEW := NEW #= '"some_key"=>"5"';
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER ins_bef
BEFORE INSERT ON tbl
FOR EACH ROW EXECUTE PROCEDURE trg_tbl_ins_bef();...
FOR EACH ROW EXECUTE FUNCTION trg_tbl_ins_bef();Context
StackExchange Database Administrators Q#82039, answer score: 16
Revisions (0)
No revisions yet.