0

I am having some issues figuring out how to run multiple dynamic queries in a single function.

 CREATE OR REPLACE FUNCTION cnms_fy22q2.test_function(
    fyq text)
    RETURNS void
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$
BEGIN
 -- logic
    TRUNCATE TABLE 'schema_' || fyq || '.my_table'
    DROP TABLE 'schema_' || fyq || '.my_table';
END;
$BODY$; 

I am generally getting syntax errors, like ERROR: syntax error at or near .... What am I doing wrong here?

gwydion93
  • 1,681
  • 3
  • 28
  • 59
  • Apart from not actually using dynamic SQL, your first dynamic query is also missing the semicolon – Bergi May 20 '22 at 18:14

3 Answers3

1

You can't simply concatenate strings to make a dynamic sql statement. Take a look at EXECUTE and EXECUTE IMMEDIATE.

In your case, you could use it like this:

CREATE OR REPLACE FUNCTION cnms_fy22q2.test_function(
    fyq text)
    RETURNS void
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE
AS $BODY$
BEGIN
    -- logic
    EXECUTE 'TRUNCATE TABLE schema_' || fyq || '.my_table';
    EXECUTE 'DROP TABLE schema_' || fyq || '.my_table';
END
$BODY$; 
flwd
  • 548
  • 3
  • 12
1

Use the format function which will return a string and execute in your function.

create function permanently_delete_table(fyq text) RETURNS void
    LANGUAGE plpgsql AS $$
    declare
    begin
         EXECUTE format('TRUNCATE TABLE schema_%s.my_table',fyq); 
         EXECUTE format('DROP TABLE schema_%s.my_table',fyq); 
    end
$$;

Demo in sqldaddy.io

emrdev
  • 2,155
  • 3
  • 9
  • 15
  • Better use `%I` instead of `%s` for proper escaping ([demo](https://dbfiddle.uk/?rdbms=postgres_14&fiddle=ddc359bd452959b17069fe06d309cdf5)) – Bergi May 20 '22 at 18:16
0

Just to add a third option that I came up with which combines the queries inside a single EXECUTE format(); statement, here's what I came up with:

CREATE OR REPLACE FUNCTION cnms_fy22q2.drop_summary_tables_function(
fyq text)
  RETURNS void
  LANGUAGE 'plpgsql'
  COST 100
  VOLATILE 
AS $BODY$
BEGIN
 -- logic
  EXECUTE format(
  'TRUNCATE TABLE schema_%s.my_table;
  DROP TABLE  schema_%s.my_table', fyq, fyq);
END;
$BODY$; 
gwydion93
  • 1,681
  • 3
  • 28
  • 59