From: 20060524 on
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 = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Orders] WITH CHECK ADD CONSTRAINT
[CK_Orders_Order_Status] CHECK (([Order_Status]='Shipped' OR
[Order_Status]='InProgress'))
GO
ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [CK_Orders_Order_Status]

CREATE TABLE [dbo].[Order_Details](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Title] [nchar](10) NOT NULL,
[Orders_ID] [int] NOT NULL,
CONSTRAINT [PK_Order_Details] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
[FK_Order_Details_Orders] FOREIGN KEY([Orders_ID])
REFERENCES [dbo].[Orders] ([ID])
GO
ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT [FK_Order_Details_Orders]
GO
ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
[CK_Order_Details] CHECK (([dbo].[Order_Status]([Orders_ID])='InProgress'))
GO
ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT [CK_Order_Details]

declare @identity as int

insert Orders
select 'Title'
, 'InProgress'

set @identity = @@identity

insert Order_Details
select 'Title'
, @identity

update Orders
set Order_Status = 'Shipped'

update Order_Details
set Title = 'Title'

--Why does CK_Order_Details fire in the next update but not with the
previous update?
update Order_Details
set Title = 'Title'
, Orders_ID = @identity

drop table Order_Details
drop table Orders
From: sloan on
I'm confused.

Where is your scalar UDF?

http://sholliday.spaces.live.com/Blog/cns!A68482B9628A842A!569.entry

Check the post above.......and find the downloadable code.

I have a CHECK Constraint based on an UDF....in the example at the url
above.






<20060524(a)newsgroups.nospam> wrote in message
news:CB675C14-8660-4ED1-90B1-3BF0665ACA62(a)microsoft.com...
> 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 = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
> ) ON [PRIMARY]
>
> GO
> ALTER TABLE [dbo].[Orders] WITH CHECK ADD CONSTRAINT
> [CK_Orders_Order_Status] CHECK (([Order_Status]='Shipped' OR
> [Order_Status]='InProgress'))
> GO
> ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [CK_Orders_Order_Status]
>
> CREATE TABLE [dbo].[Order_Details](
> [ID] [int] IDENTITY(1,1) NOT NULL,
> [Title] [nchar](10) NOT NULL,
> [Orders_ID] [int] NOT NULL,
> CONSTRAINT [PK_Order_Details] PRIMARY KEY CLUSTERED
> (
> [ID] ASC
> )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
> OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
> ) ON [PRIMARY]
>
> GO
> ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
> [FK_Order_Details_Orders] FOREIGN KEY([Orders_ID])
> REFERENCES [dbo].[Orders] ([ID])
> GO
> ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT
> [FK_Order_Details_Orders]
> GO
> ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
> [CK_Order_Details] CHECK
> (([dbo].[Order_Status]([Orders_ID])='InProgress'))
> GO
> ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT [CK_Order_Details]
>
> declare @identity as int
>
> insert Orders
> select 'Title'
> , 'InProgress'
>
> set @identity = @@identity
>
> insert Order_Details
> select 'Title'
> , @identity
>
> update Orders
> set Order_Status = 'Shipped'
>
> update Order_Details
> set Title = 'Title'
>
> --Why does CK_Order_Details fire in the next update but not with the
> previous update?
> update Order_Details
> set Title = 'Title'
> , Orders_ID = @identity
>
> drop table Order_Details
> drop table Orders


From: Tibor Karaszi on
Your problem is that the update looks like:

update Orders
set Order_Status = 'Shipped'

And your constraint definition looks something like (I had a hard time
reading the DDL because of all the square brackets, btw, almost gave up...):

CHECK ((dbo.Order_Status(Orders_ID)='InProgress'))

Look at the two above. Do you see that the constraint definition doesn't (by
looking at it) refer to any of the columns you modify in the update command?
The constraint definition only refer to the Orders_ID columns, and you don't
modify that column in the UPDATE. So, SQL Server doesn't check the
constraint since it considers that the UPDATE cannot break the constraint.
This is one of the traps one can fall in when one uses UDFs in constraints.
I wouldn't be surprised if this has been blogged several times (come to
think of it, perhaps even I have blogged it...)

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://sqlblog.com/blogs/tibor_karaszi



