I am new to Postgresql, so please indulge if my question makes no sense.
I am trying to find a way to migrate my DB structure to Postgresql, in particular, I find functions quite convenient and would like to make my numerous triggers easier to write.
In my DB, I use the standard last_modified and last_modified_by fields to keep track of changes. I also use a standard primary key with incremental sequence.
There is built-in syntax to link sequences to primary key id's, but as I have to write triggers for the last_modified fields anyway, I was wondering if it was possible to have a generic function to update all at once.
Example:
Table ANIMAL has fields AMIMAL_ID (primary key, with sequence SEQ_ANIMAL), fields LAST_MODIFIED and LAST_MODIFIED_BY. 
Similarly, I have a table PLANT with fields PLANT_ID (primary key, with sequence SEQ_PLANT), fields LAST_MODIFIED and LAST_MODIFIED_BY again.
I would like to create a generic function to be called in the 4 triggers I need to create. I was hoping to get something like this:
Before insert function:
CREATE FUNCTION TRIGGER_BI(p_pkField text, p_Sequence text) RETURNS TRIGGER AS $$
DECLARE
        curtime timestamp := now();
BEGIN
    NEW.LAST_UPDATED := curtime;
    NEW.LAST_UPDATED_BY := current_user;
    NEW.p_pkField := nextval(p_Sequence);
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
Before update function:
CREATE FUNCTION TRIGGER_BU() RETURNS TRIGGER AS $$
DECLARE
        curtime timestamp := now();
BEGIN
    NEW.LAST_UPDATED := curtime;
    NEW.LAST_UPDATED_BY := current_user;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
And now, the triggers of table ANIMAL:
Before Insert:
CREATE TRIGGER ANIMAL
BEFORE INSERT
    FOR EACH ROW EXECUTE PROCEDURE TRIGGER_BI("ANIMAL_ID", "SEQ_ANIMAL");
Before Update:
CREATE TRIGGER ANIMAL
    BEFORE UPDATE
        FOR EACH ROW EXECUTE PROCEDURE TRIGGER_BU();
Triggers of table PLANT:
Before Insert:
CREATE TRIGGER PLANT
BEFORE INSERT
    FOR EACH ROW EXECUTE PROCEDURE TRIGGER_BI("PLANT_ID", "SEQ_PLANT");
Before Update:
CREATE TRIGGER PLANT
    BEFORE UPDATE
        FOR EACH ROW EXECUTE PROCEDURE TRIGGER_BU();
Is it possible, in any way, to get something generic this way?
YES! What is the correct syntax? BONUS: it is event possible to have a single function to do all the work, with default empty parameters that, if empty, would not update the sequence.
YES, BUT WAIT! what are the down-sides of such an approach? (performance, security, anything else to be considered)?
NO! So I really need on function for each trigger?
UPDATE: I explicitly create sequences because I may want to have shared sequences among several tables. The idea is to use the shared sequence as a unique parent table with several child tables having a foreign key on their primary key to the parent table. Don't hesitate to comment on this approach, but my basic understanding is that accessing a sequence's next value is much more efficient than having to manage foreign keys...
UPDATE 2:
I found some quite interesting stuff which nearly gets me there - only that my setValue function isn't working...
Here the generic trigger:
CREATE OR REPLACE FUNCTION TRIGGER_FUNC() RETURNS TRIGGER AS $$
DECLARE
    p_pkField  text;
    p_Sequence text;
    pkValue    int;
BEGIN
    EXECUTE format('SELECT ($1).%I::int', TG_ARGV[0]) USING NEW INTO pkValue;
    p_Sequence := quote_ident(TG_ARGV[1]);
    IF pkValue IS NULL THEN
        SELECT setfieldValue(pg_typeof(NEW), TG_ARGV[0], nextval(p_Sequence));
    END IF;
    NEW.LAST_UPDATED := curtime;
    NEW.LAST_UPDATED_BY := current_user;
    RETURN NEW;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
I found a hint to the solution of the setValue function here and tried adapting it, but it doesn't work - am I simply using a wrong call? Or can I use some additional knowledge in the method to make it simpler? (I already used the fact that I am setting a bigint value, but I might be able to do better?!)
Here the (non-working) code:
CREATE OR REPLACE FUNCTION public.setfieldValue(anyelement, text, bigint)
 RETURNS anyelement
 LANGUAGE plpgsql
AS $function$
DECLARE 
  _name text;
  _values text[];
  _value text;
  _attnum int;
BEGIN
  FOR _name, _attnum
     IN SELECT a.attname, a.attnum
          FROM pg_catalog.pg_attribute a 
         WHERE a.attrelid = (SELECT typrelid
                               FROM pg_type
                              WHERE oid = pg_typeof($1)::oid) 
  LOOP
    IF _name = $2 THEN
      _value := $3;
    ELSE
      EXECUTE 'SELECT (($1).' || quote_ident(_name) || ')::text' INTO _value USING $1;
    END IF;
    _values[_attnum] :=  COALESCE('"' || replace(replace(_value, '"', '""'), '''', '''''') || '"', ''); 
  END LOOP;
  EXECUTE 'SELECT (' || quote_ident(pg_typeof($1)::text) || ' ''(' || array_to_string(_values,',') || ')'').*' INTO $1; 
  RETURN $1;
END;
$function$;
 
     
     
    