24

What is the postgres equivalent of the below mysql code

CREATE TABLE t1 (
  created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE t2 (
  created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  modified TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

As per Alex Brasetvik answer below, it seems i should go with triggers, my problem is i have a number of tables t1, t2... with created and modified fields, is it possible to write a generalized procedure?

--update Almost ready

CREATE FUNCTION update_timestamp() RETURNS trigger AS $update_timestamp$
    BEGIN
        NEW.modified := current_timestamp;
        RETURN NEW;
    END;
$update_timestamp$ LANGUAGE plpgsql;

CREATE TRIGGER update_timestamp BEFORE INSERT OR UPDATE ON t1
    FOR EACH ROW EXECUTE PROCEDURE update_timestamp();
CREATE TRIGGER update_timestamp BEFORE INSERT OR UPDATE ON t2
    FOR EACH ROW EXECUTE PROCEDURE update_timestamp();

5 Answers 5

32

Just make sure all tables have the same columnname:

CREATE OR REPLACE FUNCTION upd_timestamp() RETURNS TRIGGER 
LANGUAGE plpgsql
AS
$$
BEGIN
    NEW.modified = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$;

CREATE TRIGGER t_name
  BEFORE UPDATE
  ON tablename
  FOR EACH ROW
  EXECUTE PROCEDURE upd_timestamp();
Sign up to request clarification or add additional context in comments.

Comments

13

Thank you for the information Mithun and Alex Brasetvik.

I'd like to add one minor tweak to the trigger. Since we mostly likely want the modified column to store the timestamp when the row was last changed, not when it was the target of an UPDATE statement, we have to compare the new and the old value of the row. We update the modified column only if these two values differ.

CREATE OR REPLACE FUNCTION update_modified_timestamp() RETURNS TRIGGER 
LANGUAGE plpgsql
AS
$$
BEGIN
    IF (NEW != OLD) THEN
        NEW.modified = CURRENT_TIMESTAMP;
        RETURN NEW;
    END IF;
    RETURN OLD;
END;
$$;

This trigger ensures that the modified column is updated only if the UPDATE operation actually changes the values stored in the row.

1 Comment

I think makes sense, but I run the query to ChatGPT and found few issues. this is the result --> stackoverflow.com/a/79774370/13903942
5

Update it with a trigger. Documentation and examples.

Comments

3

To further improve, the answer given by @Lauri Silvennoinen:

This trigger uses the WHEN clause as recommended by the official docs to check for changes in the row even before calling the specified function.

CREATE OR REPLACE FUNCTION update_modified_timestamp() RETURNS TRIGGER 
LANGUAGE plpgsql
AS
$$
BEGIN
    NEW.modified = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$;

CREATE OR REPLACE TRIGGER tg_update_modified
    AFTER UPDATE ON table_name
    FOR EACH ROW
    WHEN (OLD.* IS DISTINCT FROM NEW.*)
    EXECUTE FUNCTION update_modified_timestamp();

Comments

0

Improvement from Lauri Silvennoinen https://stackoverflow.com/a/10246381/13903942

I've asked ChatGPT to check for issue from the suggest query, these are the results:

CREATE OR REPLACE FUNCTION util.touch_updated_at()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    IF NEW IS DISTINCT FROM OLD THEN
        NEW.updated_at := CURRENT_TIMESTAMP;
    END IF;
    RETURN NEW;
END;
$$;

Add to a table

CREATE TRIGGER set_updated_at
BEFORE UPDATE ON auth.users
FOR EACH ROW
EXECUTE FUNCTION util.touch_updated_at();

Why?

🔹 Issues with IF (NEW != OLD)

  • In PL/pgSQL, != between two records (NEW and OLD) doesn’t work the way you expect.
    You’ll get an error like:

    ERROR:  operator does not exist: record <> record
    
    
  • PostgreSQL doesn’t define a direct row-to-row comparison operator. You need to use IS DISTINCT FROM

🔹 The proper check

IF NEW IS DISTINCT FROM OLD THEN
    NEW.modified := CURRENT_TIMESTAMP;
    RETURN NEW;
END IF;
RETURN OLD;🔹 The proper check
IF NEW IS DISTINCT FROM OLD THEN
    NEW.modified := CURRENT_TIMESTAMP;
    RETURN NEW;
END IF;
RETURN OLD;

IS DISTINCT FROM is null-safe (unlike <>).
→ So if one column is NULL and the other isn’t, it’s considered different.
→ If both are NULL, they’re considered the same.

Comments

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.