PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zapętlaj tabele z PL/pgSQL w Postgres 9.0+

Nie pamiętam, kiedy ostatnio musiałem użyć wyraźnego kursora do zapętlenia w plpgsql.
Użyj niejawnego kursora FOR pętla, to znacznie czystsze:

DO
$$
DECLARE
   rec   record;
   nbrow bigint;
BEGIN
   FOR rec IN
      SELECT *
      FROM   pg_tables
      WHERE  tablename NOT LIKE 'pg\_%'
      ORDER  BY tablename
   LOOP
      EXECUTE 'SELECT count(*) FROM '
        || quote_ident(rec.schemaname) || '.'
        || quote_ident(rec.tablename)
      INTO nbrow;
      -- Do something with nbrow
   END LOOP;
END
$$;

Musisz podać nazwę schematu, aby to działało dla wszystkich schematów (w tym tych, których nie ma w Twojej search_path ).

Poza tym faktycznie potrzebujesz używać quote_ident() lub format() z %I lub regclass zmienna zabezpieczająca przed wstrzyknięciem SQL. Nazwa tabeli może być prawie dowolna wewnątrz podwójnych cudzysłowów. Zobacz:

  • Nazwa tabeli jako parametr funkcji PostgreSQL

Drobny szczegół:pomiń podkreślenie (_ ) w LIKE wzór, aby uczynić go dosłownym podkreślenie:tablename NOT LIKE 'pg\_%'

Jak mogę to zrobić:

DO
$$
DECLARE
    tbl   regclass;
    nbrow bigint;
BEGIN
   FOR tbl IN
      SELECT c.oid
      FROM   pg_class     c
      JOIN   pg_namespace n ON n.oid = c.relnamespace
      WHERE  c.relkind = 'r'
      AND    n.nspname NOT LIKE 'pg\_%'         -- system schema(s)
      AND    n.nspname <> 'information_schema'  -- information schema
      ORDER  BY n.nspname, c.relname
   LOOP
      EXECUTE 'SELECT count(*) FROM ' || tbl INTO nbrow;
      -- raise notice '%: % rows', tbl, nbrow;
   END LOOP;
END
$$;

Zapytanie pg_catalog.pg_class zamiast tablename , dostarcza OID tabeli.

Typ identyfikatora obiektu regclass przydaje się do uproszczenia. W szczególności nazwy tabel są w podwójnych cudzysłowach i automatycznie kwalifikowane według schematu (także zapobiegają wstrzykiwaniu SQL).

To zapytanie wyklucza również tabele tymczasowe (schemat tymczasowy nosi nazwę pg_temp% wewnętrznie).

Aby uwzględnić tylko tabele z danego schematu:

    AND    n.nspname = 'public' -- schema name here, case-sensitive


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Co dokładnie wyjaśnia PostgreSQL?

  2. Replikacja PostgreSQL do odzyskiwania po awarii

  3. Głowy w chmurze na CHAR(10)

  4. PostgreSQL multi INSERT...RETURNING z wieloma kolumnami

  5. Błąd PG COPY:nieprawidłowa składnia wejściowa dla liczby całkowitej