Правилният отговор е коментар от Антон Коваленко
Никога не можете да използвате променлива като име на таблица или колона във вграден SQL.
UPDATE dynamic_table_name SET ....
PostgreSQL използва подготвени и запазени планове за вграден SQL, а препратките към целеви обекти (таблици) са дълбоко и твърдо кодирани в плановете - някои характеристики имат значително влияние върху плановете - за една таблица може да се използва индекс, за друга не. Планирането на заявките е сравнително бавно, така че PostgreSQL не го опитва прозрачно (без малки изключения).
Трябва да използвате динамичен SQL - една цел се използва за подобни ситуации. Винаги генерирате нов SQL низ и плановете не се записват
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 $$;
Внимание:Динамичният SQL е опасен (има SQL инжекция рискове) без дезинфекция на параметрите. Използвах функция „format " за него. Друг начин е да използвате "quote_ident ".
EXECUTE 'UPDATE ' || quote_ident(r.table_name) || 'SET ...