check constraint in generated scripts - sql

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.

Related

Generating Create script for existing foreign key through SSMS

While generating the Create DB script for the existing Foreign Key constraint through SSMS, we could able to see two set of alter statements. one with NOCHECK ADD and another with CHECK.
ALTER TABLE [dbo].[claim] WITH NOCHECK ADD CONSTRAINT [FK_CLAIM_COPCID]
FOREIGN KEY([copcid])
REFERENCES [dbo].[copc] ([CopcId])
GO
ALTER TABLE [dbo].[claim] CHECK CONSTRAINT [FK_CLAIM_COPCID]
GO
Why we are getting two set of scripts to create a new Constraint?.
The first alter statement is creating a constraint and instructing that constraint to be added without checking whether the existing rows obey the new constraint.
When you add a constraint without first checking the rows, it will not be fully active until you enable it. That's what the second statement does, it enables the new constraint. If there are rows that break the constraint, you won't be able to enable it.

SQL - Running multiple ALTER queries

i'm having trouble with running multiple ALTER commands in a single query.
Whenever im trying to run the following code :
ALTER TABLE Book$
ALTER COLUMN PID INT NOT NULL
ALTER TABLE Book$
ADD CONSTRAINT pk_book PRIMARY KEY(PID)
I get an error :
Cannot define PRIMARY KEY constraint on nullable column in table 'Book$'.
But if i run the queries separately , first :
ALTER TABLE Book$
ALTER COLUMN PID INT NOT NULL
And then :
ALTER TABLE Book$
ADD CONSTRAINT pk_book PRIMARY KEY(PID)
Everything seems to work just fine.
What am i doing wrong? Thanks!
Add GO(batch separator) in between to fix the problem
ALTER TABLE Book$
ALTER COLUMN PID INT NOT NULL
GO
ALTER TABLE Book$
ADD CONSTRAINT pk_book PRIMARY KEY(PID)
Without GO the entire script will be considered as single script
I'm not sure which database you are using. To explain what is happening, though, you need to understand two phases of statement processing: Compilation and Execution.
The Compilation phase reads the statement and defines the execution plan. The Execution phase then runs the plan. Nothing about the table changes just because a statement is compiled.
What is happening is that the two statements are compiled and then executed. When the second is compiled, nothing has changed (well, except for the fact that the first statement's execution plan is stored somewhere). Hence, you are getting a compilation error.
When you run the two separately, the changes from the first take place and then the second does not generate an error.

The check keyword not working in sql management studio

I have two tables tblA and tblB. And a constraint called tblA_tblB_FK is created between these tables. I wanted to update both columns in tables chained with tblA_tblB_FK constraint. While reading different posts I thought the best way is to disable the constraint for a moment and enable again after the update. For that reason I executed these queries:
alter table tblA NOCHECK CONSTRAINT tblA_tblB_FK
After this step I did the update and till now everything was OK, but then I tried to enable again the constraint, so I executed this query:
ALTER TABLE tblA CHECK CONSTRAINT tblA_tblB_FK
and it says command successfully completed. But when I try to make update again it doesn't stop me from doing that, meaning there is a problem with the enabling process. I tried to execute another query:
ALTER TABLE tblA WITH CHECK CHECK CONSTRAINT tblA_tblB_FK
and it doesn't allow me complaining there is tblA_tblB_Fk constraint active. I don't understand why it allows me to make an update, while it doesn't allow me to execute this command?
I am using SQL Server 2005. Thanks in advance for any suggestions!
Check you insert and update specification for the foreign key in management studio under Table>Table_name>Keys folder. It might be set to "Cascade".

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.

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

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]