Reputation: 134
I have next table
create table use_flags3 (
id INTEGER,
flag_name VARCHAR NOT NULL,
flag_description VARCHAR NOT NULL,
flag_type_id INTEGER NOT NULL,
package_id INTEGER,
FOREIGN KEY (flag_type_id) REFERENCES use_flags_types(id),
FOREIGN KEY (package_id) REFERENCES packages(id),
PRIMARY KEY (id)
);
I need flag_name
column to be unique only when flag_type_id equals to 1. I tried to achieve this with next constraint
CONSTRAINT idx1_chk CHECK (
flag_type_id in (select id from use_flags_types where flag_type="local") or
flag_type_id in (select id from use_flags_types where flag_type="expand") or
flag_type_id in (select id from use_flags_types where flag_type="expand_hidden") or
(
flag_type_id in (select id from use_flags_types where flag_type="global") and
flag_name not in (select flag_name from use_flags)
)
)
sqlite says 'subqueries prohibited in CHECK constraints'. I can replace
flag_type_id in (select id from use_flags_types where flag_type="local")
with
flag_type_id = ${ID_HERE} -- id from `select id from use_flags_types where flag_type="local"`
but I can not do same trick for 2nd subpart of the last part of constraint
flag_name not in (select flag_name from use_flags)
Is there any chance to do what I originally want within one table (I would really don't like to split those data in 2(+) tables)?
// hope description is quite clear
Upvotes: 3
Views: 1112
Reputation: 14596
If you have a complex constraint, you should use triggers:
http://sqlfiddle.com/#!7/2094c
CREATE TABLE use_flags3 (
id INTEGER,
flag_name VARCHAR NOT NULL,
flag_description VARCHAR NOT NULL,
flag_type_id INTEGER NOT NULL,
package_id INTEGER,
FOREIGN KEY (flag_type_id) REFERENCES use_flags_types(id),
FOREIGN KEY (package_id) REFERENCES packages(id),
PRIMARY KEY (id)
);
/* TRIGGER BEFORE UPDATE version omitted */
CREATE TRIGGER fake_unique
BEFORE INSERT ON use_flags3
FOR EACH ROW
WHEN (
EXISTS (SELECT NULL
FROM use_flags_types
WHERE flag_type IN( "local", "expand", "expand_hidden")
AND flag_type_id = id
)
OR (
EXISTS (SELECT NULL
FROM use_flags_types
WHERE flag_type="global"
AND flag_type_id = id)
AND flag_name NOT IN (SELECT flag_name FROM use_flags)
)
)
BEGIN
SELECT RAISE( ABORT, 'duplicate rows' );
END;
Upvotes: 4