sql >> Database >  >> RDS >> PostgreSQL

Waarom kunnen PL/pgSQL-functies een neveneffect hebben, terwijl SQL-functies dat niet kunnen?

U hebt de kernzin in de handleiding zelf vetgedrukt:

De hele body van een SQL-functie wordt geparseerd voordat deze wordt uitgevoerd.

Lees ook over The Parser Stage in de handleiding.

Het bestaat uit twee hoofdonderdelen:de parser en het transformatieproces . Citaat uit de handleiding:

het transformatieproces neemt de boom terug die door de parser is teruggegeven als invoer en doet de semantische interpretatie die nodig is om te begrijpen naar welke tabellen, functies en operators wordt verwezen door de query.

Als een SQL-functie deze commando's bevat:

CREATE TABLE foo (...);
INSERT INTO foo VALUES(...);

Beide verklaringen worden vrijwel gelijktijdig gepland (gebaseerd op dezelfde momentopname van de systeemcatalogi). Vandaar dat de INSERT kan de tabel "foo" niet zien, vermoedelijk gemaakt met de vorige CREATE opdracht. Dat zorgt voor een van de volgende problemen :

  1. Als er geen andere . is tabel met de naam "foo" in uw search_patch (nog), klaagt Postgres bij het maken van de functie:

    ERROR:  relation "foo" does not exist
    
  2. Als er al een andere tabel met de naam "foo" bestaat in uw search_patch (en u gebruikt geen conflicterende kolomnamen), Postgres plant de INSERT gebaseerd op die reeds bestaande tabel. Meestal resulteert dat in een fout op uitvoeringstijd , als waarden conflicten veroorzaken in de (verkeerde!) tabel. Of, met wat pech, kan het zelfs naar die tafel schrijven zonder foutmelding! Zeer stiekeme bug.

Dat kan niet gebeuren met een PL/pgSQL functie, omdat het SQL-commando's behandelt als voorbereide instructies, gepland en uitgevoerd opeenvolgend . Elke instructie kan dus objecten zien die in eerdere verklaringen zijn gemaakt.

Bijgevolg worden instructies die nooit worden bezocht, zelfs nooit gepland - in tegenstelling tot SQL-functies. En het uitvoeringsplan voor instructies kan binnen dezelfde sessie in de cache worden opgeslagen - ook in tegenstelling tot SQL-functies. Lees details over plancaching in PL/pgSQL-functies in de handleiding hier.
Elke aanpak heeft voordelen voor sommige gebruikssituaties. Verder lezen:

  • Verschil tussen taal sql en taal plpgsql in PostgreSQL-functies


  1. PostgreSQL-tabelstatistieken analyseren

  2. SQL transponeren volledige tabel

  3. Update-instructie met behulp van met clausule

  4. Nde max salaris in Oracle