Ваш фактический подход будет работать таким образом .....
- Вы вставляете первый компонент, значение должно быть 1
- Вы пытаетесь вставить второй компонент, он будет отклонен, поскольку ваша сумма уже равна 1
- Вы обновляете существующий компонент до .85
- Вы вставляете следующий компонент, значение должно быть .15
- Вы вернетесь к шагу 2. с третьим компонентом
Поскольку ваше ограничение заботится только о столбце FKID, это будет возможно, и вы можете подумать, что это работает ....
Но .... если вы вышли из процесса на шаге 3. ваша сумма не равна 1 и ограничение не может быть предвидено, если вы введете следующее значение или нет, даже в худшем случае, вы можете обновить любое значение быть больше 1, и оно будет принято.
Если вы добавите столбец значения к своему ограничению, это предотвратит эти обновления, но вы никогда не сможете выйти за пределы шага 1.
Лично я бы этого не делал, но здесь вы можете получить подход
- Используйте вычисленный столбец, предложенный Гордоном, в вашей родительской таблице. С вычисленными столбцами вы всегда получите фактическое значение, поэтому родительский элемент не будет действительным до тех пор, пока сумма не станет равной одному
- Используйте это решение, чтобы значение не превышало 1, поэтому, по крайней мере, вы будете уверены, что любой недопустимый родитель является причиной отсутствия компонента, что может быть полезно для вашего бизнес-уровня
- Как я уже упоминал в одном комментарии, остальная часть логики принадлежит бизнесу и пользовательскому интерфейсу
Примечание , поскольку вы можете видеть, что параметры id и значения не используются в функции, но мне нужно, чтобы они вызывались при создании ограничения, таким образом, ограничение также будет проверять обновления
CREATE TABLE ttest (id int, fkid int, value float)
go
create FUNCTION [dbo].[CheckSumTarget](@id int, @fkid int, @value float)
RETURNS FLOAT
AS BEGIN
DECLARE @Res float
SELECT @Res = sum(value)
FROM dbo.ttest AS t
WHERE t.FKID = @fkid
RETURN @Res
END
GO
ALTER TABLE dbo.ttest WITH CHECK ADD CONSTRAINT [CK_Target_Sum] CHECK (([dbo].[CheckSumTarget](id,[FKID],value)<=(1.0)))