如果函数声明的结果表的描述(例如,field1)中有一个字段出现在括号"100"中,则在执行函数时会发生错误:

SQL Error [42702]: ERROR: column reference "field1" is ambiguous

为了不描述这个问题很长时间和难度,我立即给出了一个行为奇怪的现成测试代码的例子:

创建要插入行的表:

drop table if exists testing_table;
create TABLE testing_table (
  -- Keep in mind the name of this field
  field1 int4
, s1 text
, constraint pk_testing_table_field1 PRIMARY key (field1)
);

创建将行插入到表中的函数

-- drop function if exists insert_testing_table;
create or replace function insert_testing_table(p_field1 int4, p_s1 text)
returns table 
(
  -- Keep in mind the name of this field
  field1 int4
  , s1 text
)
LANGUAGE plpgsql AS $function$
begin 

insert into testing_table as r (field1, s1) values (p_field1, p_s1)
on conflict (
-- It is this place that is the conflicting name that causes the error
field1
)
do update set s1 = p_s1 where r.field1 = p_field1;

return query select t.* from testing_table t where t.field1 = p_field1;

end $function$;

调用函数:

select * from insert_testing_table(1, 'aaa');

此调用将导致错误:

SQL Error [42702]: ERROR: column reference "field1" is ambiguous

不能在表达式"on conflict(...)"的括号中指定别名、表名或约束名,只能指定表字段的直接名称.

"is ambiguous"是什么意思? 在"insert on conflict do update"语句中,field1列与表的哪一列冲突?

如果我重命名"return query select..."表达式中的字段,错误仍然存在.

而是if I rename the "field1" field in the description of the resulting table, the function will run without error美元.

如何在表达式"On Conflicts(...)"的圆括号中指定字段的名称以消除错误?

我明白我可以使用:

ON CONFLICT ON CONSTRAINT,constraint_name.

但我想通过在"on Conflicts(...)"中指定字段来解决异常情况,该字段与返回表的描述中的字段相同. 这是一种什么样的陌生?

推荐答案

另一种方法是完全go 掉除参数(p_...)以外的所有变量.当创建与表本身同名的表时,Postgres会自动创建类型定义.您可以将其用作返回;然后您的函数声明实质上就变成了returns <table_name>.此外,当发生冲突时,postgres会生成一个内部元组,其中包含要插入的行的声明.这个元组称为excluded.,其列名与实际的表相同.此外,postgres清楚地知道它正在处理哪一行,因此不需要指定where.
最后,至少在这种情况下,这可以通过一条语句来完成,并且可以放入一个SQL函数中--不需要pgplsql.所以:(见demo here)

create or replace function insert_testing_table(p_field1 int4, p_s1 text)
  returns testing_table
  language sql 
as $$
    insert into testing_table(field1, s1) 
         values (p_field1, p_s1)
         on conflict (field1)
         do update 
               set s1 = excluded.s1
         returning *;
$$;    

Postgresql相关问答推荐

通过窗口函数收集反连接结果?

为什么在使用PostGIS时,英国郡的几何图形会出现在几内亚湾?

为什么我的应用程序接收的是空值而不是布尔值?

使用pg_repack从PostgreSQL中的表中删除OID

自左联接的POSTGIS更新

将具有自定义类型的表从一种模式复制到另一种模式

如何在 postgres 中查询键设置为空值的 jsonb 字段

如何在 kubernetes 中安全地重启 postgresql 容器?

气流数据库如何定期管理?

postgres 如何计算多列哈希?

从具有加权行概率的 PostgreSQL 表中 Select 随机行

PostgreSQL:在timestamp::DATE 上创建索引

安装 pg gem 失败,mkmf.rb 找不到 ruby​​ 的头文件(Mac OSX 10.6.5)

Rails 重置所有 Postgres 序列?

如何使用 postgresql 中的存储过程将数据插入表中

在 Windows 10 中执行时,Docker 容器关闭并给出data directory has wrong ownership错误

如何正确索引多对多关联表?

如何判断 PostgreSQL 事务中的待处理操作

在 PostgreSQL 中将列数据类型从 Text 更改为 Integer

在 OS X 上使用 Postgres.app 时如何将 psql 放在路径上?