Prawidłowa odpowiedź to komentarz Antona Kovalenko
W osadzonym SQL nigdy nie można używać zmiennej jako nazwy tabeli lub kolumny.
UPDATE dynamic_table_name SET ....
PostgreSQL korzysta z przygotowanych i zapisanych planów dla wbudowanego SQL, a odniesienia do obiektów docelowych (tabel) są głęboko i sztywno zakodowane w planach - niektóre cechy mają znaczący wpływ na plany - dla jednej tabeli można użyć indeksu, dla innych nie. Planowanie zapytań jest stosunkowo powolne, więc PostgreSQL nie próbuje tego w sposób przezroczysty (bez kilku wyjątków).
Powinieneś użyć dynamicznego SQL - jeden cel jest używany w podobnych sytuacjach. Zawsze generujesz nowy ciąg SQL, a plany nie są zapisywane
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 $$;
Uwaga:dynamiczny SQL jest niebezpieczny (istnieje wstrzyknięcie SQL ryzyka) bez sanityzacji parametrów. Użyłem funkcji „format " za to. Innym sposobem jest użycie "quote_ident " funkcja.
EXECUTE 'UPDATE ' || quote_ident(r.table_name) || 'SET ...