USING 절을 사용하여 함수 매개 변수와 JOIN 결과 간의 이름 충돌


17

현재 Postgres 9.4 에서이 설정이 주어지면 ( 이 관련 질문에서 ) :

CREATE TABLE foo (ts, foo) AS 
VALUES (1, 'A')  -- int, text
     , (7, 'B');

CREATE TABLE bar (ts, bar) AS
VALUES (3, 'C')
     , (5, 'D')
     , (9, 'E');

이전 질문 의 SQL Fiddle 도 있습니다 .

나는 참조 된 질문의 목표를 달성하기 위해 SELECT와 함께 썼습니다 FULL JOIN. 쉽게 한:

SELECT ts, f.foo, b.bar
FROM   foo f
FULL   JOIN bar b USING (ts);

스펙에 따라 컬럼을 처리하는 올바른 방법 ts은 테이블 규정이 없습니다. 어느 쪽의 입력 값 ( f.ts혹은 b.ts) NULL 일 수있다. 이 USING절은 약간 이상한 경우를 만듭니다. 실제로 입력에없는 "입력"열을 소개합니다. 지금까지 너무 우아합니다.

나는 이것을 plpgsql 함수에 넣었다. 편의 (또는 요구 사항)를 위해 테이블 ​​함수의 결과에 대해 동일한 열 이름을 원합니다. 따라서 동일한 열 이름과 함수 매개 변수 간의 이름 충돌을 피해야합니다. 다른 이름을 선택하여 피하는 것이 가장 좋지만 다음과 같습니다.

CREATE OR REPLACE FUNCTION f_merge_foobar()
  RETURNS TABLE(ts int, foo text, bar text) AS
$func$
BEGIN
   FOR ts, foo, bar IN
      SELECT COALESCE(f.ts, b.ts), f.foo, b.bar
      FROM   foo f
      FULL   JOIN bar b USING (ts)
   LOOP
      -- so something
      RETURN NEXT;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

문제를 강조하기 위해 대담한 강조 . tsplpgsql이 예외를 발생시키기 때문에 이전과 같이 테이블 한정없이 사용할 수 없습니다 (엄격히 필요하지는 않지만 대부분의 경우 유용 할 수 있음).

ERROR:  column reference "ts" is ambiguous
LINE 1: SELECT ts, f.foo, b.bar
               ^
DETAIL:  It could refer to either a PL/pgSQL variable or a table column.

다른 이름이나 하위 쿼리를 사용하거나 다른 기능을 사용할 수 있다는 것을 알고 있습니다. 그러나 열을 참조하는 방법이 있는지 궁금합니다. 테이블 한정을 사용할 수 없습니다. 방법 이 있어야 한다고 생각할 것입니다.
있습니까?

답변:


19

문서 PL / pgSQL에 따르면 후드 아래에서plpgsql.variable_conflict 함수를 만들기 전에 또는 함수 정의를 시작할 때 구성 매개 변수를 사용하여 이러한 충돌을 해결하는 방법을 선언 할 수 있습니다 (가능한 3 가지 값은 error(기본값) ) use_variableuse_column) :

CREATE OR REPLACE FUNCTION pg_temp.f_merge_foobar()
  RETURNS TABLE(ts int, foo text, bar text) AS
$func$
#variable_conflict use_column             -- how to resolve conflicts
BEGIN
   FOR ts, foo, bar IN
      SELECT ts, f.foo, b.bar
      FROM   foo f
      FULL   JOIN bar b USING (ts)
   LOOP
      -- do something
      RETURN NEXT;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

1
완전한. 나는 무언가를 놓치고있는 잔소리를 느꼈다. 실제로 과거에 사용했던 것을 기억합니다. 감사합니다!
Erwin Brandstetter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.