In SQL Server, foreign keys are essential for maintaining referential integrity between tables. When creating foreign keys, we have a number options available to us when it comes to defining what should happen in the event that the related data in the parent table changes. One such option is ON UPDATE SET DEFAULT
.
This article will explain what this option does, provide an example of its usage, and offer a practical scenario where this feature can be useful.
What is ON UPDATE SET DEFAULT
?
The ON UPDATE SET DEFAULT
option is used when defining a foreign key constraint in SQL Server. This option ensures that if the value in the referenced column of the parent table is updated, the foreign key column in the child table is automatically set to its default value.
To use this option, the foreign key column in the child table must have a default value defined. If no default value is set, SQL Server will not allow the ON UPDATE SET DEFAULT
constraint. That said, if the column is nullable, and no default value is defined, then the default value will be NULL
(unless it’s a timestamp
column, in which case the next timestamp value is inserted).
Syntax
To implement this option, we simply append ON UPDATE SET DEFAULT
to the foreign key definition.
For example, here’s the basic syntax for adding a foreign key with ON UPDATE SET DEFAULT
:
ALTER TABLE [ChildTable]
ADD CONSTRAINT [ConstraintName]
FOREIGN KEY ([ForeignKeyColumn])
REFERENCES [ParentTable] ([PrimaryKeyColumn])
ON UPDATE SET DEFAULT;
We can see that the last line is ON UPDATE SET DEFAULT
, which means that the foreign key uses this option for any updates to the parent table.
Example Scenario
Consider an e-commerce system with two tables:
- ShippingMethods: Stores information about the available shipping methods.
- Orders: Stores details about customer orders, including the shipping method used.
In this scenario, if a shipping method is updated or changed, we might want all orders that used the old method to be set to a default shipping method, like “Standard Shipping” (which could be ShippingMethodID = 1
).
Let’s walk through a step-by-step example:
Step 1: Create the Tables
First, create the ShippingMethods
and Orders
tables:
CREATE TABLE ShippingMethods (
ShippingMethodID INT PRIMARY KEY,
MethodName NVARCHAR(100)
);
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
OrderDate DATE,
ShippingMethodID INT DEFAULT 1,
FOREIGN KEY (ShippingMethodID)
REFERENCES ShippingMethods(ShippingMethodID)
ON UPDATE SET DEFAULT
);
In this example:
ShippingMethods
containsShippingMethodID
andMethodName
.Orders
containsOrderID
,OrderDate
, andShippingMethodID
, which referencesShippingMethodID
inShippingMethods
. The foreign key is set toON UPDATE SET DEFAULT
, and the column has a default value of1
.
Step 2: Insert Sample Data
Insert initial data into both tables and select it:
-- Populate ShippingMethods table
INSERT INTO ShippingMethods (ShippingMethodID, MethodName)
VALUES (1, 'Standard Shipping'), (2, 'Express Shipping'), (3, 'Overnight Shipping');
-- Populate Orders table
INSERT INTO Orders (OrderID, OrderDate, ShippingMethodID)
VALUES (101, '2024-08-21', 2),
(102, '2024-08-22', 3),
(103, '2024-08-23', 2);
-- Select all data
SELECT * FROM ShippingMethods;
SELECT * FROM Orders;
Here:
- Three orders are created using
Express Shipping
andOvernight Shipping
. - Three shipping methods are created:
Standard Shipping
(ID = 1),Express Shipping
(ID = 2), andOvernight Shipping
(ID = 3).
Here’s the output of the SELECT
queries:
ShippingMethodID MethodName
---------------- ------------------
1 Standard Shipping
2 Express Shipping
3 Overnight Shipping
OrderID OrderDate ShippingMethodID
------- ------------------------ ----------------
101 2024-08-21T00:00:00.000Z 2
102 2024-08-22T00:00:00.000Z 3
103 2024-08-23T00:00:00.000Z 2
Step 3: Update the Parent Table
Suppose the company decides to retire Express Shipping
and repurpose it under a different ID. If we update the ShippingMethodID
from 2
to 4
, we want any orders using the old ID (2
) to automatically switch to the default Standard Shipping
ID (1
).
Let’s update the parent table:
UPDATE ShippingMethods
SET ShippingMethodID = 4
WHERE ShippingMethodID = 2;
Since we have an ON UPDATE SET DEFAULT
constraint, any orders associated with the old ShippingMethodID
(2
) will have their ShippingMethodID
set to 1
(the default value defined on the foreign key in the Orders
table).
Step 4: Verify the Results
Finally, let’s check the data in the tables to see the effect of the update:
SELECT * FROM ShippingMethods;
SELECT * FROM Orders;
Output:
ShippingMethodID MethodName
---------------- ------------------
1 Standard Shipping
3 Overnight Shipping
4 Express Shipping
OrderID OrderDate ShippingMethodID
------- ------------------------ ----------------
101 2024-08-21T00:00:00.000Z 1
102 2024-08-22T00:00:00.000Z 3
103 2024-08-23T00:00:00.000Z 1
Here’s what happened:
- Orders
101
and103
, which initially usedExpress Shipping
(ShippingMethodID
=2
), have been automatically reassigned to the defaultStandard Shipping
(ShippingMethodID
=1
). - Order
102
, which usedOvernight Shipping
(ShippingMethodID
=3
), remains unchanged.
Other Use Cases for ON UPDATE SET DEFAULT
The ON UPDATE SET DEFAULT
option is ideal when you want to avoid leaving foreign key fields without a valid reference while ensuring that they point to a meaningful default value. A couple of other use cases could include:
- Customer Service Applications: If a customer’s account is deactivated or merged, setting the related foreign keys to a default “Guest” or “Archived” ID ensures continuity in records.
- Inventory Systems: If a product ID changes due to an update, related transactions can be set to a default “Unassigned” ID to maintain data integrity without losing transaction history.
NULL Default Values
There are some cases where ON UPDATE SET DEFAULT
will result in the column being set to NULL
. For example:
- If the column has been defined with a
DEFAULT
value ofNULL
, then it will end up havingNULL
afterON UPDATE SET DEFAULT
does it’s thing. - If we don’t specify a default value for the column, and it’s nullable, then SQL Server will make its default value
NULL
. Therefore, this will result in the column being updated toNULL
in any applicable updates.
If you want to explicitly set the column to NULL
, it might be better to use ON UPDATE SET NULL
.