通过小 SQL(ite) 实践,我尝试创建一个具有复合主键的表:
CREATE TABLE NAMES (
TYPE INTEGER NOT NULL,
SEQ INTEGER NOT NULL,
NAME VARCHAR(20),
PRIMARY KEY (TYPE, SEQ)
);
这个想法是存储从数字到名称的关联,即:SEQ
往返NAME
。由于此类“类”的数量可变,因此我添加了一TYPE
列,即SEQ
数字(和NAME
s)在特定的TYPE
.
我还尝试创建一个触发器,该触发器将自动分配SEQ
特定中的“下一个空闲”号码,TYPE
如下所示:
CREATE TRIGGER TRG_NAMES_ADD AFTER INSERT ON NAMES
FOR EACH ROW BEGIN
UPDATE NAMES SET SEQ = (SELECT COUNT(1) FROM NAMES WHERE TYPE = NEW.TYPE)
WHERE TYPE = NEW.TYPE;
END;
当我插入第一个条目时,它似乎有效,但是当我尝试添加第二个条目时,它失败了
运行时错误:UNIQUE 约束失败:NAMES.TYPE、NAMES.SEQ (19)
像这样:
sqlite> select * from NAMES;
sqlite> insert into NAMES (type, seq, name) values (0, -1, "test"); sqlite> select * from NAMES;
0|1|test
sqlite> insert into NAMES (type, seq, name) values (0, -1, "test2");
Runtime error: UNIQUE constraint failed: NAMES.TYPE, NAMES.SEQ (19)
sqlite> insert into NAMES (type, seq, name) values (1, -1, "test2");
sqlite> select * from NAMES;
0|1|test
1|1|test2
所以触发器似乎对每个TYPE
都只工作一次,但也许不起作用,因为第一个SEQ
应该是 0 而不是 1。
我也尝试过使用BEFORE
而不是AFTER
触发器,但这不会改变SEQ
一切(使用-1)。
触发器有什么问题,还是表定义有问题?
问题是触发器中
WHERE
缺少非唯一子句。AND SEQ = NEW.SEQ
此版本的触发器工作正常: