对于PostgreSQL中的函数中的INSERT ON CONFLICT UPDATE,列引用不明确

时间:2019-09-16 11:44:47

标签: postgresql

我有一个由来源提供的表格:

create table person (
    id serial not null,
    name varchar(50) not null unique,
    age int not null,
    constraint person_pkey primary key (id)
)

我想定义一个函数my_func,该函数插入新记录或使用给定记录更新年龄。我是这样实现的:

create or replace function my_func(name varchar(50), age int) returns void as $$
begin
    insert into person ("name", "age") values (my_func.name, my_func.age)
    on conflict ("name") do update
    set age = my_func.age
    where person.name = my_func.name;
end
$$ language plpgsql;

它给了我错误:

my_func('Alex', 31);

ERROR: column reference "name" is ambiguous

我不明白这个模棱两可的“名字”在哪里?我分别尝试了INSERTUPDATE,它们工作正常。我应该在功能上进行哪些更改才能使其正常工作?

通知:我想对函数的列和参数保持相同的名称。

2 个答案:

答案 0 :(得分:1)

这显然不是错误,但无法使用默认的变量冲突解决行为来解决冲突:https://www.postgresql.org/message-id/CAE3TBxyCn9dOF2273ki%3D4NFwsaJdYXiMQ6x2rydsWY_6p8z_zg%40mail.gmail.com

<块引用>

这不是错误。由于有参数,这是命名冲突 和一个同名的列(a)。

您可以为参数使用不同的名称或告诉 Postgres 如何 解决此类冲突:

CREATE OR REPLACE FUNCTION pg_temp.testf(a int)
RETURNS void LANGUAGE plpgsql AS
$body$
#variable_conflict use_column
BEGIN INSERT INTO testt(a) SELECT testf.a ON CONFLICT (a) DO NOTHING; END
$body$;

查看文档: https://www.postgresql.org/docs/current/static/plpgsql-implementation.html

关键部分是在函数中添加#variable_conflict use_column来解决冲突,而无需更改参数名称或引用约束名称而不是列名称。

答案 1 :(得分:0)

同样,我没有理由不理解当前代码;但事实似乎如此。我通过创建名称约束并在ON Conflict子句中引用它来使其工作。

create table person (
    id serial not null,
    name varchar(50) not null,
    age int not null,
    constraint person_pkey primary key (id),
    constraint person_name_uk unique (name)
);

-- 
create or replace function my_func(name varchar, age int) returns void as $$
begin
    insert into person (name, age) values (my_func.name, my_func.age)
    on conflict on constraint person_name_uk
    do update
       set age = excluded.age
    where person.name = excluded.name;
end
$$ language plpgsql;

select my_func('George',35);
select * from person;

select my_func('George',45);
select * from person;

还是,很奇怪!