why is t-sql allowing me to violate a check constraint that uses a UDP?

China☆狼群 提交于 2020-02-04 04:21:05

问题


I have a check constraint on a table in my DB. My understanding of a check is it sets a logical condition that must be true for records in a table.

USE [myDB]
GO

ALTER TABLE [dbo].[myTable]  WITH CHECK ADD  CONSTRAINT [oneProgramPerTest] CHECK  (([dbo].[howManyProgPerTest]([TestId])<(2)))
GO

ALTER TABLE [dbo].[myTable] CHECK CONSTRAINT [oneProgramPerTest]
GO

But I am able to do an update to the table that breaks the constraint. After the update, this query returns 9 records:

select COUNT (*) from myDB.dbo.myTable where myDB.[dbo].[howManyProgPerTest](testID)>1

What might be going on?


回答1:


Beware using UDFs in check constraints for this reason. This blog post describes your issue. To summarize:

(A UDF) will on the surface do its job, as long as you INSERT into the table. But if you update a row and only set the otherColumn for some row from 0 to 1, then the check constraint will not be checked.

The optimizer is smart enough to understand that the update doesn't change anything that we refer to in our CHECK constraint, so why bother checking the constraint?

End result here is that the constraint doesn't do what we want it to do. Use a trigger instead (or some other method).

(Emphasis added)




回答2:


If I may, based on the name of your constraint, are you trying to ensure that there is only one program per test? If both the program and the test are available in the same table, add a unique constraint.



来源:https://stackoverflow.com/questions/15438184/why-is-t-sql-allowing-me-to-violate-a-check-constraint-that-uses-a-udp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!