Question

i have a variable that is a name of a table. How can i select or update from this using variable in query , for example:

create or replace function pg_temp.testtst ()
returns varchar(255) as 
$$
declare 
r record; t_name name;
begin   
  for r in SELECT tablename FROM pg_tables WHERE schemaname = 'public' limit 100 loop
      t_name = r.tablename; 
      update  t_name set id = 10 where id = 15; 
  end loop; 
  return seq_name;
end;
$$
language plpgsql; 

it shows ERROR: relation "t_name" does not exist

Was it helpful?

Solution

Correct reply is a comment from Anton Kovalenko

You cannot use variable as table or column name in embedded SQL ever.

UPDATE dynamic_table_name SET ....

PostgreSQL uses a prepared and saved plans for embedded SQL, and references to a target objects (tables) are deep and hard encoded in plans - a some characteristics has significant impact on plans - for one table can be used index, for other not. Query planning is relatively slow, so PostgreSQL doesn't try it transparently (without few exceptions).

You should to use a dynamic SQL - a one purpose is using for similar situations. You generate a new SQL string always and plans are not saved

DO $$
DECLARE r record;
BEGIN
  FOR r IN SELECT table_name 
              FROM information_schema.tables
             WHERE table_catalog = 'public'
  LOOP
    EXECUTE format('UPDATE %I SET id = 10 WHERE id = 15', r.table_name);
  END LOOP;
END $$;

Attention: Dynamic SQL is unsafe (there is a SQL injection risks) without parameter sanitization. I used a function "format" for it. Other way is using "quote_ident" function.

EXECUTE 'UPDATE ' || quote_ident(r.table_name) || 'SET ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top