INSERTAR con el nombre de la tabla dinámica en la función de activación

Resuelto sschober asked hace 12 años • 2 respuestas

No estoy seguro de cómo lograr algo como lo siguiente:

CREATE OR REPLACE FUNCTION fnJobQueueBEFORE() RETURNS trigger AS $$
    DECLARE
        shadowname varchar := TG_TABLE_NAME || 'shadow';
    BEGIN
        INSERT INTO shadowname VALUES(OLD.*);
        RETURN OLD;
    END;
$$
LANGUAGE plpgsql;

Es decir, insertar valores en una tabla con un nombre generado dinámicamente.
La ejecución del código anterior produce:

ERROR:  relation "shadowname" does not exist
LINE 1: INSERT INTO shadowname VALUES(OLD.*)

Parece sugerir que las variables no se expanden/permiten como nombres de tablas. No encontré ninguna referencia a esto en el manual de Postgres.

Ya he experimentado EXECUTEasí:

  EXECUTE 'INSERT INTO ' || quote_ident(shadowname) || ' VALUES ' || OLD.*;

Pero no hubo suerte:

ERROR:  syntax error at or near ","
LINE 1: INSERT INTO personenshadow VALUES (1,sven,,,)

El RECORDtipo parece haberse perdido: OLD.*parece convertirse en una cadena y volver a analizarse, lo que genera todo tipo de problemas de tipo (por ejemplo, NULLvalores).

¿Algunas ideas?

sschober avatar Oct 27 '11 16:10 sschober
Aceptado

Me encontré con esto porque estaba buscando un INSTEAD OF DELETEdisparador dinámico. Como agradecimiento por las preguntas y respuestas, publicaré mi solución para Postgres 9.3.

CREATE OR REPLACE FUNCTION set_deleted_instead_of_delete()
RETURNS TRIGGER AS $$
BEGIN
    EXECUTE format('UPDATE %I set deleted = now() WHERE id = $1.id', TG_TABLE_NAME)
    USING OLD;
    RETURN NULL;
END;
$$ language plpgsql;
robkorv avatar Mar 06 '2016 13:03 robkorv