es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué no puedo ACTUALIZAR una tabla de Postgresql donde tengo definido un DISPARADOR (TRIGGER) con ANTES DE ACTUALIZAR?

En PostgreSQL, tengo una tabla con un disparador definido que llama a una función definida en PostgreSQL. El disparador es “BEFORE UPDATE”. Con el disparador definido, no puedo realizar actualizaciones en la tabla en cuestión. Si redefino el disparador como “AFTER UPDATE”, todo funciona correctamente. ¿Alguna idea de por qué?

La tabla es similar a la siguiente:

create table user (
id bigserial constraint pk_user primary key,
username varchar,
hasreadinstructions smallint,
hasstarted smallint,
hasendeddataentry smallint,
hasviewedresults smallint,
email varchar,
firstname varchar,
lastname varchar,
registrationdate timestamp);

Y la función es:

create function perform_notify() returns trigger
language plpgsql
as
$$
BEGIN
PERFORM pg_notify(‘has_read_instructions’, ‘foo’);
RETURN NULL;
END;
$$;

El disparador es:

CREATE TRIGGER has_read_instructions BEFORE UPDATE
ON user FOR EACH ROW EXECUTE PROCEDURE
perform_notify();

Si defino el disparador con BEFORE UPDATE, como se muestra, las actualizaciones en la tabla no funcionan, por ejemplo:

update user set hasreadinstructions = 1 where id = 1;

El resultado es UPDATE 0 y el valor no cambia.

Si cambio el disparador a “AFTER UPDATE”, todo parece funcionar correctamente y mi actualización en la tabla se realiza con el resultado UPDATE 1 y el valor se cambia.

En este caso, no me importa particularmente si uso BEFORE o AFTER, pero estoy perdido en cuanto a por qué; cualquier ayuda para entender esto será apreciada.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El motivo del problema se debe al hecho de que el desencadenador BEFORE UPDATE se dispara antes de que se realice la actualización real. En este caso, se llama a la función perform_notify() antes de que se realice la actualización, notificando así a las partes necesarias que el usuario ha leído las instrucciones. Sin embargo, como la actualización aún no se ha realizado, la columna hasreadinstructions aún está configurada en su valor original de 0, y tratar de actualizarla a 1 con la instrucción UPDATE no produce cambios.

    Por otro lado, si el desencadenador se define como AFTER UPDATE, la función perform_notify() se llama después de que se haya realizado la actualización, permitiendo así que la columna se actualice al valor deseado de 1 antes de que se envíe la notificación.

    Por lo tanto, la elección de utilizar BEFORE o AFTER depende del comportamiento deseado del desencadenador y si debe ejecutarse antes o después de que se realice la actualización.

Comments are closed.