sql >> Database teknologi >  >> RDS >> PostgreSQL

Loop på borde med PL/pgSQL i Postgres 9.0+

Jeg kan ikke huske, hvornår jeg sidst havde brug for at bruge en eksplicit markør til at sløjfe i plpgsql.
Brug den implicitte markør af en FOR loop, det er meget renere:

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

Du skal inkludere skemanavnet for at få dette til at fungere for alle skemaer (inklusive dem, der ikke er i din search_path ).

Også, du faktisk bruger at bruge quote_ident() eller format() med %I eller en regclass variabel for at sikre mod SQL-injektion. Et tabelnavn kan være næsten hvad som helst inde i dobbelte anførselstegn. Se:

  • Tabelnavn som en PostgreSQL-funktionsparameter

Mindre detaljer:Undgå understregningen (_ ) i LIKE mønster for at gøre det til et bogstaveligt understregning:tablename NOT LIKE 'pg\_%'

Sådan kan jeg gøre det:

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

Forespørgsel pg_catalog.pg_class i stedet for tablename , det giver tabellens OID.

Objektidentifikatortypen regclass er praktisk at forenkle. Især tabelnavne anføres i dobbelte anførselstegn og skemakvalificeres, hvor det er nødvendigt automatisk (forhindrer også SQL-injektion).

Denne forespørgsel ekskluderer også midlertidige tabeller (temp-skemaet hedder pg_temp% internt).

For kun at inkludere tabeller fra et givet skema:

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


  1. SQL Server TRIM-, LTRIM- og RTRIM-funktioner

  2. Beregn åbningstider mellem to datoer

  3. SQL Server:Sådan vælger du alle dage i et datointerval, selvom der ikke eksisterer nogen data i nogle dage

  4. Sikker TO_NUMBER()