PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да предадете СТАРИ, НОВИ и идентификатори на EXECUTE в тригерна функция?

Ето как вашата тригерна функция ще работи правилно:

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;

Основни точки

  • Предайте стойностите на специалния ред OLD и NEW както и TG_RELID като стойности за EXECUTE с USING клауза. Може да се наложи да изпълните TG_RELID към подходящ тип данни. Дефиницията на таблицата на tb_modificacoes е неразкрит. Или наистина искате нещо друго тук. Вижте по-долу.
    $1 , $2 и $3 в SQL низа, предаден на EXECUTE препраща към изразите в USING клауза, не към функционални параметри, които могат да бъдат посочени със същия позиционен синтаксис в тялото на функцията външно EXECUTE .

  • Свържете вашата динамична SQL команда, като използвате format() . Много по-чист и безопасен. Цитиране и екраниране на идентификатори , код и стойности правилно! %1$I и %1$L са спецификатори на формат за format() . Прочетете ръководството за подробности.

  • Изисква се правилен регистър! Вашата конвенция за изписване на идентификатори с главни букви има смисъл в Oracle, където идентификаторите без кавички се преобразуват в главни букви. Не е полезно в Postgres, където вместо това всичко е сгънато в малки букви:

  • Не използвайте ILIKE в DAD_NOME ILIKE 'USU_NASCIMENTO' . Идентификаторите на Postgres са чувствителни към главни и малки букви. Вие можете имат множество съответстващи стойности в dad_nome . Използвайте = вместо това и подавайте идентификатори, изписани правилно. И се уверете, че dad_nome се определя уникално. Вижте по-долу.

  • Вашият коментар гласи:MOD_USUARIO , -- Translated to: User (ID) . Но това не е това, което преминавате. Ръководството:

    Може да искате да използвате current_user или session_user вместо това:

  • Можете да премахнете LIMIT 1 от подзаявката if dad_nome е дефинирано UNIQUE . В противен случай трябва да решите кой ред да изберете в случай на равенство - с ORDER BY .

  • Функциите за задействане са задължителни за прекратяване с RETURN изявление. Може също да е RETURN NULL за AFTER спусък. Ръководството:

Свързани:

Настрани: Докато сте нови в Postgres, може да искате да използвате този вид усъвършенстван динамичен SQL внимателно. Трябва да разбирате какво правите.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Кой е най-елегантният начин за съхраняване на времеви печат с nanosec в postgresql?

  2. Как да получа списък с имена на последователности в Postgres?

  3. прекъсване на последователността row_number() на базата на флагова променлива

  4. ActiveRecord намира и връща само избрани колони, подравнени с [:id]

  5. Тригер срещу ограничение за проверка