sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL kan geen transacties beginnen/beëindigen in PL/pgSQL

Een plpgsql functie loopt automatisch binnen een transactie. Het lukt allemaal of het mislukt allemaal. De handleiding:

Functies en triggerprocedures worden altijd uitgevoerd binnen een transactie die tot stand is gebracht door een buitenste query - ze kunnen die transactie niet starten of uitvoeren, omdat er geen context voor hen zou zijn om in uit te voeren. Echter, een blok met een EXCEPTION clausule vormt effectief een subtransactie die kan worden teruggedraaid zonder de buitenste transactie te beïnvloeden. Zie Sectie 42.6.6 voor meer informatie.

Dus als dat nodig is, kun je een uitzondering opvangen die theoretisch zou kunnen voorkomen (maar zeer onwaarschijnlijk is).
Details over trapping-fouten in de handleiding.

Uw functie herzien en vereenvoudigd:

CREATE FUNCTION foo(v_weather text
                  , v_timeofday text
                  , v_speed text
                  , v_behavior text)
  RETURNS SETOF custombehavior
  LANGUAGE plpgsql AS
$func$
BEGIN

DELETE FROM custombehavior
WHERE  weather = 'RAIN'
AND    timeofday = 'NIGHT'
AND    speed = '45MPH';

INSERT INTO custombehavior (weather, timeofday, speed, behavior)
SELECT v_weather, v_timeofday, v_speed, v_behavior
WHERE  NOT EXISTS (
   SELECT FROM defaultbehavior
   WHERE  a = 'RAIN'
   AND    b = 'NIGHT'
   AND    c = '45MPH'
   );

RETURN QUERY
SELECT * FROM custombehavior WHERE ... ;

END
$func$;

Als u daadwerkelijk transacties moet beginnen/beëindigen zoals aangegeven in de titel kijk naar SQL procedures in Postgres 11 of hoger (CREATE PROCEDURE ). Zie:

  • Wat is in PostgreSQL het verschil tussen een "opgeslagen procedure" en andere soorten functies?


  1. String splitsen in rijen Oracle SQL

  2. SQLite IN

  3. Welk MySQL-gegevenstype moet worden gebruikt voor breedtegraad/lengtegraad met 8 decimalen?

  4. Hoe u de maand van een datum haalt in MySQL