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

Hvordan sender man GAMLE, NYE og identifikatorer til EXECUTE i en triggerfunktion?

Sådan ville din triggerfunktion fungere 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;

Vigtige punkter

  • Send de specielle rækkeværdier OLD og NEW samt TG_RELID som værdier til EXECUTE med USING klausul. Du skal muligvis caste TG_RELID til en passende datatype. Tabeldefinitionen af ​​tb_modificacoes er uoplyst. Eller du vil virkelig have noget andet her. Se nedenfor.
    $1 , $2 og $3 i SQL-strengen sendt til EXECUTE henvise til udtryk i USING klausul, ikke til funktionsparametre, som kan refereres med den samme positionelle syntaks i funktionslegemet udenfor EXECUTE .

  • Sammensæt din dynamiske SQL-kommando ved hjælp af format() . Meget renere og sikrere. Citer og escape identifikatorer , kode og værdier ordentligt! %1$I og %1$L er formatspecifikationer for format() . Læs manualen for detaljer.

  • Korrekt sag er påkrævet! Din konvention til at stave identifikatorer med store bogstaver giver mening i Oracle, hvor identifikatorer uden anførselstegn konverteres til store bogstaver. Det er ikke nyttigt i Postgres, hvor alt er foldet til små bogstaver i stedet:

  • Brug ikke ILIKE i DAD_NOME ILIKE 'USU_NASCIMENTO' . Postgres identifikatorer skelner mellem store og små bogstaver. Du kunne har flere matchende værdier i dad_nome . Brug = i stedet og videregive identifikatorer stavet korrekt. Og sørg for dad_nome er defineret unikt. Se nedenfor.

  • Din kommentar siger:MOD_USUARIO , -- Translated to: User (ID) . Men det er ikke det, du passerer. Manualen:

    Du vil måske bruge current_user eller session_user i stedet:

  • Du kan fjerne LIMIT 1 fra underforespørgslen hvis dad_nome er defineret UNIQUE . Ellers skal du bestemme, hvilken række du vil vælge i tilfælde af uafgjort - med ORDER BY .

  • Udløserfunktioner er påkrævet for at afslutte med en RETURN udmelding. Kan lige så godt være RETURN NULL for en AFTER udløser. Manualen:

Relateret:

Bortset: Mens du er ny til Postgres, vil du måske bruge denne form for avanceret dynamisk SQL omhyggeligt. Du skal forstå, hvad du laver.



  1. Når jeg INDSÆTTER flere rækker i en MySQL-tabel, vil id'erne blive øget med 1 hver gang?

  2. Optimering af Mysql-databaser

  3. Konvertering af tabel fra MyISAM til INNODB

  4. Er en deadlock mulig, når du opdaterer og sletter forskellige rækker i en tabel?