Usando gatilhos para impor restrições
-
06-07-2019 - |
Pergunta
Eu estou tentando impor a integridade em uma mesa de uma forma que eu não acho que a restrição pode ...
CREATE TABLE myData
(
id INTEGER IDENTITY(1,1) NOT NULL,
fk_item_id INTEGER NOT NULL,
valid_from DATETIME NOT NULL,
invlaid_from DATETIME NOT NULL
)
A restrição eu quero aplicar é que nunca deve haver nenhuma entrada para o mesmo "fk_item_id" com datas sobrepostas.
Nota:
invalid_from é o instante imediatamente após o período válido.
Isto significa que os dois períodos seguintes são muito bem ...
- '2008 01 de janeiro 00:00' -> '2008 01 de fevereiro 00:00' (All de Jan)
- '2008 01 de fevereiro 00:00' -> '2008 01 de março 00:00' (Todos fevereiro)
posso verificar essa regra em um gatilho. Quando o gatilho faz encontrar um insert / update ilegal, no entanto, qual é a melhor maneira de evitar os "ilegais" inserções / atualizações de acontecer?
(se o Inserida inclui dois registros válidos e dois registros inválidos, eu posso parar apenas os dois registros inválidos?)
Cheers,
Dems.
EDIT:
No caso eu tinha anteriormente, uma restrição usando uma função funcionou bem. Mas eu nunca funcionou porque o RAISERROR não funciona na versão gatilho.
Eu pensei que era porque o gatilho é um gatilho AFTER, e que eu precisaria de um gatilho antes, mas isso não parece ser uma opção ...
Solução
Você não pode excluir diretamente do inseridas (atualizações às tabelas lógicas gerar um erro), mas você pode juntar-se de volta para a tabela de origem como visto abaixo
create table triggertest (id int null, val varchar(20))
Go
create trigger after on [dbo].triggertest
for Update
as
Begin
delete tt from triggertest tt inner join
inserted i on tt.id = i.id
where i.id = 9
End
GO
insert into triggertest values (1,'x')
insert into triggertest values (2,'y')
Update triggertest set id = 9 where id = 2
select * from triggertest
1, x
Além disso, você não tem que ir a rota gatilho, você também pode vincular uma restrição de verificação para o valor de retorno de uma função
Alter table myData WITH NOCHECK add
Constraint CHK_VALID CHECK (dbo.fx_CheckValid(id, valid_from , invalid_from) = 1 );
Outras dicas
Não apague os registros da tabela inserida ... isso é falha silenciosa. A estrada para o inferno está pavimentado em submissões parcial.
Você precisa RAISERROR , que é essencialmente o que um < a href = "http://msdn.microsoft.com/en-us/library/ms188066.aspx" rel = "nofollow noreferrer"> restrição faria.
Seu gatilho poderia modificar o valid_from
e / ou invlaid_from
s DATETIME
dos registros "ilegais" para valores especiais. A etapa de limpeza posterior poderia identificar os registros "ilegais".
Aumentar um erro.