Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add PostgreSQL column constraint based on value in other column(s)

Tags:

sql

postgresql

I have a table:

CREATE TABLE ProjectCreationTasks 
(
    Id           text NOT NULL PRIMARY KEY,
    ProjectName  text,
    ProjectCode  text,
    DenialReason text
);

An administrator can approve or deny a project creation request. To approve, the admin sets both a ProjectName and ProjectCode; to deny, the admin sets a DenialReason.

How can I add a constraint such that:

  1. Name, Code, Reason can all be null simultaneously

  2. If both Name and Code has a value then Reason must be null

  3. If Reason has a value, then both Name and Code must be null

Thank you in advance.

like image 970
mkhira2 Avatar asked Aug 31 '18 17:08

mkhira2


2 Answers

You could use CHECK constaint to implement this kind of logic:

CREATE TABLE ProjectCreationTasks ( 
Id                  text NOT NULL PRIMARY KEY,
ProjectName         text,
ProjectCode         text,
DenialReason        text,
CONSTRAINT my_constraint CHECK
((ProjectName IS NULL AND ProjectCode IS NULL AND DenialReason IS NULL)
 OR(ProjectName IS NOT NULL AND ProjectCode IS NOT NULL AND DenialReason IS NULL)
 OR(DenialReason IS NOT NULL AND ProjectName IS NULL AND ProjectCode IS NULL))
);

DBFiddle Demo

like image 72
Lukasz Szozda Avatar answered Nov 02 '22 18:11

Lukasz Szozda


The answer from Lukasz Szozda is correct as modified in my comment (the problem statement is slightly ambiguous). A slightly shorter equivalent clause that might be harder to read is

CONSTRAINT my_constraint CHECK
((ProjectName IS NULL = ProjectCode IS NULL) -- go together
    AND (ProjectCode IS NULL OR DenialReason IS NULL) -- allow both NULL but disallow both NOT NULL
);
like image 44
Andrew Lazarus Avatar answered Nov 02 '22 18:11

Andrew Lazarus