37

I have a table defined by the following SQL:

CREATE TABLE test (
  id       integer PRIMARY KEY NOT NULL UNIQUE,
  status   text NOT NULL,
  enddate  date,
  /* Checks */
  CHECK (status IN ("Current", "Complete"))
);

I'd like to add a constraint using CHECK that requires enddate to be non-null if the status is "Complete".

Is this possible? I am using SQLite v3.6.16.

3 Answers 3

50

How about:

CHECK (status = "Current" or (status = "Complete" and enddate is not null))
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, this works. Is this the only way? In future I may have a larger number of statuses and the check could grow quite large.
When constraints get very complex, the approach is typically to put a layer in front of the table to enforce it. Like a stored procedure layer, or a data access library.
Well, SQLite currently does not support Stored procs, so only way to achive it will be either having triggers or implementing the logic from the UI layer.
@Rezzie I think if the statuses grow, you can still use this construct with a little modification: CHECK (status <> "Complete" or (status = "Complete" and enddate is not null)); notice that it has no mention of "Current" at all. You'll need to keep CHECK (status IN ("Current", "Complete")) as well to validate possible status values. If multiple statuses require enddate, you should be able to change <> and = to NOT IN and IN.
This could really be shortened down to (status <> "Complete" or enddate is not null) There's no need recheck the value of status, if you're checking the second half of the or statement, you already know status = "complete"
4

There's nothing stopping you from having multiple CHECK constraints on a single table. IMO the simplest and most easily expandable solution:

CHECK (status IN ("Current", "Complete"))
CHECK (status <> "Complete" OR enddate IS NOT NULL)

This uses the fact that if A then B is logically equivalent to either not A or B.

Comments

0
CREATE TABLE test (
  id       integer PRIMARY KEY,
  status   text NOT NULL CHECK (status IN ('Current', 'Complete')),
  enddate  date NOT NULL
);

This will work in SQLite, with the CHECK constraint written inline. I changed double quotes to apostrophes so it can be used in PHP.

1 Comment

Did you read the question? He even put the important part in bold what you just dismissed.

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.