7

I would like to disable the DELETE statement on a table. What I need to do is a SET a field value instead of removing the respective record.

So far I have tried the following:

CREATE TRIGGER delete_trg
INSTEAD OF DELETE
ON schema.tbl
FOR EACH ROW
EXECUTE PROCEDURE schema.tbl_delete_fn();

My schema.tbl_delete_fn() function is as follows:

CREATE OR REPLACE FUNCTION schema.tbl_delete_fn()
  RETURNS trigger AS
BEGIN
  NEW.deleted := true;

  RETURN NEW;
END;

So far this doesn't seem to work... any ideas?

2
  • 1
    Are you trying to define trigger on a view or on a table? Commented Aug 13, 2013 at 17:23
  • 2
    "Didn't work" ? Exact behaviour, error message, etc? Commented Aug 14, 2013 at 1:11

2 Answers 2

12

You want a BEFORE DELETE trigger whose function returns NULL and the row variable is OLD, not NEW.

CREATE TRIGGER delete_trg
BEFORE DELETE
ON schema.tbl
FOR EACH ROW
EXECUTE PROCEDURE schema.tbl_delete_fn();

CREATE OR REPLACE FUNCTION schema.tbl_delete_fn()
  RETURNS trigger AS '
BEGIN
  UPDATE schema.tbl SET deleted=true WHERE ctid=OLD.ctid;
  RETURN NULL;
END; ' language plpgsql;
Sign up to request clarification or add additional context in comments.

2 Comments

This trigger will block DELETE but wont change the row that is deleated.
@Igor: you're right, edited to use UPDATE instead, tested and it appears to work
6

Or...

CREATE RULE delete_rule 
AS ON DELETE TO schema.tbl
DO INSTEAD NOTHING;

Pros: Clearer, no code is called for each row visited, and no SP required.

Cons: Less standard than the trigger solution.

1 Comment

But it doesn't update the column of the "not deleted" row.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.