PostgreSQL触发器调用返回表函数报query has no destination错如何解决
问题原因
- PL/pgSQL 中不允许直接执行无结果接收逻辑的
SELECT语句,你在触发器函数中直接写SELECT some_fun(NEW.eid);没有指定结果的存储/返回目标,所以触发query has no destination for result data报错。 - 行级触发器的返回值类型固定为
TRIGGER,仅用于控制触发器的执行逻辑(BEFORE INSERT触发器返回NEW会执行插入,返回NULL会终止插入),无法直接将some_fun返回的表结构数据透传给INSERT语句的调用方。
调整方案
方案1:直接改写INSERT语句(无需触发器,最符合需求)
不需要额外维护触发器,直接在INSERT的RETURNING子句中调用some_fun即可直接得到目标结果:
INSERT INTO SomeTable(some_bool, eid) VALUES (true, 替换为实际传入的eid值) RETURNING some_fun(eid) AS returnColHeader;
方案2:必须使用触发器的场景
如果有强制要求通过触发器执行some_fun,可以通过会话级临时表中转结果:
- 调整触发器函数逻辑:
CREATE OR REPLACE FUNCTION run_some_fun() RETURNS TRIGGER AS $$ BEGIN -- 不存在临时表则创建 IF NOT EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'temp_some_fun_result' AND schemaname = 'pg_temp') THEN CREATE TEMP TABLE temp_some_fun_result (returnColHeader INT); END IF; -- 清空历史结果 TRUNCATE temp_some_fun_result; -- 写入some_fun返回的结果 INSERT INTO temp_some_fun_result(returnColHeader) SELECT returnColHeader FROM some_fun(NEW.eid); -- 返回NEW保证插入正常执行,不需要插入则改为RETURN NULL RETURN NEW; END; $$ LANGUAGE plpgsql;
- 执行INSERT后查询临时表得到结果:
INSERT INTO SomeTable(some_bool, eid) VALUES (true, 替换为实际传入的eid值); SELECT * FROM temp_some_fun_result;
额外注意
你当前写的some_fun逻辑中SELECT eid FROM Joins j1没有关联入参eID的过滤条件,每次调用都会返回Joins表全量的eid值,请根据实际业务需求补充过滤逻辑。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

