J'essaie de créer un déclencheur Postgres pour vous assurer que la valeur d'une colonne a été définie, elle ne peut pas être mise à jour (essentiellement le rendre réadien). Jusqu'à présent, j'ai proposé le projet de déclencheur suivant.
1) D'abord, suis-je sur la bonne piste?
[.____] 2) Y a-t-il une valeur dans le retour NEW
?
3) Dois-je préférer original_id
avec NEW.
?
CREATE FUNCTION check_id_change() RETURNS TRIGGER AS $$
BEGIN
IF OLD.original_id <> NEW.original_id THEN
RAISE EXCEPTION 'cannot change original_id';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER client_update_trigger AFTER UPDATE ON client FOR EACH ROW
EXECUTE PROCEDURE check_id_change();
Utiliser un before update
gâchette.
Voulez-vous soulever une exception ou simplement le faire en silence de ne pas changer la valeur?
Oui, vous devriez revenir NEW
.
Oui, vous devez préfixer le nom de la colonne avec NEW
ou OLD
.
Vous pouvez l'utiliser si vous ne voulez pas constituer une exception:
create function check_id_change() returns trigger language plpgsql as $$
begin
new.original_id = old.original_id;
return new;
end $$;
Créer un BEFORE UPDATE
sur votre colonne spécifique original_id
.
Notez que l'application utilisant la DB doit être consciente de ses contraintes, il est donc préférable de soulever une exception lorsque la colonne est mise à jour, afin d'informer la couche d'application d'une défaillance, au lieu de simplement ignorer la mise à jour.
CREATE OR REPLACE FUNCTION check_id_change()
RETURNS TRIGGER AS
$BODY$
BEGIN
IF NEW."original_id" IS DISTINCT FROM OLD."original_id"
THEN
RAISE EXCEPTION '"original_id" column cannot get updated';
END IF;
RETURN NEW;
END;
$BODY$ LANGUAGE PLPGSQL;
CREATE TRIGGER client_update_trigger
BEFORE UPDATE OF "original_id"
ON "client"
FOR EACH ROW
EXECUTE PROCEDURE check_id_change();
Ou en utilisant WHEN
condition
CREATE OR REPLACE FUNCTION check_id_change()
RETURNS TRIGGER AS
$BODY$
BEGIN
RAISE EXCEPTION '"original_id" column cannot get updated';
END;
$BODY$ LANGUAGE PLPGSQL;
CREATE TRIGGER client_update_trigger
BEFORE UPDATE OF "original_id"
ON "client"
FOR EACH ROW
WHEN (NEW."original_id" IS DISTINCT FROM OLD."original_id")
EXECUTE PROCEDURE check_id_change();
NOTE UTILISATION IS DISTINCT FROM
comparaison au lieu de <>
ou alors !=
Sauf si la colonne ait NOT NULL
ou vous êtes sûr que la valeur ne sera jamais la valeur NULL
.