오류 : set_valued 함수가 컨텍스트에서 호출되어 세트를 승인 할 수 없습니다. 무슨 일이야?


11

우분투 12.04와 함께 Postgresql 9.1을 사용합니다.

내 질문에 크레이그의 대답에 영감을 SETOF 유형 또는 SETOF 기록의 병합 내가 사용하는 잘 갈 것이라고 생각 return query, setof record그리고이 plpgsql 기능에 일련의 발생기 :

create or replace function compute_all_pair_by_craig(id_obj bigint)
    returns setof record as $$
begin
    return query select o.id, generate_series(0,o.value) from m_obj as o;     
end;
$$    language plpgsql;

실행하는 동안 오류가 발생합니다.

ERROR: set_valued function called in context that cannot accept a set

뭐가 잘못 되었 니 ? 크레이그와는 반대로 함수에게 리턴하도록 지시 setof record합니다.

나는 Craig와 똑같이 작동하는 것을 얻을 수 있습니다. 즉, 유형을 정의하고 create type pair_id_value as (idx bigint, value integer)plpgsql 함수가 setof of pair_id_value대신을 반환하도록 하십시오 setof record.

그러나이 작업 솔루션을 사용하더라도 왜 select id, generate_series(0,13)혼자서 두 개의 열로 결과를 반환 하는지 이해하지 못합니다 ... 반대로 함수 (set_pair_id_value 반환)를 호출하면 필드가 다음과 같은 하나의 열에 만return query select id, generate_series(0,my_obj.value) from my_obj 결과가 반환됩니다 튜플 인이 "(123123,0)" "(123123,1)" "(123123,2)"(3 행)입니다.

임시 테이블을 작성해야하는 경우입니까?


그것은 컴파일되지 않기 때문에 실행중인 함수의 정확한 텍스트가 될 수 없습니다. 뒤에 세미콜론이 초과 BEGIN되고 뒤에는 세미콜론이 초과 RETURN QUERY됩니다. 해당 오류를 수정 한 후 반환 할 때 오류를 확인합니다 record. 답변으로 설명합니다.
Craig Ringer

@CraigRinger 세미콜론을 다시 넣었습니다.
Stephane Rolland

답변:


7

오류 메시지는별로 도움이되지 않습니다.

regress=> SELECT * FROM  compute_all_pair_by_craig(100);
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM  compute_all_pair_by_craig(100);

그러나 쿼리를 다시 설정하여 적절한 set-returning 함수로 호출하면 실제 문제가 발생합니다.

regress=> SELECT * FROM compute_all_pair_by_craig(100);
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM compute_all_pair_by_craig(100);

매개 변수 목록 SETOF RECORD없이 사용 하는 OUT경우 호출 문에 결과를 지정해야합니다. 예 :

regress=> SELECT * FROM compute_all_pair_by_craig(100) theresult(a integer, b integer);

그러나, 그것은 사용하는 것이 훨씬 더 나은 RETURNS TABLE또는 OUT매개 변수를 설정합니다. 이전 구문을 사용하면 함수는 다음과 같습니다.

create or replace function compute_all_pair_by_craig(id_obj bigint)
    returns table(a integer, b integer) as $$
begin
    return query select o.id, generate_series(0,o.value) from m_obj as o;     
end;
$$ language plpgsql;

이는 SELECT 목록 컨텍스트에서 호출 가능하며 명시 적으로 유형을 작성하거나 호출 사이트에서 결과 구조를 지정하지 않고 사용할 수 있습니다.


질문의 후반과 관련하여 첫 번째 경우는 SELECT 목록에서 두 개의 개별 열을 지정하지만 두 번째는 단일 복합을 반환하는 것입니다. 실제로 결과를 반환하는 방법과 관련이 없으며 함수를 호출하는 방법과 관련이 있습니다. 샘플 함수를 생성하면 :

CREATE OR REPLACE FUNCTION twocols() RETURNS TABLE(a integer, b integer) 
AS $$ SELECT x, x FROM generate_series(1,5) x; $$ LANGUAGE sql;

SELECT목록 에서 반환 기능을 호출하는 두 가지 방법의 차이점- 목록에서 기발한 동작을 가진 PostgreSQL 관련 비표준 확장 :

regress=> SELECT twocols();
 twocols 
---------
 (1,1)
 (2,2)
 (3,3)
 (4,4)
 (5,5)
(5 rows)

또는 더 표준적인 방법으로 테이블로 :

regress=> SELECT * FROM twocols();
 a | b 
---+---
 1 | 1
 2 | 2
 3 | 3
 4 | 4
 5 | 5
(5 rows)

방금 테스트하여 완벽하게 작동합니다. 그리고 나는이 문법을 좋아한다 returns table.
Stephane Rolland

@StephaneRolland 질문의 뒷부분에 대한 설명으로 업데이트되었습니다.
Craig Ringer

지원을위한 thx. 이제 훨씬 더 명확합니다.
Stephane Rolland
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.