Udostępnij za pomocą


COLUMNS_UPDATED (Transact-SQL)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceBaza danych SQL w usłudze Microsoft Fabric

Ta funkcja zwraca wzorzec bitów varbinary wskazujący wstawione lub zaktualizowane kolumny tabeli lub widoku. Użyj COLUMNS_UPDATED dowolnego miejsca w treści Transact-SQL INSERT lub UPDATE wyzwalacza, aby sprawdzić, czy wyzwalacz powinien wykonywać określone akcje.

Transact-SQL konwencje składni

Składnia

COLUMNS_UPDATED ( )

Typy zwracane

varbinary (zmienna)

Uwagi

COLUMNS_UPDATED testy dla UPDATE lub INSERT akcji wykonywanych na wielu kolumnach. Aby przetestować jedną UPDATE kolumnę lub INSERT podjąć próby, użyj metody UPDATE().

COLUMNS_UPDATED Zwraca co najmniej jeden bajt uporządkowany od lewej do prawej. Najbardziej odpowiedni bit każdego bajtu jest najmniej znaczącym bitem. Najbardziej prawy fragment lewego bajtu reprezentuje pierwszą kolumnę tabeli w tabeli, następny bit po lewej stronie reprezentuje drugą kolumnę itd. COLUMNS_UPDATED Zwraca wiele bajtów, jeśli tabela, w której jest tworzony wyzwalacz, zawiera więcej niż osiem kolumn, przy czym najmniej znaczący bajt jest po lewej stronie. COLUMNS_UPDATED Zwraca TRUE wartość dla wszystkich kolumn w INSERT akcjach, ponieważ kolumny mają wstawione jawne wartości lub niejawne (NULL).

Aby przetestować aktualizacje lub wstawiać do określonych kolumn, postępuj zgodnie ze składnią z operatorem bitowym i maską bitową testowanych kolumn. Załóżmy na przykład, że tabela t1 zawiera kolumny C1, , C2C3, C4i C5. Aby sprawdzić, czy kolumny C2, C3i C4 wszystkie zostały pomyślnie zaktualizowane (z tabelą t1 z wyzwalaczem UPDATE ), postępuj zgodnie ze składnią za pomocą & 14polecenia . Aby sprawdzić, czy tylko kolumna C2 jest aktualizowana, określ wartość & 2. Zobacz Przykład A i Przykład B, aby zapoznać się z rzeczywistymi przykładami.

Użyj COLUMNS_UPDATED dowolnego miejsca wewnątrz Transact-SQL INSERT lub UPDATE wyzwalacza. Jeśli jest to uruchamiane poza wyzwalaczem, zwracana jest wartość NULL.

Kolumna ORDINAL_POSITIONINFORMATION_SCHEMA.COLUMNS widoku nie jest zgodna ze wzorcem bitowym kolumn zwracanych przez COLUMNS_UPDATEDelement . Aby uzyskać wzorzec bitowy zgodny z elementem COLUMNS_UPDATED, należy odwołać się do ColumnID właściwości COLUMNPROPERTY funkcji systemowej podczas wykonywania zapytań względem INFORMATION_SCHEMA.COLUMNS widoku, jak pokazano w poniższym przykładzie.

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';

Jeśli wyzwalacz ma zastosowanie do kolumny, COLUMNS_UPDATED zwraca wartość jako true lub 1, nawet jeśli wartość kolumny pozostaje niezmieniona. Jest to projektowe, a wyzwalacz powinien implementować logikę biznesową, która określa, czy operacja wstawiania/aktualizowania/usuwania jest dozwolona, czy nie.

Zestawy kolumn

Gdy zestaw kolumn jest zdefiniowany w tabeli, COLUMNS_UPDATED funkcja działa w następujący sposób:

  • Podczas jawnego aktualizowania kolumny składowej zestawu kolumn odpowiedni bit dla tej kolumny jest ustawiony na 11wartość , a bit zestawu kolumn ma wartość .

  • Podczas jawnego aktualizowania zestawu kolumn bit zestawu kolumn jest ustawiony na 1, a bity dla wszystkich rozrzedzona kolumn w tej tabeli są ustawione na 1wartość .

  • W przypadku operacji wstawiania wszystkie bity są ustawione na 1wartość .

    Ze względu na to, że zmiany w zestawie kolumn powodują, że bity wszystkich kolumn w kolumnie ustawionej na wartość 1resetują wartość , niezmienione kolumny w zestawie kolumn zostaną zmodyfikowane. Aby uzyskać więcej informacji na temat zestawów kolumn, zobacz Use Column Sets (Używanie zestawów kolumn ).

Przykłady

Odp. Używanie COLUMNS_UPDATED do testowania pierwszych ośmiu kolumn tabeli

W tym przykładzie są tworzone dwie tabele: employeeData i auditEmployeeData. Tabela employeeData zawiera poufne informacje o płacach pracowników, a członkowie działu kadr mogą je modyfikować. Jeśli numer ubezpieczenia społecznego (SSN), roczne wynagrodzenie lub numer konta bankowego dla pracownika zmieni się, rekord inspekcji zostanie wygenerowany i wstawiony do tabeli inspekcji auditEmployeeData .

COLUMNS_UPDATED() Dzięki funkcji możemy szybko przetestować wszelkie zmiany wprowadzone w kolumnach zawierających poufne informacje o pracownikach. Użycie COLUMNS_UPDATED() tej metody działa tylko podczas próby wykrycia zmian w pierwszych ośmiu kolumnach w tabeli.

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 AS 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 AS 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. Używanie COLUMNS_UPDATED do testowania więcej niż ośmiu kolumn

Aby przetestować aktualizacje wpływające na kolumny inne niż pierwsze osiem kolumn tabeli, użyj SUBSTRING funkcji , aby przetestować poprawny bit zwrócony przez COLUMNS_UPDATED. W tym przykładzie testuje się aktualizacje wpływające na kolumny 3, 5i 9 w AdventureWorks2022.Person.Person tabeli.

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