Skip to content

The Dummy Programmer

Stories of daily programming

  • Home
  • My other dummy projects
  • Games
    • Space Y: An Asteroids clone
  • Services
    • What’s my user agent
    • What’s my IP address
  • About
  • Toggle search form

Sql Server add constraint WITH NOCHECK

Posted on March 21, 2020May 3, 2020 By

Good morning guys!

Today I want to talk about a Sql Server feature that you could use when creating foreign key constraints: the WITH NOCHECK option.

If you look at the name it seems that with that option, the constraint is not enforced… but it is not true.

You can check this by running this script:

CREATE TABLE [dbo].[Child](
[ID] [int] NOT NULL PRIMARY KEY CLUSTERED,
[ParentID] [int] NOT NULL,
[ChildName] [varchar](10) NOT NULL,
)
GO

CREATE TABLE [dbo].[Parent](
[ID] [int] NOT NULL PRIMARY KEY CLUSTERED,
[ParentName] [varchar](10) NOT NULL 
) 
GO

ALTER TABLE [dbo].[Child] WITH NOCHECK ADD CONSTRAINT [FK_Child_Parent] FOREIGN KEY([ParentID])
REFERENCES [dbo].[Parent] ([ID])
GO

INSERT INTO [dbo].[Parent]([ID], [ParentName]) VALUES(1, 'Parent1')
INSERT INTO [dbo].[Child]([ID], [ParentID], [ChildName]) VALUES(1, 1, 'Child1')
INSERT INTO [dbo].[Child]([ID], [ParentID], [ChildName]) VALUES(2, 2, 'Child1')
GO

The second insert statement in the table Child will raise an error because the parent with ID 2 doesn’t exist.

Msg 547, Level 16, State 0, Line 26
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Child_Parent". The conflict occurred in database "TestDatabase", table "dbo.Parent", column 'ID'.
The statement has been terminated.

To see the difference, first of all try to execute this slightly modified version of the script above, in which we will create the table and fill it with data:

-- First of all, drop the tables!!
DROP TABLE [dbo].[Child]
GO

DROP TABLE [dbo].[Parent]
GO

CREATE TABLE [dbo].[Child](
[ID] [int] NOT NULL PRIMARY KEY CLUSTERED,
[ParentID] [int] NOT NULL,
[ChildName] [varchar](10) NOT NULL,
)
GO

CREATE TABLE [dbo].[Parent](
[ID] [int] NOT NULL PRIMARY KEY CLUSTERED,
[ParentName] [varchar](10) NOT NULL
)
GO

INSERT INTO [dbo].[Parent]([ID], [ParentName]) VALUES(1, 'Parent1')
INSERT INTO [dbo].[Child]([ID], [ParentID], [ChildName]) VALUES(1, 1, 'Child1')
INSERT INTO [dbo].[Child]([ID], [ParentID], [ChildName]) VALUES(2, 2, 'Child1')
GO

Now we have a child record with no valid “ParentID” value, and if you try to create the constraint using the WITH NOCHECK option, the constraint will be created without errors!

ALTER TABLE [dbo].[Child] WITH NOCHECK ADD CONSTRAINT [FK_Child_Parent] FOREIGN KEY([ParentID])
REFERENCES [dbo].[Parent] ([ID])
GO

As demonstrated in the beginning of the post, in this situation you still can’t insert invalid “ParentID” values.

So the difference between “WITH NOCHECK” and “WITH CHECK” is that in the first case, no check is made on existing data while creating the constraint, so is possible that dirty data can exist in the table even after the creation of the constraint.

Apart from the presence of dirty data, which in itself is already a serious matter, be careful that a foreign key constraint created using the “WITH NOCHECK” is marked as “not trusted”, which means that Sql Server cannot use it in executions plan because of the possible presence of inconsistent data.

The following query extract the list of all the foreign keys of the database with a column indicating if the foreign key is trusted or not:

SELECT OBJECT_NAME(constid), OBJECTPROPERTY(constid, 'CnstIsNotTrusted') AS NotTrusted
FROM sys.sysforeignkeys

Bye bye friends!

Sql Server, Sql Server 2016

Post navigation

Previous Post: Get SQL Server version in T-SQL
Next Post: A chat program built in C# with .NET socket library

Related Posts

Search a string in stored procedures, functions and views in a SQL Server database Sql Server
Getting SQL Server sample databases Sql Server
Merge two or more historical tables with Sql Server T-SQL – Part 2 Sql Server
Sql Server error: A severe error occurred on the current command.  The results, if any, should be discarded. Sql Server
Sql Server Instant File Initialization Sql Server
Sql Server: apply an aggregate function to fields values in a row Sql Server

Search

Related posts

  • Add a new website to an Apache installation
  • Merge two or more historical tables with Sql Server…
  • Merge two or more historical tables with Sql Server…
  • Get SQL Server version in T-SQL

Categories

  • .NET 6 (1)
  • .NET 7 (1)
  • AJAX (1)
  • Android (2)
  • Apache (4)
  • ASP.NET (9)
  • ASP.NET MVC (3)
  • Avalonia UI (1)
  • BCP (1)
  • Bitlocker (2)
  • C# (14)
  • CentOS (4)
  • ClosedXML (1)
  • CLR (1)
  • DNS (1)
  • Encryption (3)
  • Excel (2)
  • FuelPHP (3)
  • Games (2)
  • Google Chrome (1)
  • GSuite (1)
  • HTML (1)
  • Imagick (2)
  • Javascript (1)
  • Kindle (1)
  • LAMP (3)
  • Linux (7)
  • MariaDB (2)
  • Mathematics (2)
  • MySql (4)
  • NPOI (1)
  • Office 365 (1)
  • Perl (1)
  • PHP (6)
  • Programming (1)
  • Remote desktop (1)
  • SFTP (2)
  • Sockets (3)
  • Sql Server (20)
  • Sql Server 2016 (14)
  • Sql Server 2019 (1)
  • SSL (4)
  • Task scheduler (1)
  • Telerik ASP.NET AJAX (2)
  • The Dummy Programmer Chat (2)
  • Threading (5)
  • Tools (1)
  • TPL (3)
  • TypeScript (3)
  • Ubuntu (4)
  • Virtualization software (3)
  • Visual Studio (1)
  • Visual Studio Code (2)
  • VueJS (1)
  • Web fonts (1)
  • Web programming (6)
  • Windows (12)
  • Windows 10 (15)
  • Windows Forms (1)
  • Windows Server (6)

Copyright © 2024 The Dummy Programmer | Privacy Policy | Terms of use |

Powered by PressBook Masonry Dark

Manage Cookie Consent
This site doesn’t collect user personal data and doesn’t install profiling or analytical cookies, either its own or from third parties. Read our privacy policy for more info.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
Manage options Manage services Manage {vendor_count} vendors Read more about these purposes
View preferences
{title} {title} {title}