Please explain the syntax the SQLServer uses to create a check constraint - sql

When I right click on a default constraint and I ask SQL Server to create a CREATE script for it, it generates the following code:
ALTER TABLE [dbo].[tblEventTurnJudgeStartValues] WITH NOCHECK ADD CONSTRAINT [tblEventTurnJudgeStartValues_ExecutionToggle] CHECK (([ExecutionToggle]=(1) OR [ExecutionToggle]=(0) OR [ExecutionToggle]=(-1)))
GO
ALTER TABLE [dbo].[tblEventTurnJudgeStartValues] CHECK CONSTRAINT [tblEventTurnJudgeStartValues_ExecutionToggle]
For the record, I understand the first ALTER statement but I do not understand what the the second alter statement does. Tried to google the "CHECK CONSTRAINT" phrase but only got hits on the add constraint syntax.
Thanks.
Seth
update
Thanks Joe for your answer. Found this link which helps.
http://blog.sqlauthority.com/2009/11/12/sql-server-disable-check-constraint-enable-check-constraint/
I did not know that you could enable and disable constraints. Cool!
Seth

The first statement creates the constraint, but since it is created with NOCHECK, existing data is not validated at the time of creation.
The second statement simply turns the constraint on and is technically redundant.
Personally, I'd prefer the second statement be written with the WITH CHECK option, which will validate all existing data against the constraint and will prevent the constraint from becoming untrusted.
ALTER TABLE [dbo].[tblEventTurnJudgeStartValues] WITH CHECK CHECK CONSTRAINT [tblEventTurnJudgeStartValues_ExecutionToggle]

Related

Why is SQL Server is adding a check constraint to my nocheck FK constraint?

SQL Server is adding a check constraint to my nocheck constraint.
I start with this:
ALTER TABLE [dbo].[Subjects] WITH NOCHECK ADD CONSTRAINT [FK_Subject_OrganizationSubjectRank] FOREIGN KEY([OrganizationId], [StatusId], [Rank])
REFERENCES [dbo].[OrganizationSubjectRanks] ([OrganizationId], [OrganizationSubjectStatusId], [Name])
GO
And SQL server adds this to my code every time I execute:
ALTER TABLE [dbo].[Subjects] CHECK CONSTRAINT [FK_Subject_OrganizationSubjectRank]
GO
This is causing foreign key constraint errors.
How do I prevent SQL server from adding this check constraint to my code?
The short answer is to run:
ALTER TABLE [dbo].[Subjects] NOCHECK CONSTRAINT [FK_Subject_OrganizationSubjectRank]
The explanation is that WITH CHECK | WITH NOCHECK and CHECK | NOCHECK have two separate functionalities. WITH CHECK | WITH NOCHECK applies to, and only to existing data at the time the command is run. CHECK | NOCHECK applies to, and only to new data.
When creating a FK Constraint, you have the WITH CHECK | WITH NOCHECK options regarding the existing data, but the CHECK option is automatically set. That is why you see the second command. In order to override the default of CHECK you need to explicitly run an additional NOCHECK command.
See this link for further reference: https://sqlpowered.com/foreign-keys-check-nocheck-and-with-check/
This is expected behavior.
When you create a constraint using WITH NOCHECK, all that means is that, at the time you ALTER the table and ADD the constraint, the constraint will not be checked to see if the data already in the table conflicts with it.
After that, it becomes a regular constraint like any other. All future INSERT/UPDATES will have to comply with the constraint. So if you refresh your SSMS and Script the table, you will just see the CONSTRAINT without any NOCHECK.
To summarize, NOCHECK only matters while you are altering the table. After that, it has no effect, and the constraint acts the same as if you had not used NOCHECK when you created it.
If you are trying to permanently REMOVE the constraint, then you need to DROP it.

Difference in SQL syntax for enabling a constraint (SQL Server)

Is there any difference between these two statements below?
ALTER TABLE [table_name] CHECK CONSTRAINT [constraint_name]
and
ALTER TABLE [table_name] WITH CHECK CHECK CONSTRAINT [constraint_name]
From Alter Table documentation:
WITH CHECK | WITH NOCHECK:
Specifies whether the data in the table is or is not validated against a newly added or re-enabled FOREIGN KEY or CHECK constraint. If not specified, WITH CHECK is assumed.
So, since the default is to do it "WITH CHECK", there is no difference at all.
The WITH CHECK clause will check any existing data and fail if there is data that doesn't meet the constraint. Without the WITH CHECK clause, the constraint will only apply to new data added to the table.
If the table has no data in it, then the statements are functionally equivalent.
Here is the documentation for the ALTER TABLE command in question:
http://msdn.microsoft.com/en-us/library/ms190273.aspx
It's a rather lengthy page, so I'll quote from it:
WITH CHECK | WITH NOCHECK
Specifies whether the data in the table is or is not validated against a newly added or re-enabled
FOREIGN KEY or CHECK constraint. If not specified, WITH CHECK is assumed for new constraints,
and WITH NOCHECK is assumed for re-enabled constraints.
It goes on to give this advice:
If you do not want to verify new CHECK or FOREIGN KEY constraints against existing data, use WITH
NOCHECK. We do not recommend doing this, except in rare cases. The new constraint will be
evaluated in all later data updates. Any constraint violations that are suppressed by WITH NOCHECK
when the constraint is added may cause future updates to fail if they update rows with data that
does not comply with the constraint.

What does second check constraint mean?

