sqlpostgresqlplpgsqldynamic-sqlpostgresql-8.2

Truncating table before dynamic SQL with looping variables inside of one function


I have a function that loops through specific schema names and inserts data into a table. I would like to be able to truncate said table before the insert loop occurs. I've tried putting the truncate statement inside of the dynamic query and that caused it to only keep schema's data inside of the table. I also tried declaring it as it's own variable and then executing the statement separately from the looping statement -- but that resulted in the same.

So my question is -- Where exactly would I put a truncate table dwh.prod_table_notify statement within this function? So that every time I run this function the table would be truncated and then the insert would properly loop through each schema being returned from the FOR statement.

NOTE: I'm forced to use postgres 8.2

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$

Solution

  • 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$