我编写了函数,它使用WITH构造插入到表中,如下所示:
CREATE OR REPLACE FUNCTION test_func()
RETURNS json AS
$BODY$
begin
return (
with t as (
insert into t(id)
select 1
returning *
)
select '{"a":"a"}'::json
);
end;
$BODY$
LANGUAGE plpgsql VOLATILE;
select test_func()
那是返回错误:
ERROR: WITH clause containing a data-modifying statement must be at the top level
SQL-состояние: 0A000
如果执行
with t as (
insert into t(id)
select 1
returning *
)
select '{"a":"a"}'::json
结果没有错误。为什么会发生这种情况以及如何绕过这个?
您正在对该查询进行子选择,这就是为什么它不起作用。这也不起作用:
select * from (
with t as (
insert into t(id)
select 10
returning *
)
select '{"a":"a"}'::json
) as sub
有一些解决方案。
a)声明它返回setof
并使用return query
CREATE OR REPLACE FUNCTION test_func()
RETURNS setof json AS
$BODY$
begin
return query
with t as (
insert into t(id)
select 7
returning *
)
select '{"a":"a"}'::json;
end;
$BODY$
LANGUAGE plpgsql VOLATILE;
b)将其声明为language sql
CREATE OR REPLACE FUNCTION test_func()
RETURNS json AS
$BODY$
with t as (
insert into t(id)
select 8
returning *
)
select '{"a":"a"}'::json;
$BODY$
LANGUAGE sql VOLATILE;
c)在参数列表中声明输出变量并将结果分配给它们
CREATE OR REPLACE FUNCTION test_func(OUT my_out_var json)
AS
$BODY$
begin
with t as (
insert into t(id)
select 9
returning *
)
select '{"a":"a"}'::json INTO my_out_var;
end;
$BODY$
LANGUAGE plpgsql VOLATILE;