sql >> Databáze >  >> RDS >> PostgreSQL

Jak předat STARÉ, NOVÉ a identifikátory EXECUTE ve spouštěcí funkci?

Vaše spouštěcí funkce by správně fungovala takto:

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;

Hlavní body

  • Předejte speciální hodnoty řádku OLD a NEW stejně jako TG_RELID jako hodnoty na EXECUTE pomocí USING doložka. Možná budete muset odeslat TG_RELID na vhodný datový typ. Definice tabulky tb_modificacoes je nezveřejněno. Nebo tu opravdu chcete něco jiného. Viz níže.
    $1 , $2 a $3 v řetězci SQL předaném EXECUTE odkazujte na výrazy v USING klauzule, ne na parametry funkce, na které lze odkazovat se stejnou polohovou syntaxí v těle funkce mimo EXECUTE .

  • Spojte svůj dynamický příkaz SQL pomocí format() . Mnohem čistší a bezpečnější. identifikátory citujte a escapujte , kód a hodnoty správně! %1$I a %1$L jsou specifikátory formátu pro format() . Podrobnosti naleznete v příručce.

  • Je vyžadována správná velikost písmen! Vaše konvence používat identifikátory pravopisu s velkými písmeny má smysl v Oracle, kde jsou identifikátory bez uvozovek převedeny na velká písmena. Není to užitečné v Postgresu, kde je místo toho vše složeno na malá písmena:

  • Nepoužívejte ILIKE v DAD_NOME ILIKE 'USU_NASCIMENTO' . Identifikátory Postgres rozlišují velká a malá písmena. Mohli byste mít více odpovídajících hodnot v dad_nome . Použijte = místo toho a předejte správně napsané identifikátory. A ujistěte se, že dad_nome je definována jedinečná. Viz níže.

  • Váš komentář říká:MOD_USUARIO , -- Translated to: User (ID) . Ale to není to, co předáte. Manuál:

    Možná budete chtít použít current_user nebo session_user místo toho:

  • Můžete odstranit LIMIT 1 z poddotazu if dad_nome je definováno jako UNIQUE . Jinak se musíte rozhodnout, kterou řadu vybrat v případě nerozhodného výsledku – pomocí ORDER BY .

  • Spouštěcí funkce jsou vyžadovány ukončíte znakem RETURN tvrzení. Může být také RETURN NULL pro AFTER spoušť. Příručka:

Související:

Strana: Zatímco jste v Postgresu nováčkem, možná budete chtít tento druh pokročilého dynamického SQL používat opatrně. Musíte rozumět tomu, co děláte.



  1. Rekurzivní/hierarchický dotaz pomocí Postgres

  2. Načítání neúplného objektu pomocí mapování hibernace jako nativního dotazu

  3. ON DELETE SET NULL v postgres

  4. Existují nějací dobří klienti PostgreSQL pro linux?