考虑到我们在尝试将新行插入表时遇到UNIQUE constraint failed
错误。
该行由几个主键组成,这些主键被链接以创建复合键约束,即由4个字段id
,id_x
,id_y
和id_z
组合而成。
第一个id
关键需要是一个unique
键,“自动递增”,而id_x
,id_y
和id_z
是foreign keys
。
由于我们无法在sqlite中对复合键使用自动增量功能,因此我们使用以下触发器来查找每个字段的最高整数并添加1以满足唯一性约束:
CREATE TRIGGER [autoincrement]
AFTER INSERT
ON table_main
WHEN NEW.id IS NULL
BEGIN
UPDATE table_main
SET id = IFNULL((SELECT MAX(id) FROM table_main) + 1, 0),
id_x = IFNULL((SELECT MAX(id_x) FROM table_main) + 1, 0),
id_y = IFNULL((SELECT MAX(id_y) FROM table_main) + 1, 0),
id_z = IFNULL((SELECT MAX(id_z) FROM table_main) + 1, 0);
END;
尽管如此,我们仍然得到UNIQUE constraint failed
错误。
更新:id_z
有一个forign key
约束。
由于我们无法在复合键上使用自动增量功能
以下是具有增加的唯一ID的复合键(您称之为自动增量): -
DROP TABLE IF EXISTS table_main;
DROP TABLE IF EXISTS table_fkx;
DROP TABLE IF EXISTS table_fky;
DROP TABLE IF EXISTS table_fkz;
DROP TRIGGER IF EXISTS [autoincrement];
CREATE TABLE IF NOT EXISTS table_fkx (id INTEGER PRIMARY KEY, datacol TEXT);
CREATE TABLE IF NOT EXISTS table_fky (id INTEGER PRIMARY KEY, datacol TEXT);
CREATE TABLE IF NOT EXISTS table_fkz (id INTEGER PRIMARY KEY, datacol TEXT);
CREATE TABLE IF NOT EXISTS table_main (
id INTEGER PRIMARY KEY,
id_x INTEGER REFERENCES table_fkx(id),
id_y INTEGER REFERENCES table_fky(id),
id_z INTEGER REFERENCES table_fkz(id),
UNIQUE(id, id_x, id_y, id_z)
);
/*
CREATE TRIGGER [autoincrement]
AFTER INSERT
ON table_main
WHEN NEW.id IS NULL
BEGIN
UPDATE table_main
SET id = IFNULL((SELECT MAX(id) FROM table_main) + 1, 0),
id_x = IFNULL((SELECT MAX(id_x) FROM table_main) + 1, 0),
id_y = IFNULL((SELECT MAX(id_y) FROM table_main) + 1, 0),
id_z = IFNULL((SELECT MAX(id_z) FROM table_main) + 1, 0);
END;
*/
INSERT INTO table_fkx VALUES (10,'some data'),(33,'more data'),(56,'even more data');
INSERT INTO table_fky VALUES (73,'some data'),(1200,'more data'),(560,'even more data');
INSERT INTO table_fkz VALUES (15,'some data'),(1500,'more data'),(123456,'even more data');
INSERT INTO table_main (id_x,id_y,id_z) VALUES
(10,1200,15),(56,1200,15),(33,560,15),(10,73,15) -- etc
;
-- INSERT what could be a considered a duplicate but now is not as the autoincremnt(sic) makes it unique
INSERT INTO table_main (id_x,id_y,id_z) VALUES (33,560,15); -- i.e. same as 3rd
SELECT * FROM table_main
JOIN table_fkx ON id_x = table_fkx.id
JOIN table_fky ON id_y = table_fky.id
JOIN table_fkz ON id_z = table_fkz.id
;
但是,如果复合键的一部分是唯一的,则意味着您可以有效地插入引用相同外键的潜在无用行。
也许它不是触发器,而是因为触发器。
这会将table_main
中的所有行更新为相同的键(当NEW.id
为null时)。当table_main
中有2行(或更多行)时,这肯定会导致约束违规。
UPDATE table_main
SET id = IFNULL((SELECT MAX(id) FROM table_main) + 1, 0),
id_x = IFNULL((SELECT MAX(id_x) FROM table_main) + 1, 0),
id_y = IFNULL((SELECT MAX(id_y) FROM table_main) + 1, 0),
id_z = IFNULL((SELECT MAX(id_z) FROM table_main) + 1, 0);
如果NEW.id
不为null,则问题出在其他地方。