Temporary disable foreignkeys? - sql

I saw thisone in MSDN magazine.i wanted to Temporary disable Foreignkeys,Can i do using following code.. Not needed to delete but temporary disable because i wanted to enable again
ALTER TABLE Orders
NOCHECK CONSTRAINT
FK_Orders_Customers

-- Disable the constraint.
ALTER TABLE Orders NOCHECK CONSTRAINT FK_Orders_Customers
-- Reenable the constraint.
ALTER TABLE Orders WITH CHECK CHECK CONSTRAINT FK_Orders_Customers

Yes, as you've suspected ALTER TABLE [table] CHECK / NOCHECK CONSTRAINT *FK_Name* enables and disables foreign key constraint checking. It also proves why it is a good idea to explicitly name your constraints i.e. to avoid names like FK__TABLE__A2A64E930CBAE877.
One point to note that after inserting / changing data with disabled foreign key constraints is that SQL won't trust your constraint if you simply enable it with CHECK CONSTRAINT. You will need to do the following to get SQL to recheck the constraint during re enable:
ALTER TABLE [table] WITH CHECK CHECK CONSTRAINT *FK_Name*
You can check for violations with
DBCC CHECKCONSTRAINTS ([table])
Ref : http://msdn.microsoft.com/en-us/library/ms177456(v=sql.90).aspx (Disabling Constraints) and also see http://geekswithblogs.net/dturner/archive/2011/01/31/sql-constraints-check-and-nocheck.aspx

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.

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.

Oracle Dependencies exists error

When I try to disable the constraint I am getting the following error
cannot disable constraint (SCOTT.EMPLOYEE_PK) - dependencies exist
Please give me the solution for this problem.
Can I use CASCADE to disable the constraint?
If I use CASCADE, then will I able to enable the constraint again?
According to the documentation the action to do is:
Either disable the foreign key constraints or use disable cascade
So use this to disable the primary key and its index:
alter table employee disable primary key
You can re-enable the index/constraint when done, but make sure you don't invalidate the index:
alter table employee enable primary key
Also read: Modifying, Renaming, or Dropping Existing Integrity Constraints.

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?