2016-12-09 1 views
1

필자는 테이블 moredata에 가입하려는 일반적인 상황이 있습니다. 간단한 예를 제공하기 위해, 내가 가진 상상 : moredata이 동일하게 유지하면서테이블을 입력으로 사용하는 Postgresql 기능? plpgsql 함수에서 동적 SQL은 갈 수 있습니까?

SELECT * 
FROM x 
JOIN moredata d on x.yyyymmdd = d.yyyymmdd 

x이 달라질 수 있습니다. 코드를 재사용 할 수있는 좋은 방법은 무엇입니까? 위의 코드를 자동화하여 다른 테이블에 적용 할 수 있습니다 (예 : 'x'대신 'y'테이블에서 같은 작업 수행).

한 가지 방법은 테이블 이름에 따라 작동하는 동적 SQL을 사용하여 plpgsql 함수를 작성하는 것입니다. 같은 뭔가 :

CREATE FUNCTION joinmoredata(tblname text) RETURNS TABLE(...) AS $$ 
BEGIN 
    RETURN QUERY EXECUTE format('SELECT * FROM %I JOIN moredata on ...', tblname); 
END; 
$$ LANGUAGE plpgsql; 

그러나 당신은 파생 테이블이나 CTE에 적용 할 수 없었다. 더 좋은 방법이 있습니까? 아니면 동적 SQL이 상황에서 코드를 재사용하는 가장 좋은 방법입니까?

(I 코드를 재사용 할 이유 주, 실제 쿼리는 SELECT * FROM x JOIN moredata d on x.yyyymmdd = d.yyyymmdd보다 더 복잡한이 많이되는 것입니다.)

+0

함수 반환 값은 무엇입니까? –

+0

'x는 달라질 것입니다. '.. 정확히 어떻게? 각 테이블에 동일한 열이 있습니까? (유형, 이름, 번호)? 리턴 타입'RETURNS TABLE (...)'도 달라질 것인가? –

+0

@ErwinBrandstetter'x'는 매번 동일한 열을 가지며 함수가 반환하는 테이블은 매번 동일한 열을 갖도록 표준화 될 수 있습니다. –

답변

2

x 대신에 각 테이블의 동일한 데이터 형식과 동일한 열 이름을 사용하고 동일한 행 유형을 반환하면 동적 SQL을 사용하는 것이 좋습니다. 귀하의 질문에 이미있는 것처럼. format()%I과 같이 사용하면 식별자를 삭제하는 방법을 알고있어 구문 오류와 SQL 삽입을 방지 할 수 있습니다.

권한 관리 계획이 있어야합니다. 그리고 테이블 이름 해석 및 다른 스키마의 같은 이름을 가진 다른 테이블과의 혼동을 피하기 위해 스키마 한정 테이블 이름이나 데이터 형식 regclass을 전달합니다.

밀접하게 관련 더 자세한 사항 :

더 복잡해진다 경우 - 열 이름과 유형의 변화 - 당신은 항상 ...

클라이언트 프로그램에서 쿼리 문자열을 연결할 수 있습니다
1

난 단지 내가 언제 내가 SQL의 큰 부분을 다시 할 필요가 동적 SQL을 사용하는 것이 말할 수있다 코드 및 WHERE 절이나 테이블 이름 등에서 만 변경할 수 있습니다. 그리고 그것은 정상적으로 작동하며 INSERT 또는 UPDATES를 포함하는 매우 복잡한 CTE 쿼리도이 방법으로 작동합니다. 그래서 동적 SQL에 투표 할 것입니다.

관련 문제