<20060524(a)newsgroups.nospam> wrote in message
news:CB675C14-8660-4ED1-90B1-3BF0665ACA62(a)microsoft.com...
> 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 = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
> ) ON [PRIMARY]
>
> GO
> ALTER TABLE [dbo].[Orders] WITH CHECK ADD CONSTRAINT
> [CK_Orders_Order_Status] CHECK (([Order_Status]='Shipped' OR
> [Order_Status]='InProgress'))
> GO
> ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [CK_Orders_Order_Status]
>
> CREATE TABLE [dbo].[Order_Details](
> [ID] [int] IDENTITY(1,1) NOT NULL,
> [Title] [nchar](10) NOT NULL,
> [Orders_ID] [int] NOT NULL,
> CONSTRAINT [PK_Order_Details] PRIMARY KEY CLUSTERED
> (
> [ID] ASC
> )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
> OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
> ) ON [PRIMARY]
>
> GO
> ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
> [FK_Order_Details_Orders] FOREIGN KEY([Orders_ID])
> REFERENCES [dbo].[Orders] ([ID])
> GO
> ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT
> [FK_Order_Details_Orders]
> GO
> ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
> [CK_Order_Details] CHECK
> (([dbo].[Order_Status]([Orders_ID])='InProgress'))
> GO
> ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT [CK_Order_Details]
>
> declare @identity as int
>
> insert Orders
> select 'Title'
> , 'InProgress'
>
> set @identity = @@identity
>
> insert Order_Details
> select 'Title'
> , @identity
>
> update Orders
> set Order_Status = 'Shipped'
>
> update Order_Details
> set Title = 'Title'
>
> --Why does CK_Order_Details fire in the next update but not with the
> previous update?
> update Order_Details
> set Title = 'Title'
> , Orders_ID = @identity
>
> drop table Order_Details
> drop table Orders

From: Tibor Karaszi on
I found my blog post (also see the rather lengthy discussion for
elaboration):
http://sqlblog.com/blogs/tibor_karaszi/archive/2009/12/17/be-careful-with-constraints-calling-udfs.aspx

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://sqlblog.com/blogs/tibor_karaszi



<20060524(a)newsgroups.nospam> wrote in message
news:CB675C14-8660-4ED1-90B1-3BF0665ACA62(a)microsoft.com...
> 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 = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
> ) ON [PRIMARY]
>
> GO
> ALTER TABLE [dbo].[Orders] WITH CHECK ADD CONSTRAINT
> [CK_Orders_Order_Status] CHECK (([Order_Status]='Shipped' OR
> [Order_Status]='InProgress'))
> GO
> ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [CK_Orders_Order_Status]
>
> CREATE TABLE [dbo].[Order_Details](
> [ID] [int] IDENTITY(1,1) NOT NULL,
> [Title] [nchar](10) NOT NULL,
> [Orders_ID] [int] NOT NULL,
> CONSTRAINT [PK_Order_Details] PRIMARY KEY CLUSTERED
> (
> [ID] ASC
> )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
> OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
> ) ON [PRIMARY]
>
> GO
> ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
> [FK_Order_Details_Orders] FOREIGN KEY([Orders_ID])
> REFERENCES [dbo].[Orders] ([ID])
> GO
> ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT
> [FK_Order_Details_Orders]
> GO
> ALTER TABLE [dbo].[Order_Details] WITH CHECK ADD CONSTRAINT
> [CK_Order_Details] CHECK
> (([dbo].[Order_Status]([Orders_ID])='InProgress'))
> GO
> ALTER TABLE [dbo].[Order_Details] CHECK CONSTRAINT [CK_Order_Details]
>
> declare @identity as int
>
> insert Orders
> select 'Title'
> , 'InProgress'
>
> set @identity = @@identity
>
> insert Order_Details
> select 'Title'
> , @identity
>
> update Orders
> set Order_Status = 'Shipped'
>
> update Order_Details
> set Title = 'Title'
>
> --Why does CK_Order_Details fire in the next update but not with the
> previous update?
> update Order_Details
> set Title = 'Title'
> , Orders_ID = @identity
>
> drop table Order_Details
> drop table Orders

From: --CELKO-- on
We might want to make the schema relational, follow ISO-11179 rules
and so forth before we worry about other fixes. You do know that
IDENTITY is not ever a key by definition, that there is no such
creature as a magical universal “id” in RDBMS, etc.? Did you really
need to use NCHAR() for Chinese or other non-Latin codes? The data
element orders_id should be singular. Etc.

The standard design pattern for orders and their details is like this:

CREATE TABLE Orders
(order_nbr INTEGER NOT NULL PRIMARY KEY,
something_title NCHAR(10) NOT NULL,
order_status CHAR(10) DEFAULT 'in progress' NOT NULL
CHECK (order_status IN ('in progress', 'shipped'))
);


CREATE TABLE Order_Details
(order_nbr INTEGER NOT NULL
REFERENCES Orders(order_nbr)
ON UPDATE CASCADE
ON DELETE CASCADE,
item_nbr INTEGER NOT NULL
REFERENCES Inventory(item_nbr)
ON UPDATE CASCADE
ON DELETE CASCADE,
PRIMARY KEY (order_nbr, item_nbr)
item_status CHAR(10) DEFAULT 'in progress' NOT NULL
CHECK (item_status IN ('in progress', 'shipped'))
..);

Notice the use of a **REAL** relational key instead of a fake pointer
chain, the use of DRI, etc. SQL Server has supported Standard syntax
for years, so you should have written:

INSERT INTO Orders (..) VALUES (..);

thus avoiding dialect. Your whole approach is procedural, so you did
not think of a declarative design and immediately jumped to
proprietary, procedural UDFs.

Can you give a clear statement of what business rule you want to
enforce? Maybe something like: An order as a whole is 'in progress'
if any item on order is 'in progress' or something else?