冲突列上的Postgres 10具有相同的名称,返回table = ambiguous中的列

时间:2018-06-12 09:27:55

标签: postgresql plpgsql

我有以下表格定义:

CREATE TABLE test.table_on_conflict (
  a INTEGER NOT NULL,
  b INTEGER,
  CONSTRAINT table_pkey PRIMARY KEY(a)
) 
WITH (oids = false);

和功能定义:

CREATE OR REPLACE FUNCTION test.update_on_conflict (
  _a integer,
  _b integer
)
RETURNS TABLE (
  a integer,
  b integer
) AS
$body$
BEGIN

INSERT INTO test.table_on_conflict (a, b)
SELECT _a, _b
ON CONFLICT (a) DO UPDATE SET b = EXCLUDED.b;           

RETURN QUERY
SELECT t.a, t.b
FROM test.table_on_conflict t
WHERE t.a = _a;

END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100 ROWS 1000;

因为返回表有列" a",ON CONFLICT(a)DO UPDATE SET ...给出错误:

ERROR:  column reference "a" is ambiguous 
LINE 3: ON CONFLICT (a) DO UPDATE SET b = EXCLUDED.b
                     ^ 
DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
QUERY:  INSERT INTO test.table_on_conflict (a, b) SELECT _a, _b ON CONFLICT (a) DO UPDATE SET b = EXCLUDED.b
CONTEXT:  PL/pgSQL function test.update_on_conflict(integer,integer) line 4 at SQL statement

有没有办法使用约束名来消除歧义?

1 个答案:

答案 0 :(得分:2)

我看到两种不同的解决方案:

首先将函数简化为SQL函数:

CREATE OR REPLACE FUNCTION update_on_conflict (_a integer, _b integer)
  RETURNS TABLE (a integer, b integer) AS
$body$

  INSERT INTO table_on_conflict (a, b)
  values (_a, _b)
  ON CONFLICT (a) DO UPDATE 
    SET b = EXCLUDED.b
  returning *;           

$body$
LANGUAGE sql;

如果你确实需要PL / pgSQL(因为你有其他代码没有向我们展示),你可以将函数声明为RETURNS setof table_on_conflict

CREATE OR REPLACE FUNCTION update_on_conflict (_a integer, _b integer)
  RETURNS setof  table_on_conflict
AS
$body$
begin

  return query
    INSERT INTO table_on_conflict (a, b)
    values (_a, _b)
    ON CONFLICT (a) DO UPDATE SET b = EXCLUDED.b
    returning *;           

end;  
$body$
LANGUAGE plpgsql;

在任何情况下都不需要单独的select。您可以直接返回INSERT语句的结果。

不相关,但是:语言名称是标识符。不要把它放在单引号中。