sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur skickar man GAMLT, NYTT och identifierare för att EXEKUTERA i en triggerfunktion?

Så här skulle din triggerfunktion fungera korrekt:

CREATE OR REPLACE FUNCTION loca_app.func_historico_mod_usuarios()
  RETURNS trigger AS
$func$
BEGIN
   EXECUTE format(
      'INSERT INTO loca_app.tb_modificacoes
              (mod_momento, mod_valor_anterior, mod_valor_atual, mod_usuario, mod_dado)
       VALUES (now()      , $1.%1$I           , $2.%1$I        , $3         , $4)

              )', TG_ARGV[0])
   USING OLD, NEW, TG_RELID
      , (SELECT dad_id FROM loca_app.tb_dados
         WHERE  dad_nome = TG_ARGV[0]  -- cast? see blow
         LIMIT  1);

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

Huvudpunkter

  • Skicka de speciella radvärdena OLD och NEW samt TG_RELID som värden till EXECUTE med USING klausul. Du kan behöva casta TG_RELID till en passande datatyp. Tabelldefinitionen för tb_modificacoes är oupplyst. Eller så vill du verkligen ha något annat här. Se nedan.
    $1 , $2 och $3 i SQL-strängen som skickades till EXECUTE hänvisa till uttryck i USING klausul, inte till funktionsparametrar, som kan refereras med samma positionella syntax i funktionskroppen utanför EXECUTE .

  • Sammanfoga ditt dynamiska SQL-kommando med format() . Mycket renare och säkrare. Citera och undvik identifierare , kod och värden ordentligt! %1$I och %1$L är formatspecifikationer för format() . Läs manualen för detaljer.

  • Rätt fall krävs! Din konvention att stava identifierare med stora bokstäver är meningsfull i Oracle, där identifierare utan citattecken konverteras till versaler. Det är inte användbart i Postgres, där allt viks till gemener istället:

  • Använd inte ILIKE i DAD_NOME ILIKE 'USU_NASCIMENTO' . Postgres-identifierare är skiftlägeskänsliga. Du kunde har flera matchande värden i dad_nome . Använd = istället och skicka identifierare stavade korrekt. Och se till att dad_nome definieras unikt. Se nedan.

  • Din kommentar säger:MOD_USUARIO , -- Translated to: User (ID) . Men det är inte det man klarar av. Manualen:

    Du kanske vill använda current_user eller session_user istället:

  • Du kan ta bort LIMIT 1 från underfrågan om dad_nome är definierad som UNIQUE . Annars måste du bestämma vilken rad du ska välja vid oavgjort - med ORDER BY .

  • Triggerfunktioner krävs för att avsluta med en RETURN påstående. Kan lika gärna vara RETURN NULL för en AFTER utlösare. Handboken:

Relaterat:

Åsido: Medan du är ny på Postgres kanske du vill använda den här typen av avancerad dynamisk SQL noggrant. Du måste förstå vad du gör.



  1. Ansluter SAP Lumira till Microsoft Access

  2. Kan jag använda ett Postgres-nyckelord som ett alias i den valda listan?

  3. Välj översta raderna tills värdet i den specifika kolumnen har visats två gånger

  4. Konvertera nvarchar till bigint i SQL Server 2008