WITH CHECK | NOCHECK OPTION FOR EXISTING DATA CHECK ENFORCEMENT IS IGNORED - sql-server

I am using Visual Studio 2012, with a SQL database project and running database analysis against this database and it is raising the following warning:
WITH CHECK | NOCHECK OPTION FOR EXISTING DATA CHECK ENFORCEMENT IS IGNORED.
My understanding of the error is that the CHECK and NOCHECK constraints will be ignored for the existing data when the script is run (in each case for me, it is an ALTER TABLE).
My question is thus, why would a check constraint be ignored?
Warning ID number
It seems the warning ID has changed so I am including both below so that it is easily searchable in future.
In Visual Studio 2010 this had the warning ID of: SQL03159
In Visual Studio 2012 this has the warning ID of: SQL70588
Related Information
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_SomeCol]

In my case, this occurred in a script I imported that had a structure like this:
CREATE TABLE [dbo].[ELMAH_Error]
(
[ErrorId] UNIQUEIDENTIFIER NOT NULL,
)
GO
ALTER TABLE [dbo].[ELMAH_Error] WITH NOCHECK ADD
CONSTRAINT [PK_ELMAH_Error] PRIMARY KEY NONCLUSTERED ([ErrorId]) ON [PRIMARY]
GO
When I look at the above code, the WITH NOCHECK looks redundant since the table should have only just been created and therefore be empty. So I suspect this code analysis warning is pointing out this redundancy.

It isn't about redundancy, but rather the fact that the project is desired state, or the ideal state of the DDL schema.
When applying the project to an existing database, the process (publish, dacpac deployment, etc) will enforce the check constraints as the delta is applied. The with check and with nocheck are therefore meaningless in the project DDL that defines the table and subsequent constraint(s).
The only place CHECK and NOCHECK are honored are in the pre and post deployment scripts.
EDIT:
If you ever generate a script from a dacpac you will notice things happen in phases.
When it comes to applying new constraints, they are always added WITH NOCHECK. The final phase is applying WITH CHECK to all constraints that need it, AFTER post deployment scripts are run. This allows the maximum amount of customization to occur during the various phases, including the pre and post deployment script phase.

Related

Why do you get "Saving changes is not permitted" when changing the length of an nvchar column in SQL?

According to this:
Microsoft description of how SQL works
This problem occurs when you make one or more of the following changes
to the table: You change the Allow Nulls setting for a column. You
reorder columns in the table. You change the column data type. You add
a new column. You change the filegroup of a table or its text/image
data.
I tried changing the max length of a nvchar from 25 to 100 on a column and it won't let me save it.
It is not at all listed as being one of the conditions under which this error should be presented.
Can anyone tell me why SSMS 18 is doing this to me?
Check for dependencies (i.e. Foreign Keys)
Use ALTER, for example
CREATE TABLE [dbo].[Test]( [aaa] nchar NULL) ON [PRIMARY] GO
ALTER TABLE Test ALTER COLUMN aaa NCHAR(100)
SSMS is quite quirky when it comes to database objects.
The article you linked to explains what the issue is.
SSMS has a safeguard built in that prevents you saving changing where its script would drop and re-create the table.
Sometimes SSMS can be overly cautious and it's not even necessary.
You can (and probably should) use the alter table syntax directly, however you can disable this behaviour in SSMS by going to:
tools > options > Designers > Table and Database Desingners
and then untick the option Prevent saving changes that require table re-creation

Missing Dependencies and Foreign Key Constraint - SQLCompare Red gate

We use SQL Compare 11.6.11.2463 to move our database changes to different environments. When we doing that we notices that Table definitions were changes and Foreign Key Constraint was altered where the data in the table was not correct. I have a question here that why the constraint were modified without giving an error that data is bad for that constraint and it should have error while deploying that Foreign Key Constraint.
Second Question is, When we are seeing the dependencies of a table, it does not show all the procedures that table is referenced and used. We are missing the dependencies when we right click on a table and see View Dependencies. Is something changed by the use of SQL Compare as we are not seeing Dependencies.

SQL Server change collation on varchar columns that has a foreign key constraint

Is there any easier way to change the collation on columns with foreign key constraints than manually removing them and adding them back up?
I have tried the disabling of the constraints without luck with the statement:
ALTER TABLE PM_Minnekorter NOCHECK CONSTRAINT ALL
Is it possible to automate the dropping of the constraints and recreation of them again? or is it any other better solutions?
Well we cannot change collation of column which are referenced.
It is clearly mentioned in this link https://msdn.microsoft.com/en-us/library/ms190920.aspx.
As far as automate dropping and creating question is concerned we can do that.
You can see it here. [the code is already exlained and available so giving it]
https://www.mssqltips.com/sqlservertip/3347/drop-and-recreate-all-foreign-key-constraints-in-sql-server/

Different behavior in 2 SQL servers

