我有一个由来源提供的表格:
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
我不明白这个模棱两可的“名字”在哪里?我分别尝试了INSERT
和UPDATE
,它们工作正常。我应该在功能上进行哪些更改才能使其正常工作?
通知:我想对函数的列和参数保持相同的名称。
答案 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;
还是,很奇怪!