PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Ulangi tabel dengan PL/pgSQL di Postgres 9.0+

Saya tidak ingat kapan terakhir kali saya benar-benar perlu menggunakan kursor eksplisit untuk mengulang di plpgsql.
Gunakan kursor implisit dari FOR loop, itu jauh lebih bersih:

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
$$;

Anda harus menyertakan nama skema agar ini berfungsi untuk semua skema (termasuk yang tidak ada di search_path Anda ).

Juga, Anda sebenarnya membutuhkan untuk menggunakan quote_ident() atau format() dengan %I atau regclass variabel untuk melindungi terhadap injeksi SQL. Nama tabel bisa hampir semua dalam tanda kutip ganda. Lihat:

  • Nama tabel sebagai parameter fungsi PostgreSQL

Detail kecil:hindari garis bawah (_ ) di bagian LIKE pola untuk membuatnya menjadi literal garis bawah:tablename NOT LIKE 'pg\_%'

Bagaimana saya bisa melakukannya:

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
$$;

Kueri pg_catalog.pg_class bukannya tablename , ini memberikan OID tabel.

Jenis pengenal objek regclass berguna untuk menyederhanakan. n khususnya, nama tabel dikutip ganda dan memenuhi syarat skema jika diperlukan secara otomatis (juga mencegah injeksi SQL).

Kueri ini juga mengecualikan tabel sementara (skema temp bernama pg_temp% secara internal).

Untuk hanya menyertakan tabel dari skema tertentu:

    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. Bagaimana justify_hours() Bekerja di PostgreSQL

  2. Buffer (Lingkaran) di PostGIS

  3. Postgres:pilih jumlah nilai dan kemudian jumlahkan ini lagi

  4. Apakah ada hit kinerja menggunakan tipe data desimal (MySQL/Postgres)

  5. Bisakah PostgreSQL mengindeks kolom array?