Хорошо, я только что кое-что узнал.
Так что получается, что с CHECK CONSTRAINTS и UPDATES, CONSTRAINT проверяется, только если один из столбцов, на которые есть ссылки в CONSTRAINT, изменился.
В вашем случае ваш CONSTRAINT проверяет UDF, которому вы передаете ItemID
.
В вашем UPDATE, по-видимому, вы изменяете только значение Allocation
, а не ItemID
, поэтому оптимизатор думает: «Если ItemID
не изменился, то нет необходимости проверять ограничение", и это не так, и ОБНОВЛЕНИЕ завершается успешно, даже несмотря на то, что CONSTRAINT должна была его потерпеть.
Я проверил это, перестроив вашу функцию и ограничение и добавив к ней Allocation
:
ALTER FUNCTION [dbo].[fn_AllocationIsValid] (@itemId as int, @Allocation int)
RETURNS int AS
BEGIN
DECLARE @isValid bit;
SELECT @isValid = CASE WHEN ISNULL(SUM(Allocation), 0) <= MAX(Inventory) THEN 1 ELSE 0 END
FROM Allocations A
JOIN Items I ON I.Id = A.ItemId
WHERE I.Id = @itemId
GROUP BY I.Id;
RETURN @isValid;
END
И:
ALTER TABLE [dbo].[Allocations] WITH CHECK ADD CONSTRAINT [CK_Allocations]
CHECK (([dbo].[fn_AllocationIsValid]([Itemid], Allocation)=(1)))
GO
Обратите внимание, что мне сначала пришлось УБРАТЬ исходное ограничение и обрезать / заново заполнить таблицу, но я не хочу, чтобы я показал вам, как это сделать.
Также обратите внимание, что Allocation
не участвует ни в какой логике функции.Я вообще не менял логику, я просто добавил параметр для @Allocation
.Параметр никогда не используется.
Затем, когда я сделал UPDATE, который поднял сумму Allocation
до значения MAX, я получил ожидаемую ошибку:
Оператор UPDATE конфликтовалс ограничением CHECK "CK_Allocations".Конфликт произошел в базе данных "Tab_Test", таблице "dbo.Allocations".
Почему?Поскольку @Allocation
не не используется в логике функции, столбец Allocation
равен с ссылкой в CONSTRAINT, поэтому оптимизатор проверяет ограничение, когда значениеиз Allocation
изменений.
Некоторые утверждают, что из-за подобных вещей всегда предпочтительнее использовать TRIGGER вместо CHECK CONSTRAINT, который вызывает UDF.Я не уверен, и я не видел никаких воспроизводимых экспериментов, которые доказывают это.Но я оставляю это на ваше усмотрение, каким путем вы хотите пойти с этим.
Надеюсь, эта информация окажется полезной для некоторых будущих читателей.
PS: Приписывая должное доверие, я узнал все это сНекоторая помощь из сообщения на форуме в моем комментарии к вопросу, которая привела к этому блогу по теме .