databasepostgresqlfunctionsyntax-errorexecute

PostgreSQL syntax error when using EXECUTE in Function


I'm trying to create a function which references a temporary table in PostgreSQL 8.4. Based on my research it seems the best way to do this is to use the EXECUTE command to execute my query from a defined string.

Unfortunately I'm getting an odd syntax error when trying to create the function.

My current function definition is as follows:

CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
  EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
$$ LANGUAGE SQL;

The error I am getting is:

ERROR:  syntax error at or near "'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table'"
LINE 2:   execute 'INSERT INTO table1 (col1, col2, col3) SELECT col1...

It seems I get the same error regardless of what is actually in the string literal.

My questions are, 1) what is the correct syntax for using the EXECUTE feature, and 2) is there a better way to write a function like this that references a temporary table?


Solution

  • I think your problem is the language you're using. EXECUTE in the SQL language:

    EXECUTE is used to execute a previously prepared statement. Since prepared statements only exist for the duration of a session, the prepared statement must have been created by a PREPARE statement executed earlier in the current session.

    isn't the same as EXECUTE in PL/pgSQL:

    Oftentimes you will want to generate dynamic commands inside your PL/pgSQL functions, that is, commands that will involve different tables or different data types each time they are executed. PL/pgSQL's normal attempts to cache plans for commands (as discussed in Section 39.10.2) will not work in such scenarios. To handle this sort of problem, the EXECUTE statement is provided:

    EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
    

    You're using the SQL EXECUTE (which executes a prepared statement) when you want to be using the PL/pgSQL EXECUTE (which executes a string as SQL).

    Try this:

    CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
    BEGIN
        EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
    END;
    $$ LANGUAGE PLPGSQL;
    

    Or, another example that seems closer to what you seem to be trying to do:

    create or replace function example(tname text) returns void as $$
    begin
        execute 'insert into ' || tname || ' (name) values(''pancakes'')';
    end;
    $$ language plpgsql;
    

    That will insert 'pancakes' into the table that you pass in the tname argument to the function.