I have the following code
--first statement
ALTER TABLE [nameOfMyTable] WITH CHECK ADD CONSTRAINT [nameOfMyConstraint] FOREIGN KEY([myFK])
REFERENCES [tableReference] ([myFK])
GO
--second statement
ALTER TABLE [nameOfMyTable] CHECK CONSTRAINT [nameOfMyConstraint]
GO
First, i define a CHECK constraint on a table. What does mean second statement?
The 2nd statement is redundant, the only time it would be needed is if the first statement had WITH NOCHECK. By default WITH CHECK is added if you don't explicitly state CHECK or NOCHECK in the ADD CONSTRAINT statement.
sql server management studio generate this code by default – Mikhail
Because the code is being auto generated it is just being constructed by a set of steps. Some of those steps will have some overlap so the "table definition" step may enable or disable the check the constraint while it creates the table, but the "setup constraints" step may also enable or disable the constraint.
Relevant documentation:
WITH CHECK | WITH NOCHECK
Specifies whether the data in the table is or is not validated against a newly added or re-enabled FOREIGN KEY or CHECK constraint.
If not specified, WITH CHECK is assumed for new constraints, and WITH
NOCHECK is assumed for re-enabled constraints.
If you do not want to verify new CHECK or FOREIGN KEY constraints against existing data, use WITH NOCHECK. We do not recommend doing
this, except in rare cases. The new constraint will be evaluated in
all later data updates. Any constraint violations that are suppressed
by WITH NOCHECK when the constraint is added may cause future updates
to fail if they update rows with data that does not comply with the
constraint.
The query optimizer does not consider constraints that are defined WITH NOCHECK. Such constraints are ignored until they are re-enabled
by using ALTER TABLE WITH CHECK CHECK CONSTRAINT ALL.
{ CHECK | NOCHECK } CONSTRAINT
Specifies that constraint_name is enabled or disabled. This option can only be used with FOREIGN KEY and CHECK constraints. When NOCHECK
is specified, the constraint is disabled and future inserts or updates
to the column are not validated against the constraint conditions.
DEFAULT, PRIMARY KEY, and UNIQUE constraints cannot be disabled.
From the docs:
Specifies that constraint_name is enabled or disabled. This option can only be used with FOREIGN KEY and CHECK constraints. When NOCHECK is specified, the constraint is disabled and future inserts or updates to the column are not validated against the constraint conditions. DEFAULT, PRIMARY KEY, and UNIQUE constraints cannot be disabled.
The second statement in the given context is redundant if run immediately after the creation of the constraint (with out without WITH CHECK, creation of the foreign key constraint with ADD CONSTRAINT FOREIGN KEY will do the WITH CHECK immediately by default).
The second statement is used to reenable constraint checking
ALTER TABLE [nameOfMyTable] CHECK CONSTRAINT [nameOfMyConstraint];
usually after it has been disabled, like so:
ALTER TABLE [nameOfMyTable] NOCHECK CONSTRAINT [nameOfMyConstraint];
GO
Scripting tools often create DDL like this - overkill, although I guess they really want to be sure :)
There is a third flavour, which is to re-check the validity of the constraint, e.g. after doing a Bulk Copy or similar which may have invalidated the constraint (marked it as untrusted). This is done like so:
ALTER TABLE [nameOfMyTable] WITH CHECK CHECK CONSTRAINT [nameOfMyConstraint];
Edit Hopefully this SQLFiddle clears this up?

MS SQL Server - What is the value of WITH CHECK in a foreign key constraint?

When I have SQL Server Management Studio generate a table creation script for me, the foreign key constraints are a bit different than how I would write them.
Here is one:
ALTER TABLE [dbo].[GeoBytesCountries]
WITH CHECK
ADD CONSTRAINT [FK_GeoBytesCountries_MapReferenceId]
FOREIGN KEY ([MapReferenceId])
REFERENCES [dbo].[GeoBytesMapReferences] ([MapReferenceId])
GO
ALTER TABLE [dbo].[GeoBytesCountries]
CHECK CONSTRAINT [FK_GeoBytesCountries_MapReferenceId]
GO
I would write this foreign key constraint without "WITH CHECK" and the 2nd "CHECK CONSTRAINT" statement and expect to get the same functionality.
Can someone explain to me the value of the using "WITH CHECK" and a separate "CHECK CONSTRAINT" statement when you are writing a foreign key constraint for a table?
Or is the code below completely / functionally equivalent to the code above?
ALTER TABLE [dbo].[GeoBytesCountries]
ADD CONSTRAINT [FK_GeoBytesCountries_MapReferenceId]
FOREIGN KEY ([MapReferenceId])
REFERENCES [dbo].[GeoBytesMapReferences] ([MapReferenceId])
GO
The way I see it, the two step approach allows you to at least keep more "bad" data from getting in assuming the with check part fails. That is, your constraint will exist and apply to DML from that point forward, but you may have to do some cleanup on your existing data to make it a trusted constraint.

check constraint in generated scripts

In SSMS, Tasks > Generate Scripts, I have selected a few tables and in the generated SQL I get:
ALTER TABLE [Project] WITH CHECK ADD CONSTRAINT [FK_Project_aspnet_Users] FOREIGN KEY([UserId])
REFERENCES [aspnet_Users] ([UserId])
GO
ALTER TABLE [Project] CHECK CONSTRAINT [FK_Project_aspnet_Users]
GO
Why does it CHECK in the second statement if WITH CHECK is specified in the first? The second statement appears directly after the first.
TIA
You are correct to observe that it is redundant.
It's just the way that SSMS generates scripts.
Note that the script could be modified after it is generated. That first statement could be changed to use 'WITH NO CHECK', and that second statement would not be redundant.
The purpose of the first statement is to add the constraint.
The purpose of the second statement is to enable the constraint.
At least, that's the way I read the script. If I were manually running the statements one by one, I might get a "constraint already exists" exception, but that constraint might not be enabled.
I would still run the second statement, to ensure the existing constraint gets enabled.