Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

274
Views
How to make a PostgreSQL constraint only apply to a new value

I'm new to PostgreSQL and really loving how constraints work with row level security, but I'm confused how to make them do what I want them to.

I have a column and I want add a constraint that creates a minimum length for a text column, this check works for that:

(length((column_name):: text) > 6)

BUT, it also then prevents users updating any rows where column_name is already under 6 characters.

I want to make it so they can't change that value TO that, but can still update a row where that is already happening, so they can change it as needed according to my new policy.

Is this possible?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

BUT, it also then prevents users updating any rows where column_name is already under 6 characters.

Well, no. When you try to add that CHECK constraint, all existing rows are checked, and an exception is raised if any violation is found.
You would have to make it NOT VALID. Then yes.

You really need a trigger on INSERT or UPDATE that checks new values. Not as cheap and not as bullet-rpoof, but still pretty solid. Like:

CREATE OR REPLACE FUNCTION trg_col_min_len6()
  RETURNS trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
   IF TG_OP = 'UPDATE'
   AND OLD.column_name IS NOT DISTINCT FROM NEW.column_name THEN
      -- do nothing
   ELSE
      RAISE EXCEPTION 'New value for column "note" must have at least 6 characters.';
   END IF;
  
   RETURN NEW;
END
$func$;

-- trigger
CREATE TRIGGER tbl1_column_name_min_len6
BEFORE INSERT OR UPDATE ON tbl
FOR EACH ROW
WHEN (length(NEW.column_name) < 7)
EXECUTE FUNCTION trg_col_min_len6();

db<>fiddle here

It should be most efficient to check in a WHEN condition to the trigger directly. Then the trigger function is only ever called for short values and can be super simple.
See:

  • Trigger with multiple WHEN conditions
  • Fire trigger on update of columnA or ColumnB or ColumnC
over 4 years ago · Santiago Trujillo Report

0

You can create separate triggers for Insert and Update letting each completely define when it should fired. If completely different logic is required for the DML action this technique allows writing dedicated trigger functions. In this case that is not required the trigger function reduces to raise exception .... See Demo

-- Single trigger function for both Insert and Delete
create or replace function trg_col_min_len6()
  returns trigger
  language plpgsql 
as $$
begin
   raise exception 'Cannot % val = ''%''. Must have at least 6 characters.'
                 , tg_op, new.val;
   return null;
end;
$$;

-- trigger before insert 
create trigger tbl_val_min_len6_bir
    before insert 
        on tbl
       for each row
      when (length(new.val) < 6)
      execute function trg_col_min_len6();

-- trugger before update 
create trigger tbl_val_min_len6_bur
    before update
        on tbl
       for each row    
      when (    length(new.val) < 6
            and new.val is distinct from old.val 
           ) 
     execute function trg_col_min_len6();
  
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!