sql >> Database >  >> RDS >> PostgreSQL

Hoe variabele instellingen te gebruiken in triggerfuncties?

Behandel alle mogelijke gevallen voor de aangepaste optie correct:

  1. optie nog niet ingesteld

    Alle verwijzingen ernaar vormen een uitzondering , inclusief current_setting() tenzij aangeroepen met de tweede parameter missing_ok . De handleiding:

  2. optie ingesteld op een geldige integer letterlijke

  3. optie ingesteld op een ongeldige integer letterlijke

  4. optie reset (die opbrandt tot een speciaal geval van 3. )

    Als u bijvoorbeeld een aangepaste optie instelt met SET LOCAL of set_config('myvars.user_id3', '55', true) , wordt de optiewaarde aan het einde van de transactie gereset. Het bestaat nog , kan worden verwezen, maar het retourneert nu een lege tekenreeks ('' ) - die niet kan worden gecast naar integer .

Afgezien van duidelijke fouten in je demo, moet je je voorbereiden op alle 4 gevallen. Dus:

CREATE OR REPLACE FUNCTION add_transition1()
  RETURNS trigger AS
$func$
DECLARE
   _user_id text := current_setting('myvars.user_id', true);  -- see 1.
BEGIN
   IF _user_id ~ '^\d+$' THEN  -- one or more digits?

      INSERT INTO transitions1 (user_id, house_id)
      VALUES (_user_id::int, NEW.id);  -- valid int, cast is safe

   ELSE

      INSERT INTO transitions1 (user_id, house_id)
      VALUES (NULL, NEW.id);           -- use NULL instead

      RAISE WARNING 'Invalid user_id % for house_id % was reset to NULL!'
                  , quote_literal(_user_id), NEW.id;  -- optional
   END IF;

   RETURN NULL;  -- OK for AFTER trigger
END
$func$  LANGUAGE plpgsql;

db<>fiddle hier

Opmerkingen:

  • Vermijd variabelenamen die overeenkomen met kolomnamen. Zeer foutgevoelig. Een populaire naamgevingsconventie is om namen van variabelen vooraf te laten gaan door een onderstrepingsteken:_user_id .

  • Toewijzen op aangiftetijdstip om één toewijzing op te slaan. Let op het gegevenstype text . We casten later, nadat we ongeldige invoer hebben opgelost.

  • Vermijd het verhogen / oversluiten van een uitzondering indien mogelijk . De handleiding:

  • Test op geldige integer-tekenreeksen. Deze eenvoudige reguliere expressie staat alleen cijfers toe (geen voorloopteken, geen witruimte):_user_id ~ '^\d+$' . Ik reset naar NULL voor ongeldige invoer. Aanpassen aan uw behoeften.

  • Ik heb een optionele WARNING . toegevoegd voor uw gemak bij het debuggen.

  • Gevallen 3. en 4. ontstaan ​​alleen omdat aangepaste opties letterlijke tekenreeksen zijn (type text ), kunnen geldige gegevenstypen niet automatisch worden afgedwongen.

Gerelateerd:

Afgezien daarvan kunnen er elegantere oplossingen zijn voor wat u probeert te doen zonder aangepaste opties, afhankelijk van uw exacte vereisten. Misschien dit:



  1. Een niet-null-beperking toevoegen aan een kolom met null-waarden

  2. PHPExcel gebruiken om automatisch gegenereerde Excel-bestanden te maken

  3. Kan geen tekst naar MySQL posten met Insert Into

  4. juiste slaapstand-annotatie voor byte[]