2013-08-06 2 views
0

특정 스키마 이름을 반복하고 테이블에 데이터를 삽입하는 함수가 있습니다. 삽입 루프가 발생하기 전에 상기 테이블을자를 수 있어야합니다. 동적 쿼리 안에 truncate 문을 넣으려고했는데 그 결과 테이블의 내부에 스키마 데이터 만 보관할 수있었습니다. 나도 자신의 변수로 선언 한 다음 루핑 문과 별도로 명령문을 실행 해 보았습니다.하지만 결과는 동일합니다.하나의 함수 안에 루핑 변수가있는 동적 SQL 전에 테이블 잘림

제 질문은 - 정확히이 함수 내에 truncate table dwh.prod_table_notify 문을 넣을 수 있습니까? 따라서이 함수를 실행할 때마다 테이블이 잘리고 이후 삽입은 FOR 문에서 반환되는 각 스키마를 통해 적절하게 반복됩니다.

참고 : 나는 포스트 그레스

CREATE OR REPLACE FUNCTION dwh.dim_table_notification() 
RETURNS void 
LANGUAGE plpgsql 
AS $function$ 
Declare 
     myschema varchar; 
     sql2 text;     
Begin 
for myschema in 
select distinct table_schema 
from information_schema.tables 
where table_name in ('dim_loan_type', 'dim_acct_type') 
and table_schema NOT LIKE 'pg_%' 
and table_schema NOT IN ('information_schema', 'ad_delivery', 'dwh', 'users', 'wand', 'ttd') 
order by table_schema 
loop 
sql2 ='insert into dwh.prod_table_notify 
select '''|| myschema ||''' as userid, loan_type_id as acct_type_id, loan_type::varchar(10) as acct_type, loan_type_desc::varchar(50) as acct_type_desc, term_code, 1 as loan_type from '|| myschema || '.' ||'dim_loan_type where term_code is null 
union 
select '''|| myschema ||''' as userid, acct_type_id, acct_type::varchar(10), acct_type_desc::varchar(50), term_code, 0 as loan_type from '|| myschema || '.' ||'dim_acct_type where term_code is null'; 
execute sql2; 
end loop; 
END; 
$function$ 
+0

내가 뭔가를 잃어 버렸다고 생각합니다. 왜 루프 앞에 먼저 자르지 않습니까? – Dmitri

+0

@Dmitri 작동하지 못했습니다. 어디로 넣을까요? – precose

+1

첫 번째 진술 :'BEGIN' 다음에'for myschema in' 앞에. 이제부터 살펴 보았습니다. 거기에 함수 선언이 두 번 있습니다. 단지 복사/붙여 넣기 오류입니까? – Dmitri

답변

1
CREATE OR REPLACE FUNCTION dwh.dim_table_notification() 
    RETURNS void LANGUAGE plpgsql AS 
$func$ 
DECLARE 
    myschema text; 
BEGIN 

-- truncate simply goes here: 
TRUNCATE dwh.prod_table_notify; 

FOR myschema IN 
    SELECT quote_ident(table_schema) 
    FROM information_schema.tables 
    WHERE table_name IN ('dim_loan_type', 'dim_acct_type') 
    AND table_schema NOT LIKE 'pg_%' 
    AND table_schema NOT IN 
      ('information_schema', 'ad_delivery', 'dwh', 'users', 'wand', 'ttd') 
    ORDER BY table_schema 
LOOP 
    EXECUTE ' 
    INSERT INTO dwh.prod_table_notify 
       (userid, acct_type_id, acct_type, acct_type_desc, loan_type) 
    SELECT '''|| myschema ||''', loan_type_id, loan_type::varchar(10) 
     , loan_type_desc::varchar(50), term_code, 1 AS loan_type 
    FROM '|| myschema || '.dim_loan_type 
    WHERE term_code IS NULL 
    UNION ALL 
    SELECT '''|| myschema ||''' AS userid, acct_type_id, acct_type::varchar(10) 
     , acct_type_desc::varchar(50), term_code, 0 AS loan_type 
    FROM '|| myschema || '.dim_acct_type 
    WHERE term_code IS NULL'; 
END LOOP; 
END 
$func$ 
  • 당신이, 당신이 실제로 TRUNCATE을 사용할 수 있습니다 확신 8.2을 사용하도록 강요 해요? the manual for 8.2 인용 :

    TRUNCATE는 이러한 모든 테이블이 같은 명령에 잘립니다하지 않는 한, 다른 테이블에서 외래 키 참조가 테이블에 사용할 수 없습니다.
    DELETE FROM dwh.prod_table_notify;

  • 당신은 식별자를 소독해야한다 : 테이블 작은 경우

    , DELETE는 우선 TRUNCATE보다 빠르다! quote_ident()을 사용하십시오 (8.2 페이지 참조).

  • 여기에 DISTINCT을 사용하면 아무런 의미가 없습니다.

  • INSERT에 대한 열 정의 목록을 제공하십시오. 그렇지 않으면 테이블을 나중에 바꿀 때 혼동을 일으킬 수 있습니다.

  • SELECT의 두 다리에있는 행이 고유하면 UNION 대신 UNION ALL을 사용하십시오. 중복을 포기하려는 시도가 없습니다.

+0

완벽하게 작동합니다. 그리고 네 테이블이 작아서 잘라내 기 대신 DELETE FROM을 사용했습니다. 당신은 훌륭한 사람 에르빈입니다! – precose