COLUMNS_UPDATED (Transact-SQL)
Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance
Esta función devuelve un patrón de bits varbinary que indica las columnas de una tabla o vista que se insertaron o se actualizaron. Use COLUMNS_UPDATED
en cualquier lugar del cuerpo de un desencadenador INSERT o UPDATE de Transact-SQL para probar si el desencadenador debe ejecutar ciertas acciones.
Convenciones de sintaxis de Transact-SQL
Sintaxis
COLUMNS_UPDATED ( )
Tipos de valores devueltos
varbinary
Observaciones
COLUMNS_UPDATED
comprueba las acciones UPDATE o INSERT realizadas en varias columnas. Para comprobar los intentos UPDATE o INSERT realizados en una columna, use UPDATE().
COLUMNS_UPDATED
devuelve uno o más bytes que se ordenan de izquierda a derecha. El bit situado más a la derecha de cada byte es el menos significativo. El primer bit por la derecha del byte situado más a la izquierda representa la primera columna de la tabla, el siguiente bit a la izquierda representa la segunda columna, y así sucesivamente. COLUMNS_UPDATED
devuelve varios bytes si la tabla en que se ha creado el desencadenador contiene más de ocho columnas, siendo el menos significativo el primero por la izquierda. COLUMNS_UPDATED
devuelve TRUE en todas las columnas de las acciones INSERT porque en las columnas se insertaron valores explícitos o implícitos (NULL).
Para probar las actualizaciones o inserciones en columnas específicas, siga la sintaxis con un operador bit a bit y una máscara de bits de enteros de las columnas probadas. Por ejemplo, supongamos que la tabla t1 contiene las columnas C1, C2, C3, C4 y C5. Para comprobar que las columnas C2, C3 y C4 se han actualizado correctamente (donde la tabla t1 tiene un desencadenador UPDATE), siga la sintaxis con & 14. Para comprobar si solo se ha actualizado la columna C2, especifique & 2. Vea Ejemplo A y Ejemplo B para obtener ejemplos reales.
Use COLUMNS_UPDATED
en cualquier parte dentro de un desencadenador INSERT o UPDATE de Transact-SQL.
La columna ORDINAL_POSITION de la vista INFORMATION_SCHEMA.COLUMNS no es compatible con el patrón de bits de las columnas devueltas por COLUMNS_UPDATED
. Para obtener un patrón de bits compatible con COLUMNS_UPDATED
, haga referencia a la propiedad ColumnID
de la función del sistema COLUMNPROPERTY
cuando realice una consulta de la vista INFORMATION_SCHEMA.COLUMNS
, como se muestra en el ejemplo siguiente.
SELECT TABLE_NAME, COLUMN_NAME,
COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME),
COLUMN_NAME, 'ColumnID') AS COLUMN_ID
FROM AdventureWorks2022.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Person';
Si un desencadenador se aplica a una columna, COLUMNS_UPDATED
se devolverá como true
o 1
, incluso si el valor de columna permanece sin cambios. Esto es así por diseño y el desencadenador debe implementar la lógica de negocios que determina si la operación de inserción, actualización o eliminación está permitida o no.
Conjuntos de columnas
Cuando un conjunto de columnas se define en una tabla, la función COLUMNS_UPDATED
se comporta de las maneras siguientes:
Cuando se actualiza de forma explícita una columna que es miembro del conjunto de columnas, el bit correspondiente para esa columna se establece en 1, y el bit del conjunto de columnas se establece en 1.
Cuando se actualiza de forma explícita un conjunto de columnas, el bit del conjunto de columnas se establece en 1, y los bits para todas las columnas dispersas de la tabla se establecen en 1.
En las operaciones de inserción, todos los bits se establecen en 1.
Dado que los cambios en un conjunto de columnas hacen que los bits de todas las columnas del conjunto de columnas se establezcan en 1, parecerá que se han modificado las columnas sin cambiar de un conjunto de columnas. Vea Usar conjuntos de columnas para obtener más información sobre los conjuntos de columnas.
Ejemplos
A. Usar COLUMNS_UPDATED para comprobar las primeras ocho columnas de una tabla.
En este ejemplo se crean dos tablas: employeeData
y auditEmployeeData
. La tabla employeeData
contiene información confidencial de los sueldos de los empleados y la pueden modificar los miembros del departamento de recursos humanos. Si se cambia el número de seguridad social, el sueldo anual o el número de cuenta bancaria de un empleado, se genera un registro de auditoría y se inserta en la tabla de auditoría auditEmployeeData
.
Con la función COLUMNS_UPDATED()
, se pueden probar rápidamente los cambios realizados en las columnas que contienen información confidencial de los empleados. El uso de COLUMNS_UPDATED()
de esta manera solo funciona al intentar detectar cambios en las primeras ocho columnas de la tabla.
USE AdventureWorks2022;
GO
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'employeeData')
DROP TABLE employeeData;
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'auditEmployeeData')
DROP TABLE auditEmployeeData;
GO
CREATE TABLE dbo.employeeData (
emp_id INT NOT NULL PRIMARY KEY,
emp_bankAccountNumber CHAR (10) NOT NULL,
emp_salary INT NOT NULL,
emp_SSN CHAR (11) NOT NULL,
emp_lname NCHAR (32) NOT NULL,
emp_fname NCHAR (32) NOT NULL,
emp_manager INT NOT NULL
);
GO
CREATE TABLE dbo.auditEmployeeData (
audit_log_id uniqueidentifier DEFAULT NEWID() PRIMARY KEY,
audit_log_type CHAR (3) NOT NULL,
audit_emp_id INT NOT NULL,
audit_emp_bankAccountNumber CHAR (10) NULL,
audit_emp_salary INT NULL,
audit_emp_SSN CHAR (11) NULL,
audit_user sysname DEFAULT SUSER_SNAME(),
audit_changed DATETIME DEFAULT GETDATE()
);
GO
CREATE TRIGGER dbo.updEmployeeData
ON dbo.employeeData
AFTER UPDATE AS
/* Check whether columns 2, 3 or 4 have been updated. If any or all
columns 2, 3 or 4 have been changed, create an audit record.
The bitmask is: power(2, (2-1)) + power(2, (3-1)) + power(2, (4-1)) = 14.
This bitmask translates into base_10 as: 2 + 4 + 8 = 14.
To test whether all columns 2, 3, and 4 are updated, use = 14 instead of > 0
(below). */
IF (COLUMNS_UPDATED() & 14) > 0
/* Use IF (COLUMNS_UPDATED() & 14) = 14 to see whether all columns 2, 3,
and 4 are updated. */
BEGIN
-- Audit OLD record.
INSERT INTO dbo.auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'OLD',
del.emp_id,
del.emp_bankAccountNumber,
del.emp_salary,
del.emp_SSN
FROM deleted del;
-- Audit NEW record.
INSERT INTO dbo.auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'NEW',
ins.emp_id,
ins.emp_bankAccountNumber,
ins.emp_salary,
ins.emp_SSN
FROM inserted ins;
END;
GO
/* Inserting a new employee does not cause the UPDATE trigger to fire. */
INSERT INTO employeeData
VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32);
GO
/* Updating the employee record for employee number 101 to change the
salary to 51000 causes the UPDATE trigger to fire and an audit trail to
be produced. */
UPDATE dbo.employeeData
SET emp_salary = 51000
WHERE emp_id = 101;
GO
SELECT * FROM auditEmployeeData;
GO
/* Updating the employee record for employee number 101 to change both
the bank account number and social security number (SSN) causes the
UPDATE trigger to fire and an audit trail to be produced. */
UPDATE dbo.employeeData
SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
WHERE emp_id = 101;
GO
SELECT * FROM dbo.auditEmployeeData;
GO
B. Utilizar COLUMNS_UPDATED para comprobar más de ocho columnas
Para comprobar las actualizaciones que afectan a otras columnas que no sean las ocho primeras de la tabla, use la función SUBSTRING
para comprobar si COLUMNS_UPDATED
devuelve el bit correcto. En este ejemplo se comprueban las actualizaciones que afectan a las columnas 3
, 5
y 9
de la tabla AdventureWorks2022.Person.Person
.
USE AdventureWorks2022;
GO
IF OBJECT_ID (N'Person.uContact2', N'TR') IS NOT NULL
DROP TRIGGER Person.uContact2;
GO
CREATE TRIGGER Person.uContact2 ON Person.Person
AFTER UPDATE AS
IF ( (SUBSTRING(COLUMNS_UPDATED(), 1, 1) & 20 = 20)
AND (SUBSTRING(COLUMNS_UPDATED(), 2, 1) & 1 = 1) )
PRINT 'Columns 3, 5 and 9 updated';
GO
UPDATE Person.Person
SET NameStyle = NameStyle,
FirstName=FirstName,
EmailPromotion=EmailPromotion;
GO
Consulte también
Operadores bit a bit (Transact-SQL)
CREATE TRIGGER (Transact-SQL)
UPDATE() (Transact-SQL)