我有一个表,我希望防止插入重复的行。
CREATE TABLE blah(id INTEGER PRIMARY KEY ASC, a INTEGER, b INTEGER, c, d, e, f,
UNIQUE (a,b,c,d,e,f) ON CONFLICT IGNORE);
现在我插入几行:
INSERT INTO event2 (a,b,c,d)
VALUES (1,1405451500,"Y",100),
(1,1405451555,"Z",115);
现在,如果我重新运行上面的命令,我希望它不会插入任何内容,因为新行完全匹配已经存在的行。相反,我看到插入了两个新行。
读取SQLite documentation,如果一个或多个列为NULL,则SQLite似乎不会强制执行UNIQUE约束。如果有某种方法可以使用其他一些机制来实现这一目标?在上述情况下,c
,d
,e
和f
列可以为null。或者我可以使用空字符串而不是NULL但是阅读其他一些答案似乎表明null不应该与空字符串混淆,因为它们表示单独的东西。
答案 0 :(得分:0)
您可以使用BEFORE INSERT
触发器来检查数据的正确性。
请注意,这会在每次插入之前进行全表扫描,因此对于较大的表,它会导致插入速度变慢!
要加快速度(并避免全表扫描),您应CREATE INDEX
,其中包括触发器中检查的所有列。
以下是您使用示例的方式:
CREATE TRIGGER event2uniqTrigger
BEFORE INSERT ON event2
WHEN (
SELECT count( * )
FROM event2 t
WHERE ( CASE
WHEN new.a IS NULL THEN t.a IS NULL
ELSE t.a = new.a
END )
AND
( CASE
WHEN new.b IS NULL THEN t.b IS NULL
ELSE t.b = new.b
END )
AND
( CASE
WHEN new.c IS NULL THEN t.c IS NULL
ELSE t.c = new.c
END )
AND
( CASE
WHEN new.d IS NULL THEN t.d IS NULL
ELSE t.d = new.d
END )
AND
( CASE
WHEN new.e IS NULL THEN t.e IS NULL
ELSE t.e = new.e
END )
AND
( CASE
WHEN new.f IS NULL THEN t.f IS NULL
ELSE t.f = new.f
END )
) > 0
BEGIN
SELECT RAISE ( FAIL, 'inserted value not unique' );
END;
和索引:
CREATE INDEX event2idx ON event2 (a, b, c, d, e, f);
您可能还想为BEFORE UPDATE
创建另一个触发器。它看起来就像上面的那个,除了BEFORE UPDATE
部分。