1
BEGIN
   _table_name := 'mytable';

   CREATE TEMPORARY TABLE _table_name (
     id integer NOT NULL,
     name character varying,
     active boolean
   ) ON COMMIT DROP';

-- logic here

RETURN QUERY SELECT table1.id, table1.name FROM _table_name AS table1;
END;

I have simplified my problem. I'm trying to use a variable as the table name.

I know you can do things like SELECT * FROM table1 WHERE id = _id where _id is a declared varaible.

I know I can do this EXECUTE, but then I have a query like: INSERT INTO table2 (id) SELECT id FROM unnest(_ids) as id where _ids is an array.

Anyway to solve problem 1 with using a variable as table name? and problem 2, using unnest inside EXECUTE?

So the problem is that the queries take _table_name as a literal table name, it doesn't look like it's using 'mytable' as the table name instead.

2
  • postgresql.org/docs/current/static/…
    – user330315
    Commented Mar 9, 2015 at 22:00
  • @a_horse_with_no_name I already read that. My argument was that how come you can use variables in literal queries like in the example with _id vs the create table example.
    – user962449
    Commented Mar 9, 2015 at 22:03

2 Answers 2

2

If you're dynamically changing the table name (i.e. via a variable) then you will need to use EXECUTE. You can use this with arrays and unnest, as long as you cast the arrays to/from a TEXT representation.

DECLARE 
    _ids INT[] = ARRAY[ 1, 2, 3, 4, 5 ];
    _table_name TEXT = 'mytable';
BEGIN 
  EXECUTE
    'INSERT INTO ' || QUOTE_IDENT( _table_name ) || ' (id)
     SELECT id
     FROM unnest( ' || QUOTE_LITERAL( _ids::TEXT ) || '::INT[] ) AS id';
END; 
1

You have been told about dynamic SQL with EXECUTE in plpgsql. You build the query string dynamically including invariable code and identifiers.

But do not concatenate values. Use the USING clause instead:

DECLARE 
   _ids INT[] = ARRAY[ 1, 2, 3, 4, 5 ];
   _table_name TEXT = 'mytable';
BEGIN 
   EXECUTE
    'INSERT INTO ' || quote_ident(_table_name) || ' (id)
     SELECT * FROM unnest($1)'
   USING ids;
END; 

Avoids error-prone casting back and forth.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.