我有以下表格定义:
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
有没有办法使用约束名来消除歧义?
答案 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语句的结果。
不相关,但是:语言名称是标识符。不要把它放在单引号中。