我希望能够调用
set_config
在与 INSERT 语句相同的事务/范围内设置配置参数。插入后会触发一个函数,该函数会从此配置参数中读取数据。
我需要将其作为单个语句来完成,因此 CTE 似乎是一个好主意:
WITH
idx AS (SELECT set_config('audit.trace_id', '123', true)),
rows AS (INSERT INTO "person" ("name") values ('Mary') RETURNING *)
SELECT * FROM rows
但是,似乎
audit.trace_id
无法用于触发功能。所以我想我应该像下面这样构造它,这应该创建一个依赖项:
WITH
idx AS (SELECT set_config('audit.trace_id', '123', true))
INSERT INTO "person" ("name") values ('Mary') RETURNING *
但是,
audit.trace_id
中的值仍然没有设置在触发函数的范围内。我相信这是因为 Postgre 避免运行 SELECT,因为结果不需要进一步进入 CTE。
如果我从两者中选择,如下所示,则当触发函数运行时
audit.trace_id
已成功设置:
WITH
idx AS (SELECT set_config('audit.trace_id', '123', true) as __trace_id),
row as (INSERT INTO "person" ("name") values ('Mary') RETURNING *)
SELCET * FROM idx, row
问题
“audit.trace_id”是否保证在触发器在 person 表上执行时设置?或者这里是否存在可能的竞争条件?
编辑:
这个呢?看起来效果不错:
INSERT INTO "person" ("name") values ('Mary') RETURNING *, set_config('audit.trace_id', '123', true)
在 PostgreSQL 中,在公用表表达式 (CTE) 中,不保证查询按照编写的顺序执行,它们由 PostgreSQL 引擎优化,并且可能并行执行或以不同的顺序执行。不出所料。
但是,WITH
INSERT INTO "person" ("name") values ('Mary') RETURNING *, set_config('audit.trace_id', '123', true)
将是确保在触发器函数执行之前设置配置参数'audit.trace_id'
的最可靠方法,因为它在
INSERT
语句的
RETURNING
子句中设置配置参数,本质上使其成为数据修改语句的一部分,确保它在同一事务内且在任何
AFTER INSERT
触发之前执行。