To answer the question
You can SET
a (customized option) like this:
SET myvar.role_id = '123';
But that requires a literal value. There is also the function set_config()
. Quoting the manual:
set_config(setting_name, new_value, is_local)
... set parameter and return new value
set_config
sets the parameter setting_name
to new_value
. If is_local
is true
, the new value will only apply to the current transaction.
Correspondingly, read option values with SHOW
or current_setting()
. Related:
But your trigger is on the wrong table (tbl_executor
) with wrong syntax. Looks like Oracle code, where you can provide code to CREATE TRIGGER
directly. In Postgres you need a trigger function first:
So:
CREATE OR REPLACE FUNCTION trg_log_who()
RETURNS trigger AS
$func$
BEGIN
INSERT INTO tbl_log(executor, op)
VALUES(current_setting('myvar.role_id')::int, TG_OP); -- !
RETURN NULL; -- irrelevant for AFTER trigger
END
$func$ LANGUAGE plpgsql;
Your example setup requires the a type cast ::int
.
Then:
CREATE TRIGGER trg_log_who
AFTER INSERT OR UPDATE OR DELETE ON tbl_other -- !
FOR EACH ROW EXECUTE PROCEDURE trg_log_who(); -- !
Finally, fetching id
from the table tbl_executor
to set the variable:
BEGIN;
SELECT set_config('myvar.role_id', id::text, true) -- !
FROM tbl_executor
WHERE name = current_user;
INSERT INTO tbl_other VALUES( ... );
INSERT INTO tbl_other VALUES( ... );
-- more?
COMMIT;
Set the the third parameter (is_local
) of set_config()
to true
to make it session-local as requested. (The equivalent of SET LOCAL
.)
But why per row? Would seem more reasonable to make it per statement?
...
FOR EACH STATEMENT EXECUTE PROCEDURE trg_foo();
Different approach
All that aside, I'd consider a different approach: a simple function returning the id
a column default:
CREATE OR REPLACE FUNCTION f_current_role_id()
RETURNS int LANGUAGE sql STABLE AS
'SELECT id FROM tbl_executor WHERE name = current_user';
CREATE TABLE tbl_log (
executor int DEFAULT f_current_role_id() REFERENCES tbl_executor(id)
, op VARCHAR
);
Then, in the trigger function, ignore the executor
column; will be filled automatically:
...
INSERT INTO tbl_log(op) VALUES(TG_OP);
...
Be aware of the difference between current_user
and session_user
. See: