Сохранение обновленных столбцов в SQL Server 2008 с помощью триггера - PullRequest
0 голосов
/ 06 сентября 2011

У меня есть большая таблица в базе данных, и я хочу отслеживать изменения, внесенные в отдельные записи. Точнее, я хочу записать дату и изменения, внесенные в столбцы.

Поскольку в таблице более 25 столбцов, я не хочу тестировать их по отдельности.

Таблица регистрации выглядит как ID-Date-Table-Column-OldValue-NewValue

В моем AFTER UPDATE триггере я хотел бы проверить, какие столбцы имеют разные значения и записать их в мою таблицу.

Я знаю, что могу получить столбцы таблицы с помощью:

DECLARE @meta_table TABLE (  
    idx smallint Primary Key IDENTITY(1,1) 
    , TABLE_NAME nchar(100), COLUMN_NAME nchar(100), COLUMN_ID int 
) 

INSERT @meta_table 
SELECT TABLE_NAME, COLUMN_NAME,
    COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME),
    COLUMN_NAME, 'ColumnID') AS COLUMN_ID
FROM MYDATABASE.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'myTable';

Я могу перебрать столбцы с помощью:

SET @i = 1 
SET @numrows = (SELECT COUNT(*) FROM @meta_table) 
IF @numrows > 0 
    WHILE (@i <= (SELECT MAX(idx) FROM @meta_table)) 
    BEGIN 
        SET @col = (SELECT COLUMN_NAME FROM @meta_table WHERE idx = @i)

        -- do something with @col

        SET @i = @i + 1 
    END

На первом шаге я хотел бы проверить все столбцы, но что-то вроде этого не работает

IF (SELECT @col FROM inserted) <> (SELECT @col FROM deleted)
BEGIN
    -- INSERT into logging table ...
END

Кроме того, это будет проверять только первую строку обновлений, поэтому мне нужно сделать это для каждой строки в удаленной / вставленной таблице.

Ответы [ 3 ]

2 голосов
/ 06 сентября 2011

Нет смысла перебирать столбцы таблицы. Поскольку триггер предназначен для конкретной таблицы, вы уже знаете, какие у нее столбцы! Просто запишите триггер с интересующими вас столбцами. Вы говорите, что это может быть повторяющейся, скучной и подверженной ошибкам задачей? Хорошие программисты в таких случаях автоматизируют задачу, например. прибегать к генерации кода для автоматической генерации триггеров, мгновенно проводить их рефакторинг и синхронизировать их с изменениями схемы. Развертывание runtime обнаружение схемы - не самый лучший способ.

1 голос
/ 06 сентября 2011

Сбор данных изменений может быть решением для регистрации изменений таблицы DML.

0 голосов
/ 06 сентября 2011

Хм - если вы хотите регистрировать ТОЛЬКО поля, которые изменились, то вам обязательно нужно проверить каждое поле отдельно.Однако, как вы узнали, сравнение не работает одинаково для разных типов данных.Таким образом, вам, вероятно, потребуется проверить типы данных каждого поля и выполнить соответствующее сравнение.Я полагаю, что в INFORMATION_SCHEMA есть поле с именем «DATA_TYPE», поэтому, когда вы выполняете вставку мета-таблицы, добавьте дополнительный столбец:


INSERT @meta_table  
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE,
    COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), 
    COLUMN_NAME, 'ColumnID') AS COLUMN_ID 
FROM MYDATABASE.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'myTable'; 


, а затем проверьте его в цикле:


SET @i = 1    
SET @numrows = (SELECT COUNT(*) FROM @meta_table)    
IF @numrows > 0    
    WHILE (@i <= (SELECT MAX(idx) FROM @meta_table))    
    BEGIN    
        SELECT @col = COLUMN_NAME, @dataType = DATA_TYPE
        FROM @meta_table WHERE idx = @i)   

        -- do something with @col   

        SET @i = @i + 1    
    END   

И затем вам нужно проверить тип данных перед сравнением ..


IF(@dataType = 'varchar')
BEGIN

-- do your comparison and insert here

END
ELSE IF(@dataType = 'int')
BEGIN

-- do you comparison and insert here

END
....



... и так далее, для всех типов данных, которые есть в таблице ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...