PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak przekazać STARY, NOWY i identyfikatory do WYKONANIA w funkcji wyzwalacza?

Oto jak twoja funkcja wyzwalacza będzie działać poprawnie:

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;

Główne punkty

  • Przekaż specjalne wartości wierszy OLD i NEW jak również TG_RELID jako wartości EXECUTE z USING klauzula. Być może będziesz musiał przesłać TG_RELID do typu danych dopasowania. Definicja tabeli tb_modificacoes jest nieujawniony. Albo naprawdę chcesz tutaj czegoś innego. Zobacz poniżej.
    $1 , $2 i $3 w ciągu SQL przekazanym do EXECUTE odnoszą się do wyrażeń w USING klauzula, nie do parametrów funkcji, do których można się odwoływać za pomocą tej samej składni pozycyjnej w treści funkcji na zewnątrz EXECUTE .

  • Połącz swoje dynamiczne polecenie SQL za pomocą format() . O wiele czystszy i bezpieczniejszy. Cytuj i uciekaj identyfikatory , kod i wartości odpowiednio! %1$I i %1$L są specyfikatorami formatu dla format() . Przeczytaj instrukcję, aby uzyskać szczegółowe informacje.

  • Wymagana jest prawidłowa wielkość liter! Twoja konwencja pisowni identyfikatorów wielkimi literami ma sens w Oracle, gdzie niecytowane identyfikatory są konwertowane na duże litery. Nie jest to przydatne w Postgresie, gdzie wszystko składa się do małych liter:

  • Nie używaj ILIKE w DAD_NOME ILIKE 'USU_NASCIMENTO' . W identyfikatorach Postgres rozróżniana jest wielkość liter. możesz mieć wiele pasujących wartości w dad_nome . Użyj = zamiast tego i przekaż poprawnie napisane identyfikatory. I upewnij się, że dad_nome jest zdefiniowany jako unikalny. Zobacz poniżej.

  • Twój komentarz brzmi:MOD_USUARIO , -- Translated to: User (ID) . Ale to nie jest to, co mijasz. Instrukcja:

    Możesz użyć current_user lub session_user zamiast tego:

  • Możesz usunąć LIMIT 1 z podzapytania, jeśli dad_nome jest zdefiniowany UNIQUE . W przeciwnym razie musisz zdecydować, który wiersz wybrać w przypadku remisu - za pomocą ORDER BY .

  • Funkcje wyzwalania są wymagane zakończyć za pomocą RETURN oświadczenie. Równie dobrze może być RETURN NULL dla AFTER cyngiel. Podręcznik:

Powiązane:

Na bok: Jeśli jesteś nowy w Postgresie, możesz chcieć ostrożnie używać tego rodzaju zaawansowanego dynamicznego SQL. Musisz zrozumieć, co robisz.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wstawianie wielu rekordów z pg-promise

  2. Erlang i PostgreSQL

  3. Jak pogrupować dzieci i rodziców w jednym zapytaniu?

  4. Zainstaluj sortowanie utf8 w PostgreSQL

  5. Zastąp sekwencję szeregową w PostgreSql za pomocą Entity Framework (C#)