Триггер базы данных аудита - PullRequest
0 голосов
/ 03 января 2019

У меня есть триггер аудита для таблиц базы данных, я узнал об этом из онлайн-статьи.Триггер работает отлично, но я хочу настроить его в соответствии с моими потребностями.Я застрял в одном месте и мне нужна помощь.Я новичок в этом, так что это может быть простой вопрос.

ALTER TRIGGER [d2c].[tr_referral_client] ON [d2c].[referral_client] FOR 
UPDATE, DELETE, Insert
AS
SET NOCOUNT ON
    DECLARE @bit INT ,
    @field INT ,
    @fieldId INT ,
    @maxfield INT ,
    @char INT ,
    @fieldname VARCHAR(128) ,
    @FieldDisplayName VARCHAR(128),
    @TableDisplayName VARCHAR(128),
    @SchemaName VARCHAR(128) ,
    @TableName VARCHAR(128) ,
    @PKCols VARCHAR(1000) ,
    @sql VARCHAR(2000), 
    @UpdateDate VARCHAR(21) ,
    @UserName VARCHAR(128) ,
    @Type CHAR(1) ,
    @PKSelect VARCHAR(1000) ,
    @linkageID VARCHAR(1000) ,
    @FullTableName VARCHAR(256),
    @oldvalue VARCHAR(1000),
    @newvalue VARCHAR(1000),
    @modified_by VARCHAR(20)='modified_by',
    @isviewable char(1)

    --You will need to change @TableName to match the table to be audited
    SELECT @TableName = 'referral_client', @SchemaName = 'd2c'

    SELECT @FullTableName = @SchemaName + '.' + @TableName

    -- date and user
    SELECT @UserName = SYSTEM_USER ,
    @UpdateDate = CONVERT(VARCHAR(8), GETDATE(), 112) 
    + ' ' + CONVERT(VARCHAR(12), GETDATE(), 114)

    -- Action
    IF EXISTS (SELECT * FROM inserted)
    IF EXISTS (SELECT * FROM deleted)
    SELECT @Type = 'U'

        ELSE
            SELECT @Type = 'I'
        ELSE
    SELECT @Type = 'D'

    -- get list of columns
    SELECT * INTO #ins FROM inserted
    SELECT * INTO #del FROM deleted

     if @type in('U','D')
     select @isviewable = '1'
     else
     select @isviewable = '0'

    -- Get primary key columns for full outer join
    SELECT @PKCols = COALESCE(@PKCols + ' and', ' on') 
    + ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,

    INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
    WHERE pk.TABLE_NAME = @TableName
    AND pk.TABLE_SCHEMA = @SchemaName
    AND CONSTRAINT_TYPE = 'PRIMARY KEY'
    AND c.TABLE_NAME = pk.TABLE_NAME
    AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
    AND c.CONSTRAINT_SCHEMA = pk.TABLE_SCHEMA

    -- Get primary key select for insert
    SELECT @PKSelect = COALESCE(@PKSelect+'+','') + '''' +
     '''+convert(varchar(100),coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))+''''' 
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
    WHERE pk.TABLE_NAME = @TableName
    AND pk.TABLE_SCHEMA = @SchemaName
    AND CONSTRAINT_TYPE = 'PRIMARY KEY'
    AND c.TABLE_NAME = pk.TABLE_NAME
    AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
    AND c.CONSTRAINT_SCHEMA = pk.TABLE_SCHEMA

    -- Get client id select for insert
    SELECT @linkageID = COALESCE(@linkageID+'+','') + '''' + 
     '''+convert(varchar(100),coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))+''''' 
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
    WHERE c.TABLE_NAME = @TableName
    AND c.TABLE_SCHEMA = @SchemaName
    AND c.COLUMN_NAME = 'linkage_profile_id'

    IF @PKCols IS NULL
    BEGIN
    RAISERROR('no PK on table %s', 16, -1, @FullTableName)
    RETURN
    END

    ---------------------Display value for table
    SET @TableDisplayName = CASE @TableName
           WHEN 'referral_client' THEN 'Referrals'
        END
    --------------------------
    SELECT @field = 0, 
    @maxfield = MAX(ORDINAL_POSITION) 
    FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND TABLE_SCHEMA = @SchemaName

    WHILE @field < @maxfield
    BEGIN
    SELECT @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_NAME = @TableName
        AND TABLE_SCHEMA = @SchemaName
        AND ORDINAL_POSITION = @field

    SELECT @fieldid = COLUMNPROPERTY(OBJECT_ID(@FullTableName), @fieldname, 'ColumnID')

    SELECT @field = MIN(ORDINAL_POSITION) 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = @TableName 
    AND TABLE_SCHEMA = @SchemaName
    AND ORDINAL_POSITION > @field
    select @bit = (@fieldid - 1 )% 8 + 1
    select @bit = power(2,@bit - 1)
    select @char = ((@fieldid - 1) / 8) + 1

    --------------------getting referral values
    if @fieldname in ('referral_id')
    begin
    select @oldvalue = c.referral_name
    from lu.referral c inner join deleted d
    on d.referral_id = c.referral_id

    select @newvalue = c.referral_name
    from lu.referral c inner join inserted i
    on i.referral_id = c.referral_id
    end
    -------------------------

    if @fieldname NOT in ('referral_id')
    begin
    select @oldvalue ='Code here'====================================>>
    --convert(varchar(1000),d.' + @fieldname + ')'+ ',

    Select @newvalue = 'Code here'==================================>>
    --convert(varchar(1000),i.' + @fieldname + ')'+ ',

    END
    ------------------
    if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D')
        if @fieldname not in ('modified_by','date_modified')
            --------------display values for fields
        SET @FieldDisplayName = CASE @fieldname
           WHEN 'referral_client_id' THEN 'Referral ID'
           WHEN 'linkage_profile_id' THEN 'Linkage Profile ID'
           WHEN 'referral_id' THEN 'Referral Name'
           WHEN 'other_desc' THEN 'Other Description'
           WHEN 'Created_by' THEN 'Record Created By'
           WHEN 'Date_created' THEN 'Record Creation Date'
           WHEN 'Modified_by' THEN 'Record Last Modified By'
           WHEN 'date_modified' THEN 'Record Last Modified Date'
        END
    ---------------------------

    BEGIN

    SELECT @sql = '
    insert d2c.Audit ( Type,
    TableSchema,
    TableName,
    tabledisplayname,
    fielddisplayname, 
    PK, 
    linkage_profile_id,
    is_viewable,
    FieldName, 
    OldValue, 
    NewValue, 
    UpdateDate, 
    UserName,
    Application
    )
    select ''' + @Type + ''',
    ''' + @SchemaName + ''',
    ''' + @TableName + ''',
    ''' + @TableDisplayName + ''',
    ''' + @FieldDisplayName + ''',
    ' + @PKSelect+ ',
    ' + @linkageID+ ',
     '+ @isviewable+' ,
    ''' + @fieldname + ''''+ ',' + @oldvalue + ',
    ' + @newvalue + ',
    ''' + @UpdateDate + ''''+ ',

    ''' + @UserName + '''' + ',

    ''' + REPLACE(APP_NAME(), '''', '''''') + '''' 
           + ' from #ins i full outer join #del d'
           + @PKCols
           + ' where i.' + @fieldname + ' <> d.' + @fieldname 
           + ' or (i.' + @fieldname + ' is null and  d.' + @fieldname + ' is not null)' 
           + ' or (i.' + @fieldname + ' is not null and  d.' + @fieldname + ' is null)'
    EXEC (@sql)

    END
    END

Это триггер, который я использую.При вставке изменились значения в таблице аудита, старое значение и новое значение были вставлены с использованием кода - - convert(varchar(1000),d.' + @fieldname + ')'+ ', для удаленного и --convert(varchar(1000),i.' + @fieldname + ')'+ ', для вставленного.

Так как мне нужно было изменить значениядля определенного столбца я добавил оператор if и использовал @oldvalue и @newvalue для генерации того, что мне нужно, а затем пропустил его через оператор вставки.

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

Я могу ответить на любые ваши вопросы.

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