2017-12-27 4 views
1

I Funktion geschrieben, die wie folgt in die Tabelle mit dem Bau mit Einsatz mit:WITH-Klausel eine Daten modifizierende Anweisung enthalten, müssen SQL-Zustand auf der obersten Ebene sein: 0A000

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() 

Das ist das Rück Fehler:

ERROR: WITH clause containing a data-modifying statement must be at the top level 
SQL-состояние: 0A000 

ausführen Wenn

with t as (
    insert into t(id) 
    select 1 
    returning * 
    ) 
select '{"a":"a"}'::json 

Ergebnis ohne Fehler. Warum dies stattfindet und wie kommt man dazu?

Antwort

2

Sie tun Subselect für diese Abfrage, mit warum es nicht funktioniert. Das wird nicht funktionieren entweder:

select * from (
    with t as (
    insert into t(id) 
    select 10 
    returning * 
    ) 
select '{"a":"a"}'::json 
) as sub 

Es gibt ein paar Lösungen für diese sind.

a) festzustellen, es als setof zurückkehren und verwenden 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) festzustellen, es als 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) festzustellen, Ausgangsgröße (n) in Argumentliste und weisen Ergebnis ihnen

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; 
+0

Vielen Dank! b. - ist gut für mich! – DanStopka

Verwandte Themen