Reputation: 86
How do I set unique constraint over multiple columns when any one can be null in SQLite?
e.g. I have made unique("col1","col2","col3")
and tried insert into tablename values("abc","def",null)
twice it inserted both rows.
The unique constraint is not working when third column is null.
Upvotes: 4
Views: 1957
Reputation: 3786
Starting with version 3.9.0 (2015-10-14) you can use indexes on expressions (https://www.sqlite.org/expridx.html) and use for example the COALESCE
function to transform null
values into some form of fallback value:
CREATE UNIQUE INDEX IX_Unique ON Table1 (
COALESCE(col1, ""),
COALESCE(col2, ""),
COALESCE(col3, "")
);
Upvotes: 2
Reputation: 180280
You could create a trigger to enfore this:
CREATE TRIGGER col1_col2_col3null_unique
BEFORE INSERT ON MyTable
FOR EACH ROW
WHEN col1 IS NOT NULL
AND col2 IS NOT NULL
AND col3 IS NULL
BEGIN
SELECT RAISE(ABORT, 'col1/col2/col3 must be unique')
FROM MyTable
WHERE col1 = NEW.col1
AND col2 = NEW.col2
AND col3 IS NULL;
END;
You need such a trigger for each possible combination of NULLs in the three columns. Furthermore, if it is possible to have UPDATEs that change such a column to NULL, you need triggers for those, too.
Upvotes: 1
Reputation: 6627
In sqlite, all null are differences. I think the best way to solve this issue is to set column c not null with a special default value. Then use the default value (for example 0, '') to represent null.
you can easily extend this solution to any columns
create table test (
a text not null default "",
b text not null default "",
c text not null default ""
);
Upvotes: 5