I have a project that run some integration tests. The project creates a new database each time and run the tests against this new db. Recently I moved this project to a new server and I'm having some issues when delete data from the db.
I execute the following query:
DELETE FROM TABLE1;
DELETE FROM TABLE2;
DELETE FROM TABLE3;
On the server A everything works as expected, however using server B I'm getting the following error:
The DELETE statement conflicted with the REFERENCE constraint
"FK_....". The conflict occurred in database
"TestDB", table "Table1", column
'...'.
Both servers have the same version of SQL server
Microsoft SQL Server 2012 (SP1) - 11.0.3401.0 (X64)
Jan 9 2014 13:22:15
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: ) (Hypervisor)
Both Schema and data are the same and DB are created using the same process.
Any Ideas?
Actually, it is possible to have the same schema in both places, and even the same data, and experience different behavior. How? Because constraints (CHECK and FOREIGN KEY) can be disabled. Yup.
To see if the Foreign Key in question is enabled or disabled, just run the the following, making sure to put the name of the FK in question in the WHERE clause:
SELECT *
FROM sys.foreign_keys
WHERE [name] = N'{name_of_FK_in_question}';
Look at the column named is_disabled. I suspect that it is set to 1 on Server A (where everything "works") and is 0 on Server B (where things "don't work"). I put "works" and "don't work" in quotes, because if this is truly the case, then reality is the opposite of what you are experiencing. Meaning, the system with the FK enabled and getting the error is actually working as that is what FKs should do. The system not getting an error is possibly allowing orphaned (i.e. bad) data in.
To enable the FK, run the following:
ALTER TABLE {table_name}
WITH CHECK -- verifies the data currently in the table
CHECK CONSTRAINT [{name_of_FK_in_question}];
Of course, if the bad data is there, you either need to:
Delete the bad data first, or
Specify WITH NOCHECK on the ALTER so that it will accept the bad data:
ALTER TABLE {table_name}
WITH NOCHECK -- accept the bad data aleady there
CHECK CONSTRAINT [{name_of_FK_in_question}];
However, this does not solve the issue 100%. If you run that SELECT query (noted above) again, you should see that the is_disabled field is now set to 0. BUT, if you look at the is_not_trusted field, it will be set to 1. If a constraint is enabled yet not trusted, it will enforce its rule as expected, but the Query Optimizer (Q.O.) will ignore it, which is generally not a great thing as the constraints are actually used not just to enforce data integrity rules, but also as clues for the Q.O. to logically reduce certain steps in some queries (i.e. they sometimes help increase performance). In order to get the constraint to be "trusted", you will have to delete the bad data and verify all constraints on the table via:
ALTER TABLE {table_name}
WITH CHECK -- verifies the data currently in the table
CHECK CONSTRAINT [{name_of_FK_in_question}];
However, if for some reason you need the "bad" data, then you will just have a Foreign Key that enforces data integrity but has no potential for improving performance (which is still much better than having no FK defined :).
For more info, please see the MSDN page for ALTER TABLE.
For the sake of completeness I will also mention that it is possible that on Server A (where there is no error), that the FK is defined with the option ON DELETE CASCADE which auto-deletes and related data prior to removing the row(s) from the table that is being deleted from, while Server B (where there is an error) does not have the ON DELETE action specfied (or is specified as NO ACTION). This, however, is something that should show up when doing a schema compare (unless specifying to ignore the ON DELETE and ON UPDATE actions), whereas whether the constraint is enabled or disabled is more likely to be ignored in a schema compare.
There is a foreign key (named in the error message) which is preventing you from deleting an item from Table1 because it would violate the foreign key (i.e. a there would be a row in the other table which referenced the row that you were about to delete)
The difference between the two databases is going to either be:
The first database didn't have the foreign key
The first database didn't have any rows in the table constrained by the foreign key
To find which table the foreign key is on see the question How can I list all foreign keys referencing a given table in SQL Server?
EXEC sp_fkeys 'TableName'
Like Justin says, either the keys or data isn't the same, if it works for your case, then setting the keys to cascade of delete will remedy this, but you must identify the keys first.

SQL Server Check/NoCheck difference in generated scripts

I am trying to sync up the schemas between to different databases. Basically, I ran tasks->Generate Scripts with SQL Server Management Studio (2005) on both databases and am comparing the output with a diff tool.
For some reason, one script adds the constraint WITH CHECK and one WITH NO CHECK, followed by both constraints being re-enabled.
I for the first database I get:
ALTER TABLE [dbo].[Profile] WITH CHECK ADD CONSTRAINT [FK_Profile_OrganizationID] FOREIGN KEY([OrganizationID])
REFERENCES [dbo].[Organization] ([OrganizationID])
GO
ALTER TABLE [dbo].[Profile] CHECK CONSTRAINT [FK_Profile_OrganizationID]
GO
The second database generates as
ALTER TABLE [dbo].[Profile] WITH NOCHECK ADD CONSTRAINT [FK_Profile_OrganizationID] FOREIGN KEY([OrganizationID])
REFERENCES [dbo].[Organization] ([OrganizationID])
GO
ALTER TABLE [dbo].[Profile] CHECK CONSTRAINT [FK_Profile_OrganizationID]
GO
So I have two questions:
Is the end result the same?
(Edit:
It seems that a lot of people are picking up on only the first statement of the two scripts. I am interested in the end result of the entirety of both scripts.)
If the end result is the same, why does Management Studio generate them differently for different databases?
The end result is not the same!
SQL Server will not trust the uniqueness of the FK is it is not checked. This means additional processing is required if you use the column in a query.
Long story short is that you should get SQL Server to check the column so it's considered trusted.
As for why they're different from different servers, check the isnottrusted column in sys.foreign_keys. This may affect what SSMS is generating?
For more of a rant on this, check my other answer that relates to FK & NO CHECK/ CHECK options.
Yes the two scripts are different
WITH CHECK will check existing data against the new constraint.
WITH NOCHECK will not check existing data against the new constraint. This will allow you to have child records without a corresponding parent.
EDIT:
As for why SSMS is doing this I have no idea
Both are SQL Server 2005 servers? As the result is the same, the code generation tool maybe use different routines based in different versions of the product

Resources