La risposta corretta è un commento di Anton Kovalenko
Non è mai possibile utilizzare la variabile come nome di tabella o colonna nell'SQL incorporato.
UPDATE dynamic_table_name SET ....
PostgreSQL utilizza piani preparati e salvati per SQL incorporato e i riferimenti a oggetti di destinazione (tabelle) sono codificati in modo approfondito e rigido nei piani - alcune caratteristiche hanno un impatto significativo sui piani - per una tabella può essere utilizzata l'indice, per l'altra no. La pianificazione delle query è relativamente lenta, quindi PostgreSQL non la prova in modo trasparente (senza poche eccezioni).
Dovresti usare un SQL dinamico - uno scopo viene utilizzato per situazioni simili. Generi sempre una nuova stringa SQL e i piani non vengono salvati
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 $$;
Attenzione:Dynamic SQL è non sicuro (c'è un'iniezione SQL rischi) senza sanificazione dei parametri. Ho usato una funzione "formato " per questo. Un altro modo è usare "quote_ident " funzione.
EXECUTE 'UPDATE ' || quote_ident(r.table_name) || 'SET ...