How to Execute a Trigger Only When a Specific Column is Updated (SQL Server)

In SQL Server, you can create DML triggers that execute code only when a specific column is updated.

The trigger still fires, but you can test whether or not a specific column was updated, and then run code only if that column was updated.

You can do this by using the UPDATE() function inside your trigger. This function accepts the column name as its argument. It returns a boolean.

Example

Here’s the table:

CREATE TABLE t1 (
    id int IDENTITY(1,1) NOT NULL,
    c1 int DEFAULT 0,
    c2 int DEFAULT 0,
    c3 int DEFAULT 0
);

And here’s the trigger:

CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE (c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;

In this example, I create a table called t1 and a trigger called trg_t1.

I use an IF statement along with the UPDATE() function to test whether or not the c1 column was updated.

When the trigger runs, it will only execute the subsequent code if that condition is true.

Fire the Trigger

Let’s insert a row, but we’ll only insert a value into the c1 column.

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Result:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 0    | 1    |
+------+------+------+------+

As expected, the trigger fired, and the column c3 was also updated.

This happened because I included the INSERT argument in my trigger’s definition (i.e. I specified AFTER INSERT, UPDATE which means that the trigger is fired whenever data is inserted or updated). If I had only specified AFTER UPDATE, it would not have fired when I inserted data – it would only fire whenever I update existing data.

Remember that the table was defined with DEFAULT 0, so the c2 column defaulted to zero.

Now let’s update the c1 column.

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Result:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 0    | 2    |
+------+------+------+------+

Again, the c3 column was updated along with c1.

Now let’s do an update to the c2 column (this column isn’t included in the trigger).

UPDATE t1 
SET c2 = c2 + 1
WHERE id = 1;

SELECT * FROM t1;

Result:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 1    | 2    |
+------+------+------+------+

So this time, c2 was updated but c3 wasn’t. That’s because the c1 column wasn’t updated, and our trigger only updates c3 when c1 is updated.

The same thing would’ve happened if we’d inserted a row without specifying c1 in the INSERT statement.

What if I Update the Column with the Same Value?

If you update a column with the same value, the UPDATE() function will return true.

Here’s an example.

We know from our previous examples that the c1 column contains a value of 2.

Let’s explicitly update that column with the same value: 1

UPDATE t1 
SET c1 = 2
WHERE id = 1;

SELECT * FROM t1;

Result:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 1    | 3    |
+------+------+------+------+

So now c3 has incremented, even though the value for c1 is still the same.

Let’s do it again, but this time set it to itself (i.e. change c1 = 1 to c1 = c1).

UPDATE t1 
SET c1 = c1
WHERE id = 1;

SELECT * FROM t1;

Result:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 2    | 1    | 4    |
+------+------+------+------+

Again, c3 has incremented.

Unsuccessful Update Attempts

It’s important to note that the UPDATE() function merely indicates whether an INSERT or UPDATE attempt was made on a specified column of a table or view. It will still return true if the attempt was unsuccessful.