Создать аудит данных в SQL Server - PullRequest
0 голосов
/ 22 августа 2011

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

Допустим, у меня есть следующая таблица:

[TableA]
------
ID
ColumnA
ColumnB
ColumnC

Для аудита я создал таблицу, такую ​​как:

[TableA.Audit]
------
ID
TableAID
UserID
Date (default value = getdate())
ColumnA
ColumnB
ColumnC

Я тогда написал скрипт вроде:

DECLARE @currentColumnA int
       ,@currentColumnB int
       ,@currentColumnC int

SELECT TOP 1 @currentColumnA=ColumnA
            ,@currentColumnB=ColumnB
            ,@currentColumnC=ColumnC
FROM [TableA]
WHERE ID=@TableAID

UPDATE [TableA]
SET ColumnA=@ColumnA
    ,ColumnB=@ColumnB
    ,ColumnC=@ColumnC
WHERE ID=@TableAID

INSERT INTO [TableA.Audit] (TableAID, UserID, ColumnA, ColumnB, ColumnC)
VALUES (@TableAID, @UserID, NULLIF(@ColumnA, @currentColumnA), NULLIF(@ColumnB, @currentColumnB), NULLIF(@ColumnC, @currentColumnC))

Проблема в том, что если я добавлю поле ColumnD к TableA, мне придется отредактировать мою таблицу TableA.Audit так же, как и приведенный выше скрипт.

Поэтому есть ли лучший способ сделать это?

Ответы [ 3 ]

3 голосов
/ 22 августа 2011

Вам лучше написать триггеры для таблицы AFTER INSERT, AFTER DELETE и AFTER UPDATE. Таким образом, в любое время будет регистрироваться НИЧЕГО (приложение, Management Studio и т. Д.), Которое вставляет, обновляет или удаляет данные в таблице. Вам нужно будет добавить поле для действия аудита и в свой триггер вставить литерал для действия (например, «I» или «INSERT»). Я структурирую свои таблицы аудита следующим образом:

audit_id: INT IDENTITY 
audit_date: DATETIME GETDATE() 
audit_action: VARCHAR(16) ... or you can use CHAR(1) 
audit_user: VARCHAR(128) SUSER_SNAME()
(the fields from the table being audited)

Поскольку наши приложения используют Active Directory, я могу по умолчанию Audit_user SUSER_SNAME ().

1 голос
/ 23 августа 2011

Мы используем триггеры (единственный способ пойти и убедиться, что вы пишете их для обработки вставки / обновления / удаления нескольких записей), и наша структура немного отличается.Сначала у нас есть таблица, в которой хранится информация о действии, человек / заявка, которая сделала это, дата, а затем номер затронутых записей.Тогда у нас есть таблица, в которой хранятся детали.Эта таблица имеет столбец идентификатора, имя столбца, старое значение, новое значение.(мы используем nvarchar (max) для столбцов в таблице аудита) Таким образом, если таблица получает новые столбцы, нам не нужно беспокоиться об изменении таблиц аудита.У нас есть один набор таблиц аудита для каждой таблицы, которую мы проверяем.

В более новых версиях сервера Sql отслеживание изменений, но мы не находим достаточно подробностей для необходимого нами аудита и слишком быстро удаляют данные, если вы не переместите их в другую постоянную таблицу.

0 голосов
/ 22 августа 2011

Проблема в том, что, если бы мне нужно было добавить поле ColumnD в TableA, мне нужно было бы отредактировать мою таблицу TableA.Audit, а также скрипт выше.

ПоэтомуЕсть ли лучший способ сделать это?

Не совсем.Вы можете улучшить реализацию с помощью триггеров, как упоминает HardCode, но вам все равно придется изменить аудит и связанные с ним скрипты.

Я был свидетелем попыток сделать это "лучше", когда вам не нужно обновлять триггерили таблица аудита.Это всегда приводит к торговле незначительной проблемой (эй, колонка была добавлена, и я должен сделать кое-что) для намного больших.Обычно вопросы производительности, правильности и надежности.

...