为什么 postgres 触发函数 returns 某些列引用不明确?

Why postgres trigger function returns some columns reference is ambiguous?

我有两个 table: 来源 table 我在其中插入或更新值

CREATE TABLE test.table_1
(
    id smallint NOT NULL DEFAULT nextval('test.table_1_id_seq'::regclass),
    sub_id smallint,
    value numeric(5,5)
)

TABLESPACE pg_default;

ALTER TABLE test.table_1
    OWNER to postgres;

我需要获取新值和旧值之间的差异,并在更新时将其添加到 table_1_sum 中的 sum_value。 或者如果 idsub_id 已经存在于 table_1_sum

中,则需要插入新行
CREATE TABLE test.table_1_sum
(
    id smallint,
    sub_id smallint,
    sum_value numeric(5,5),
    CONSTRAINT unq_constraint UNIQUE (id, sub_id)
)

TABLESPACE pg_default;

ALTER TABLE test.table_1_sum
    OWNER to postgres;

我用触发器做了一个函数来做这个

CREATE FUNCTION test.add_diff()
    RETURNS trigger
    LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
        delta_value   numeric;      
    BEGIN      
        IF (TG_OP = 'UPDATE') THEN            
            delta_value = NEW.value - OLD.value;        
        ELSIF (TG_OP = 'INSERT') THEN       
            delta_value = NEW.value;        
        ELSIF (TG_OP = 'DELETE') THEN       
            delta_value = -1 * OLD.value;       
        END IF;         
            INSERT INTO test.table_1_sum (
                sub_id,
                sum_value
                )
            VALUES (
                NEW.sub_id,
                NEW.value               
               )
                ON CONFLICT ON CONSTRAINT unq_constraint
                DO UPDATE 
                    SET 
                    sum_value = sum_value + delta_value;    
        RETURN NULL;
    END;
$BODY$;
ALTER FUNCTION test.add_diff()
    OWNER TO postgres;
    
    
CREATE TRIGGER add_value_diff
    AFTER INSERT OR DELETE OR UPDATE 
    ON test.table_1
    FOR EACH ROW
    EXECUTE PROCEDURE test.add_diff();

它不起作用。我不知道为什么。

它returns一个错误:

ERROR: column reference "sum_value" is ambiguous LINE 13: sum_value = sum_value + delta_value

我哪里错了?

demo:db<>fiddle

您必须在计算中明确引用 table_1_sum

sum_value = table_1_sum.sum_value + delta_value; 

有一个名为 EXCLUDED 的“虚拟”table 包含应插入值的行(当 INSERT 具有 ON CONFLICT DO 子句时)。此虚拟 table 与目标 table 具有相同的结构(相同的列),因此列的名称不是唯一的。

您可以在相关的 Postgres 中阅读更多详细信息 documentation