Com pouca prática de SQL(ite), tentei criar uma tabela com uma chave primária composta:
CREATE TABLE NAMES (
TYPE INTEGER NOT NULL,
SEQ INTEGER NOT NULL,
NAME VARCHAR(20),
PRIMARY KEY (TYPE, SEQ)
);
A ideia é armazenar associações de números para nomes, ou seja: SEQ
para NAME
e para trás. Como existe um número variável dessas "classes" acrescentei uma TYPE
coluna, ou seja, que os SEQ
números (e NAME
s) devem ser únicos dentro de umTYPE
.
Eu também tentei criar um gatilho que atribuirá automaticamente o SEQ
número "próximo livre" dentro de um específico TYPE
como este:
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;
Quando insiro a primeira entrada, parece funcionar, mas quando tento adicionar uma segunda, falha com
Erro de tempo de execução: Falha na restrição UNIQUE: NAMES.TYPE, NAMES.SEQ (19)
assim:
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
Portanto, o gatilho parece funcionar para cada TYPE
exatamente uma vez, mas talvez não esteja funcionando, porque o primeiro SEQ
deveria ser 0 em vez de 1.
Eu também tentei um gatilho BEFORE
em vez de AFTER
, mas isso não mudaria SEQ
tudo (usando -1).
O que há de errado com o gatilho ou é a definição da tabela?
WHERE
O problema era a cláusula não exclusiva ausenteAND SEQ = NEW.SEQ
no gatilho. Esta versão do gatilho funciona corretamente: