Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger with dynamic field name

I have a problem on creating PostgreSQL (9.3) trigger on update table. I want set new values in the loop as

EXECUTE 'NEW.'|| fieldName || ':=''some prepend data'' || NEW.' || fieldName || ';';

where fieldName is set dynamically. But this string raise error

ERROR:  syntax error at or near "NEW"

How do I go about achieving that?

like image 919
FlyBot Avatar asked Aug 02 '16 07:08

FlyBot


People also ask

What are triggers in Dynamics NAV?

Triggers are predefined functions that are executed when certain actions happen. The bodies of these functions are initially empty and must be defined by the developer. Defining C/AL code in triggers allows you to change the default behavior of Dynamics NAV. Tables have the following triggers. A new record is inserted into the table.

What is the difference between a trigger and a field?

Tables have the following triggers. A new record is inserted into the table. A record in the table is modified. A record in the table is deleted. A record is modified in a primary key field. Fields have the following triggers. Data is entered in a field or when the VALIDATE Function (Record) is executed.

How do I execute C/Al code defined in a trigger?

In response, you can set up Dynamics NAV to execute C/AL code defined in a trigger. Triggers are predefined functions that are executed when certain actions happen. The bodies of these functions are initially empty and must be defined by the developer. Defining C/AL code in triggers allows you to change the default behavior of Dynamics NAV.


1 Answers

You can implement that rather conveniently with the hstore operator #=:

Make sure the additional module is installed properly (once per database), in a schema that's included in your search_path:

  • How to use % operator from the extension pg_trgm?
  • Best way to install hstore on multiple schemas in a Postgres database?

Trigger function:

CREATE OR REPLACE FUNCTION tbl_insup_bef()
  RETURNS TRIGGER AS
$func$
DECLARE
   _prefix CONSTANT text := 'some prepend data'; -- your prefix here
   _prelen CONSTANT int  := 17;  -- length of above string (optional optimization)
   _col text := quote_ident(TG_ARGV[0]);
   _val text;
BEGIN
   EXECUTE 'SELECT $1.' || _col
   USING NEW
   INTO _val;

   IF left(_val, _prelen) = _prefix THEN 
      -- do nothing: prefix already there!
   ELSE
      NEW := NEW #= hstore(_col, _prefix || _val);  
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

Trigger (reuse the same func for multiple tables):

CREATE TRIGGER insup_bef
BEFORE INSERT OR UPDATE ON tbl
FOR EACH ROW
EXECUTE PROCEDURE tbl_insup_bef('fieldName');  -- unquoted, case-sensitive column name

Closely related with more explanation and advice:

  • Assignment of a column with dynamic column name
  • How to access NEW or OLD field given only the field's name?
  • Get values from varying columns in a generic trigger
like image 69
Erwin Brandstetter Avatar answered Oct 24 '22 13:10

Erwin Brandstetter