2016-10-11 10 views
6

중첩 된 (또는 내부) 함수를 사용하여 PL/pgSQL에서 함수를 만들고 싶습니다. 이 방법으로 문제를 작은 조각으로 나눌 수 있지만이 작은 조각을이 기능 밖에서 사용할 수는 없습니다.PL/pgSQL에서 중첩 함수를 작성하려면 어떻게해야합니까?

PL/pgSQL에서 이것을 수행 할 수 있습니까? 그렇다면 어떻게?

+0

왜 그렇게 했습니까? 나에게 비현실적인 것 같다. 문제를 많은 기능없이 작은 조각으로 나눌 수 있습니다. 또는 정말로 필요한 경우 문제를 해결할 수 있습니다. –

답변

2

중첩 함수는 PLpgSQL에서 지원되지 않습니다. 에뮬레이션은 의미가 없으며 비생산적입니다.

+1

처음에는 키위로 설명 된 에뮬레이션이 작동했습니다. 더 작은 데이터 세트에서 테스트 해 보았는데 좋았습니다. 그러나 더 큰 집계를 사용하여 작업 할 때는 항상 이상한 잠금 오류로 인해 실패했습니다. 나는 이것을 읽는 사람이 중첩 된 함수를 PL/pgSQL에서 작동시키지 않으려 고하는 것이 가장 좋을 것이라고 생각한다. –

+0

@ GregoryArenius : 나는 그 예제를 가지고 놀았지만 함수 "outer"가 호출 될 때마다 "inner"함수 ("outer"함수와 동일한 범위)를 작성/대체합니다. 따라서 이상한 오류가 발생합니다. 그것은 "내부 함수"가 아니며 "외부"의 내부 범위에도 액세스 할 수 없습니다. –

7

하면보십시오 : 포스트 그레스에서

CREATE OR REPLACE FUNCTION outer() RETURNS void AS $outer$ 
DECLARE s text; 
BEGIN 
    CREATE OR REPLACE FUNCTION inner() RETURNS text AS $inner$ 
    BEGIN 
    RETURN 'inner'; 
    END; 
    $inner$ language plpgsql; 

    SELECT inner() INTO s; 
    RAISE NOTICE '%', s; 

    DROP FUNCTION inner(); 
END; 
$outer$ language plpgsql; 

9.5 SELECT outer(); 출력

psql:/vagrant/f.sql:14: NOTICE: inner 

편집 : 당신이 외부 함수의 끝에서 내부 기능을 떨어 뜨리지 않는 경우가 계속 표시됩니다 나머지 데이터베이스.

+2

다른 것을 지적하는 몇 가지 사항 : 내부 및 외부 함수 모두에 대해 'AS $$'를 사용할 수 없습니다. 또한 함수에 인수가 있으면 해당 함수를 삭제할 때 유형을 전달해야합니다. 그리고 외부 함수의'DECLARE' 부분에서 함수가 아직 생성되지 않았기 때문에 함수를 호출 할 수 없습니다. 중첩 된 함수를 만든 후에 변수를 만들고 값을 할당하기 만하면됩니다. –

+2

@Gregory : 한 가지 더 중요한 점 : 두 개의 동시 트랜잭션이이 함수를 호출하려고하면 두 번째 함수는 함수 이름에 대한 데이터베이스의 고유성 제약으로 인해 첫 번째 트랜잭션이 커밋 될 때까지 내부 CREATE를 차단합니다. 내부 함수를 세션의 임시 스키마에 넣으면 즉, CREATE FUNCTION pg_temp.inner()를 사용하여이 문제를 해결할 수 있습니다. 추가 된 이점은 내부 함수가 외부에서 볼 수 없으며 세션 후에 자동으로 정리된다는 것입니다. –

+2

@ Gregory : 그런데'DECLARE ... BEGIN ... END' 블록은 중첩 될 수 있으므로 내부 함수가 만들어진 후에 선언을 할 수 있습니다 –