snippetsqlModerate
How to create a Postgres trigger to ensure field is non-updateable
Viewed 0 times
updateablefieldtriggerpostgrescreatenonensurehow
Problem
I'm trying to create a Postgres trigger to ensure after a column's value has been set, it cannot be updated (basically make it readonly). So far I've come up with the following draft trigger.
1) First, am I on the correct track?
2) Is there value in returning
3) Must I preface
1) First, am I on the correct track?
2) Is there value in returning
NEW?3) Must I preface
original_id with 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();Solution
Create a
NOTE since the application which is using the DB should be aware of its constraints, therefore it is better to raise an exception when the column is getting updated, in order to notify the application layer of a failure, instead of just ignoring the update.
Or using
NOTE use
BEFORE UPDATE on your specific column original_id.NOTE since the application which is using the DB should be aware of its constraints, therefore it is better to raise an exception when the column is getting updated, in order to notify the application layer of a failure, instead of just ignoring the update.
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();Or using
WHEN conditionCREATE 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 use
IS DISTINCT FROM comparison instead of <> or != unless the column has NOT NULL or you're sure that it's value will never be NULL.Code Snippets
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();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();Context
StackExchange Database Administrators Q#74517, answer score: 15
Revisions (0)
No revisions yet.