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

plpgsql - ved hjælp af dynamisk tabelnavn i declare-sætning

Det er vigtigt at forstå hovedkarakteren af ​​disse fem forskellige slags data/symboler :

1. 'my_tbl'

En streng bogstavelig af unknown type . Når den bruges i SQL (indlejret i plpgsql-kode eller ej), tvinges den til en type, der er afledt af konteksten . Hvis typen ikke kan bestemmes, kan det være nødvendigt med en eksplicit afstøbning. Ligesom:'my_tbl'::text .

2. 'my_tbl'::text

Den samme streng cast til skriv text . Det kan indeholde navnet på en tabel, men det er egentlig bare tekst.

3. 'my_tbl'::regclass

En objekt-id (OID) for en registreret klasse . Det vises og kan indtastes som en streng, der repræsenterer et gyldigt objektnavn ('my_tbl' ). Outputtet er automatisk skema-kvalificeret ('my_schema.my_tbl' ) og/eller dobbelt anførselstegn ('"mY_TbL"' ), hvis det ellers ville være tvetydigt eller ulovligt. Det kan være et almindeligt bord , sekvens , se , materialiseret visning , sammensat type osv. Detaljer i dette relaterede svar:

4. my_tbl_var my_tbl (en forkortelse for my_tbl_var my_tbl%ROWTYPE )

I DECLARE sektion af en plpgsql-kodeblok, der er en variabel erklæring med en velkendt rækketype (a.k.a. sammensat type). Typen skal registreres i systemtabellen pg_class (samme som med en regclass variabel). Det er ikke OID'et for det refererede objekt, men dets faktiske rækketype. my_tbl_var og my_tbl er begge identifikatorer her og kan ikke parametreres. Du kan også caste en hvilken som helst række eller optage direkte:(123, 'foo')::my_tbl

5. my_tbl_var record

I DECLARE sektion af en plpgsql-kodeblok, der er erklæringen af ​​en anonym optagelse . Dybest set en pladsholder for en endnu ukendt rækketype / med endnu udefineret struktur. Den kan bruges i de fleste af stederne kan en rækketype bruges. Men du kan ikke få adgang til felter fra den, før registreringsvariablen er tildelt.

Du forvirrede 1. , 3. og 4. og løste det ved at bruge 5. i stedet.
Men der er mere, der går galt her:

  • Du vælger en hel tabel, men en række (record) variabel kan kun indeholde en række ad gangen. Så kun den første tildeles og returneres. Mens der ikke er nogen ORDER BY klausul, er resultatet vilkårligt og kan ændres til enhver tid. Ondskabsfælde.

  • Da du nu bruger en record type, skal du sikre dig, at den er blevet tildelt, før du kan køre test på dens felter, ellers vil du få undtagelser for tomme tabeller. I dit tilfælde er markeringen record_var IS NULL gør næsten det samme arbejde. Men der er en hjørne-case for rækker med NULL i alle felter:derefter record_var IS NULL vurderes til sandt. Endnu vanskeligere for testen IS NOT NULL . Detaljer her:

    Jeg har føjet en demo til SQL violinen nedenfor.

  • Funktionen returnerer en enkelt skalar (boolean ) værdi. Brug:

    RETURN false;
    

    I stedet for:

    RETURN QUERY SELECT false;

Funktion

CREATE FUNCTION check_valid(_tbl regclass)
  RETURNS bool AS
$func$
DECLARE
   r record;
   _row_ct int;
BEGIN
   EXECUTE '
   SELECT is_valid, hit_count, hit_limit
   FROM  ' || _tbl || '
   ORDER  <whatever>
   LIMIT  1'            -- replace <whatever> with your sort criteria
   INTO r;              -- only needed columns

   GET DIAGNOSTICS _row_ct = ROW_COUNT;

   IF _row_ct = 0 THEN  -- necessary, because r may not be assigned
      RETURN false;
   ELSIF NOT r.is_valid OR r.hit_count > r.hit_limit THEN
      RETURN false;
   END IF;

   RETURN true;
END
$func$  LANGUAGE plpgsql;

SQL Fiddle (med to varianter af funktionen og en demo for række ER NULL).

Vigtige punkter

  • Brug GET DIAGNOSTICS for at finde ud af, om der blev fundet nogle rækker i en dynamisk sætning med EXECUTE .

  • IF udtryk kan forenkles.

  • Parameteren er af typen regclass , ikke kun et bordnavn. Jeg ville ikke bruge det vildledende navn "tabelnavn" til denne parameter. Det øger kun din indledende forvirring. Kalder det _tbl i stedet.

Hvis du også vil vende tilbage et sæt variabel rækketype:



  1. Gem php-værdi til java

  2. Sådan håndteres flere objekter ved at bruge Objekt Explorer Detail Windows i SSMS - SQL Server / TSQL Tutorial Del 22

  3. Sammenkæd strengen med antallet af forekomster

  4. Mokka Test forbindelse til DB