You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: The COLUMNS_UPDATED Transact-SQL function returns a bit pattern indicating the inserted or updated columns of a table or view.
4
4
author: markingmyname
5
5
ms.author: maghan
6
-
ms.date: "07/25/2017"
6
+
ms.reviewer: randolphwest
7
+
ms.date: 02/28/2025
7
8
ms.service: sql
8
9
ms.subservice: t-sql
9
10
ms.topic: reference
@@ -23,185 +24,203 @@ dev_langs:
23
24
24
25
[!INCLUDE [SQL Server Azure SQL Database Azure SQL Managed Instance](../../includes/applies-to-version/sql-asdb-asdbmi.md)]
25
26
26
-
This function returns a **varbinary** bit pattern indicating the inserted or updated columns of a table or view. Use `COLUMNS_UPDATED` anywhere inside the body of a [!INCLUDE[tsql](../../includes/tsql-md.md)] INSERT or UPDATE trigger to test whether the trigger should execute certain actions.
27
-
27
+
This function returns a **varbinary** bit pattern indicating the inserted or updated columns of a table or view. Use `COLUMNS_UPDATED` anywhere inside the body of a [!INCLUDE[tsql](../../includes/tsql-md.md)]`INSERT` or `UPDATE` trigger to test whether the trigger should execute certain actions.
`COLUMNS_UPDATED` tests for UPDATE or INSERT actions performed on multiple columns. To test for UPDATE or INSERT attempts on one column, use [UPDATE()](../../t-sql/functions/update-trigger-functions-transact-sql.md).
41
-
42
-
`COLUMNS_UPDATED` returns one or more bytes that are ordered from left to right. The rightmost bit of each byte is the least significant bit. The rightmost bit of the leftmost byte represents the first table column in the table, the next bit to the left represents the second column, and so on. `COLUMNS_UPDATED` returns multiple bytes if the table on which the trigger is created contains more than eight columns, with the least significant byte being the leftmost. `COLUMNS_UPDATED` returns TRUE for all columns in INSERT actions because the columns have either explicit values or implicit (NULL) values inserted.
43
-
44
-
To test for updates or inserts to specific columns, follow the syntax with a bitwise operator and an integer bitmask of the tested columns. For example, say that table **t1** contains columns **C1**, **C2**, **C3**, **C4**, and **C5**. To verify that columns **C2**, **C3**, and **C4** all successfully updated (with table **t1** having an UPDATE trigger), follow the syntax with **& 14**. To test whether only column **C2** is updated, specify **& 2**. See [Example A](#a-using-columns_updated-to-test-the-first-eight-columns-of-a-table) and [Example B](#b-using-columns_updated-to-test-more-than-eight-columns) for actual examples.
45
-
46
-
Use `COLUMNS_UPDATED` anywhere inside a [!INCLUDE[tsql](../../includes/tsql-md.md)] INSERT or UPDATE trigger.
47
-
48
-
The ORDINAL_POSITION column of the INFORMATION_SCHEMA.COLUMNS view is not compatible with the bit pattern of columns returned by `COLUMNS_UPDATED`. To obtain a bit pattern compatible with `COLUMNS_UPDATED`, reference the `ColumnID` property of the `COLUMNPROPERTY` system function when querying the `INFORMATION_SCHEMA.COLUMNS` view, as shown in the following example.
49
-
40
+
41
+
## Remarks
42
+
43
+
`COLUMNS_UPDATED` tests for `UPDATE` or `INSERT` actions performed on multiple columns. To test for `UPDATE` or `INSERT` attempts on one column, use [UPDATE()](../../t-sql/functions/update-trigger-functions-transact-sql.md).
44
+
45
+
`COLUMNS_UPDATED` returns one or more bytes that are ordered from left to right. The rightmost bit of each byte is the least significant bit. The rightmost bit of the leftmost byte represents the first table column in the table, the next bit to the left represents the second column, and so on. `COLUMNS_UPDATED` returns multiple bytes if the table on which the trigger is created contains more than eight columns, with the least significant byte being the leftmost. `COLUMNS_UPDATED` returns `TRUE` for all columns in `INSERT` actions because the columns have either explicit values or implicit (NULL) values inserted.
46
+
47
+
To test for updates or inserts to specific columns, follow the syntax with a bitwise operator and an integer bitmask of the tested columns. For example, say that table `t1` contains columns `C1`, `C2`, `C3`, `C4`, and `C5`. To verify that columns `C2`, `C3`, and `C4` all successfully updated (with table `t1` having an `UPDATE` trigger), follow the syntax with `& 14`. To test whether only column `C2` is updated, specify `& 2`. See [Example A](#a-use-columns_updated-to-test-the-first-eight-columns-of-a-table) and [Example B](#b-use-columns_updated-to-test-more-than-eight-columns) for actual examples.
48
+
49
+
Use `COLUMNS_UPDATED` anywhere inside a [!INCLUDE [tsql](../../includes/tsql-md.md)]`INSERT` or `UPDATE` trigger.
50
+
51
+
The `ORDINAL_POSITION` column of the `INFORMATION_SCHEMA.COLUMNS` view isn't compatible with the bit pattern of columns returned by `COLUMNS_UPDATED`. To obtain a bit pattern compatible with `COLUMNS_UPDATED`, reference the `ColumnID` property of the `COLUMNPROPERTY` system function when querying the `INFORMATION_SCHEMA.COLUMNS` view, as shown in the following example.
If a trigger applies to a column, the `COLUMNS_UPDATED` returns as `true` or `1`, even if the column value remains unchanged. This is by-design, and the trigger should implement business logic that determines if the insert/update/delete operation is permissible or not.
If a trigger applies to a column, the `COLUMNS_UPDATED` returns as `true` or `1`, even if the column value remains unchanged. This is by-design, and the trigger should implement business logic that determines if the insert/update/delete operation is permissible or not.
62
+
60
63
## Column sets
64
+
61
65
When a column set is defined on a table, the `COLUMNS_UPDATED` function behaves in the following ways:
62
-
- When explicitly updating a member column of the column set, the corresponding bit for that column is set to 1, and the column set bit is set to 1.
63
-
- When a explicitly updating a column set, the column set bit is set to 1, and the bits for all of the sparse columns in that table are set to 1.
64
-
- For insert operations, all bits are set to 1.
65
-
66
-
Because changes to a column set cause the bits of all columns in the column set to reset to 1, unchanged columns in a column set will appear modified. See [Use Column Sets](../../relational-databases/tables/use-column-sets.md) for more information about column sets.
67
-
68
-
## Examples
69
-
70
-
### A. Using COLUMNS_UPDATED to test the first eight columns of a table
66
+
67
+
- When explicitly updating a member column of the column set, the corresponding bit for that column is set to `1`, and the column set bit is set to `1`.
68
+
69
+
- When explicitly updating a column set, the column set bit is set to `1`, and the bits for all of the sparse columns in that table are set to `1`.
70
+
71
+
- For insert operations, all bits are set to `1`.
72
+
73
+
Because changes to a column set cause the bits of all columns in the column set to reset to `1`, unchanged columns in a column set will appear modified. See [Use Column Sets](../../relational-databases/tables/use-column-sets.md) for more information about column sets.
74
+
75
+
## Examples
76
+
77
+
### A. Use COLUMNS_UPDATED to test the first eight columns of a table
78
+
71
79
This example creates two tables: `employeeData` and `auditEmployeeData`. The `employeeData` table holds sensitive employee payroll information and human resources department members can modify it. If the social security number (SSN), yearly salary, or bank account number for an employee changes, an audit record is generated and inserted into the `auditEmployeeData` audit table.
72
-
80
+
73
81
With the `COLUMNS_UPDATED()` function, we can quickly test for any changes made to columns containing sensitive employee information. Using `COLUMNS_UPDATED()` this way works only when trying to detect changes to the first eight columns in the table.
74
-
82
+
75
83
```sql
76
-
USE AdventureWorks2022;
77
-
GO
78
-
IF EXISTS(SELECT TABLE_NAME FROMINFORMATION_SCHEMA.TABLES
79
-
WHERE TABLE_NAME ='employeeData')
80
-
DROPTABLE employeeData;
81
-
IF EXISTS(SELECT TABLE_NAME FROMINFORMATION_SCHEMA.TABLES
/* Updating the employee record for employee number 101 to change the
156
172
salary to 51000 causes the UPDATE trigger to fire and an audit trail to
157
-
be produced. */
158
-
159
-
UPDATEdbo.employeeData
160
-
SET emp_salary =51000
161
-
WHERE emp_id =101;
162
-
GO
163
-
SELECT*FROM auditEmployeeData;
164
-
GO
165
-
166
-
/* Updating the employee record for employee number 101 to change both
167
-
the bank account number and social security number (SSN) causes the
168
-
UPDATE trigger to fire and an audit trail to be produced. */
169
-
170
-
UPDATEdbo.employeeData
171
-
SET emp_bankAccountNumber ='133146A0', emp_SSN ='R-M53550M'
172
-
WHERE emp_id =101;
173
-
GO
174
-
SELECT*FROMdbo.auditEmployeeData;
175
-
176
-
GO
177
-
```
178
-
179
-
### B. Using COLUMNS_UPDATED to test more than eight columns
173
+
be produced. */
174
+
UPDATEdbo.employeeData
175
+
SET emp_salary =51000
176
+
WHERE emp_id =101;
177
+
GO
178
+
179
+
SELECT*FROM auditEmployeeData;
180
+
GO
181
+
182
+
/* Updating the employee record for employee number 101 to change both
183
+
the bank account number and social security number (SSN) causes the
184
+
UPDATE trigger to fire and an audit trail to be produced. */
185
+
UPDATEdbo.employeeData
186
+
SET emp_bankAccountNumber ='133146A0',
187
+
emp_SSN ='R-M53550M'
188
+
WHERE emp_id =101;
189
+
GO
190
+
191
+
SELECT*FROMdbo.auditEmployeeData;
192
+
GO
193
+
```
194
+
195
+
### B. Use COLUMNS_UPDATED to test more than eight columns
196
+
180
197
To test for updates that affect columns other than the first eight table columns, use the `SUBSTRING` function to test the correct bit returned by `COLUMNS_UPDATED`. This example tests for updates affecting columns `3`, `5`, and `9` in the `AdventureWorks2022.Person.Person` table.
181
-
198
+
182
199
```sql
183
-
USE AdventureWorks2022;
184
-
GO
185
-
IF OBJECT_ID (N'Person.uContact2', N'TR') IS NOT NULL
0 commit comments