SQL Server - Constraint using UDF always violates
Asked By Zodma
23-Sep-08 01:43 AM

I'm trying to write a check constraint that uses a UDF to validate whenever
an INSERT or UPDATE occures. I can write the UDF and configure the
constraint, however when I do an insert I always get an "INSERT statement
conflicted with the CHECK constraint" error, even though if I call the UDF
directly I get the right result.
Here's an example. Create the table Items:
-----------------------------------------------------------
CREATE TABLE [dbo].[Items] (
[Name] [nvarchar](50) NOT NULL
) ON [PRIMARY]
-----------------------------------------------------------
Next, create the UDF:
-----------------------------------------------------------
create FUNCTION [dbo].[CheckItem]
(
@Name nvarchar(50)
)
RETURNS bit
AS
BEGIN
DECLARE @Result bit
set @result = cast(0 as bit)
if ( select count([name])
from Items
where [name] = @name
) = 0
begin
set @Result = cast(1 as bit)
end
RETURN @Result
END
-----------------------------------------------------------
Then set up the constraint:
-----------------------------------------------------------
ALTER TABLE dbo.Items WITH NOCHECK ADD CONSTRAINT CK_Items CHECK
(dbo.CheckItem([Name])=(1))
-----------------------------------------------------------
Now try an insert and witness the error:
-----------------------------------------------------------
declare @name as nvarchar(50)
set @name='item 1'
insert into items values (@name)
-----------------------------------------------------------
However, the function returns (1):
-----------------------------------------------------------
declare @name as nvarchar(50)
set @name='item 1'
select dbo.checkitem(@name)
if dbo.checkitem(@name)=(1)
select 'Yes'
else
select 'No'
-----------------------------------------------------------
What is wrong with this constraint?
Carl.
CREATE TABLE
(1)
ALTER TABLE
(1)
SQL Server
(1)
CONSTRAINT
(1)
NOT NULL
(1)
Constraints
(1)
Nvarchar
(1)
Table
(1)
Tibor Karaszi replied...
Personally, I don't use constraints that work over several rows, for the reasons you see here. If
you check the estimated execution plan, you will see that the insert is performed first, then the
check constraint is verified. This might not seem intuitive, but that is what is performed. I don't
know whether there is documented *when* the various types of constraints are done, logically, but as
I mentioned, I avoid check constraints being dependent on other rows in the same table for these
reasons. Your example could have been done with a unique constraint (methinks), but I assume it was
only an example...
--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://sqlblog.com/blogs/tibor_karaszi
Zodma replied...
Ahhh, thank you. This was driving me crazy, as I -was- expecting the UDF to
be executed before the insert.
I'm a novice with using execution plans, but from your response I can now
see that the insert is executed first.
And yes, the example was just an example. The real use case I'm trying to
resolve is a table that stores either unique or non-unique values of certain
fields depending on the value of a foreign key.
Now that I can see how the UDF constraint works I may normalise the design
instead anyway for performance reasons.
Thanks again!
Carl.
Database Engine Tuning Advisor SQL Server I am trying to use the Database Engine Tuning Advisor. I have the developer edition Engine Tuning Advisor. When I start the Database Engine Tuning Advisor for either version of SQL I get the same message when I click Connect using either the sa account or to open a new connection. Additional information: Could not find stored procedure 'msdb. . sp_DTA_help_session'. (Microsoft SQL Server.Error:2812) I have checked and the stored procedure does not exist in msdb for either SQL05 or 08. - - Regards, James M SQL Server Tools Discussions SQL Server 2000 (1) SQL Server 2008 (1) SQL Server 2005 (1) AllDistinctDbIds.DatabaseID (1) IsDatabaseSelectedToTune
Problem with DROP CONSTRAINT SQL Server When I issue the following T-SQL 2008: ALTER TABLE ALIS.mc.LOCApp DROP CONSTRAINT LOCApp_Created_df I get the following errors: Msg 1781, Level 16, State 1, Line 1 Column a DEFAULT bound to it. Msg 1750, Level 16, State 0, Line 1 Could not create constraint. See previous errors. I can see the constraint exists in Object Explorer. If I
2 questions regarding db design: check constraint and many-to-many relationship SQL Server Hi, as I said earlier in this group that I am new to db design this task by myself. I have 2 questions below: 1. I like to use check constraint to maintain data integrity. But to what extent should we use check constraint since most data *can* be validated in one way or the other. What are the basic guidelines in applying check constraints to table columns? 2. If two entities have a many-to-many relationship, for example, Roles vs. Users, we usually create a link table called UserRoleAssignments. Should we have a primary key for such link tables? Murach's SQL
multiple cascade paths SQL Server Hi, I hate the multiple cascade paths error. I always use SQLCMD but the other day when I was using SQL Server Management Studio Express multiple cascade paths with cascade updates and deletes relationship successfully setup from Table A col1 -> TableB col1 and Table A col2 -> TableB col2. Am I dreaming ? Has someone tried this ? The relationship setup successfully tables. Something that can setup data integrity triggers (cascade updates / deletes) wysiwyg way ? Thanks, Shripal. SQL Server Discussions SQL Server 2008 (1) SQL Server 2005 (1) SQL Server (1) MySQL (1) Oracle
Check constraint with a scalar UDF not working SQL Server CREATE TABLE [dbo].[Orders]( [ID] [int] IDENTITY(1, 1) NOT NULL, [Title] [nchar](10) NOT NULL, [Order_Status] [nchar](10) NOT NULL, CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS