Postgresql 包含数据修改语句的WITH子句必须处于顶级SQL状态:0A000

Postgresql 包含数据修改语句的WITH子句必须处于顶级SQL状态:0A000,postgresql,Postgresql,我编写了一个函数,它与insert into table一起使用,如下所示: 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 plpgs

我编写了一个函数,它与insert into table一起使用,如下所示:

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
结果没有错误。
为什么会发生这种情况,以及如何避免这种情况?

您正在对该查询执行subselect,这就是它不起作用的原因。 这也行不通:

select * from (
   with t as (
     insert into t(id) 
     select 10
     returning *
    )
 select '{"a":"a"}'::json
) as sub
有几种解决方案

a) 将其声明为returning
setof
并使用
returnquery

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) 将其声明为
语言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;