Not Trigger few Columns

  • I have tables with records when updated or delete would be moved to audit tables. But, I dont want to audit few columns in my tables so how should I do it inside the trigger.

    Create table abc (col1 int primary key, col2 int, col3 varchar(200), col4 varchar(15), col5 datetime)

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    Create trigger [dbo].[abc_Tra1]

    on [dbo].[abc]

    after update,

    delete

    as

    begin

    set nocount on

    set xact_abort on

    set arithabort on

    if (TRIGGER_NESTLEVEL()<2)

    BEGIN

    insert dbo.audit_abc

    (col1,col2,col2,col4,col5,audittype)

    select d.col1,d.col2,d.col2,d.col4,d.col5,

    case

    when i.col1 is null then 'delete'

    else 'update'

    end

    from deleted d

    left outer join inserted i

    on d.col1 = i.col1

    end

    end

    Here, I dont want to audit when updates are performed to col2 & col3 & whenever updates are performed on rest of the columns the old records should be pushed to audit tables.

    I'm using after update, delete trigger on the table to capture the audit records.

  • Go to Books Online (BOL) and lookup COLUMNS_UPDATED and UPDATE functions. That is where I'd start. let us know if you have any additional questions after reading about these functions.

  • COLUMNS_UPDATED is not helpful. It requires lot of validation which would impact the performance. I want this to be validated at the query level.

    if all columns except my two columns are not updated, then do audit.

    If I use COLUMNS_UPDATED the condition would be validated every time there is some action on the table instead I want the query to insert record in audit table except for my two columns updated action. I think some where condition to the query would do this.

  • Putting something in the Where clause will take more processing power than using the updated columns function.

    - Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
    Property of The Thread

    "Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon

  • To clarify, if col2 and col3 are updated, don't audit regardless if any other columns are updated? Or, if only col2 and/or col3 are updated don't audit? Sorry, your requirements are all that clear.

  • For example, take my query:

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select d.col1,d.col2,d.col2,d.col4,d.col5,

    case

    when i.col1 is null then 'delete'

    else 'update'

    end

    from deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where col2<>col2

    and col5<>col5

    In this query except col3 & col5 all other columns would be audited. As col1 is the key field it would not take much performance impact.

    moreover, (using COLUMN_UPDATES) the columns cordinal position if it has any design issue in the future.

  • RJ (3/31/2009)


    For example, take my query:

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select d.col1,d.col2,d.col2,d.col4,d.col5,

    case

    when i.col1 is null then 'delete'

    else 'update'

    end

    from deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where col2<>col2

    and col5<>col5

    In this query except col3 & col5 all other columns would be audited. As col1 is the key field it would not take much performance impact.

    moreover, (using COLUMN_UPDATES) the columns cordinal position if it has any design issue in the future.

    First, this doesn't clarify the requirements for me at all.

    Second, assuming the above is fired in a triggered fired for either an update or delete, it isn't going to work. One, it has ambiguous column names in the WHERE clause. Two, when fired for a delete, the WHERE clause, if properly aliased, will always be false as <> null will always return a false. You would need to check for null values on the RIGHT side of the LEFT OUTER JOIN.

  • You can use the Update() function for this, if you prefer column names over ordinal positions.

    - Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
    Property of The Thread

    "Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon

  • 1. My Requirement is I have 26 columns in a table & we might add few more columns. Out of 26, two columns one column is in 6 position & other is in 15th position which I dont want to audit. All other columns I want to audit.

    2. In my query that I posted I missed to put alias name in where clause. so the query would be:

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select d.col1,d.col2,d.col2,d.col4,d.col5,

    case

    when i.col1 is null then 'delete'

    else 'update'

    end

    from deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where d.col2<>i.col2

    and d.col5<>i.col5

    3. yes, during delete you will not see any records for inserted which will fail. I wanted to use any methods that simply help me in this state as my system is high performance application & cann't take any complex functions. More over whether Updated_COLUMNS would work if i have more than 32 columns in my table (also cardinal position scare me). I'm still not clear how to implement my requirement.

  • Does this give you what you want? Realize that this is going to be a large insert query for your actual table.

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select

    d.col1,

    d.col2,

    d.col2,

    d.col4,

    d.col5,

    case

    when i.col1 is null

    then 'delete'

    else 'update'

    end

    from

    deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where

    ((d.col1 <> i.col1) or (i.col1 is null))

    or ((d.col4 <> i.col4) or (i.col4 is null))

    or ((d.col5 <> i.col5) or (i.col5 is null))

    -- If changes only occurred to col2 or col3, no insert will occur.

  • this is a good query but would fail if there are NULL values in deleted. i think the below query would fix it. But, anyway I have to double check if this is better than any other methods. please also let me know how to implement this using "UPDATE" function inside the trigger in order to mention the column name explicitly.

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select

    d.col1,

    d.col2,

    d.col2,

    d.col4,

    d.col5,

    case

    when i.col1 is null

    then 'delete'

    else 'update'

    end

    from

    deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where

    ((d.col1 <> i.col1) or (i.col1 is null) or (d.col1 is null))

    or ((d.col4 <> i.col4) or (i.col4 is null) or (d.col4 is null))

    or ((d.col5 <> i.col5) or (i.col5 is null) or (d.col5 is null))

    --- If changes only occurred to col2 or col3, no insert will occur.

  • RJ (3/31/2009)


    this is a good query but would fail if there are NULL values in deleted. i think the below query would fix it. But, anyway I have to double check if this is better than any other methods. please also let me know how to implement this using "UPDATE" function inside the trigger in order to mention the column name explicitly.

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select

    d.col1,

    d.col2,

    d.col2,

    d.col4,

    d.col5,

    case

    when i.col1 is null

    then 'delete'

    else 'update'

    end

    from

    deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where

    ((d.col1 <> i.col1) or (i.col1 is null) or (d.col1 is null))

    or ((d.col4 <> i.col4) or (i.col4 is null) or (d.col4 is null))

    or ((d.col5 <> i.col5) or (i.col5 is null) or (d.col5 is null))

    --- If changes only occurred to col2 or col3, no insert will occur.

    That depends on your column definitions. If the columns do not allow null values, you only have to worry about the columns in the inserted table being null when a delete is done due to the left outer join.

  • Yes. Other than the key column we wouldn't need to add "or ((d.col5 <> i.col5) or (i.col5 is null) or (d.col5 is null))" to a column that is not nulllable as it will never have a null value.

    instead adding "or ((d.col5 <> i.col5))" would be good enough.

  • RJ (3/31/2009)


    Yes. Other than the key column we wouldn't need to add "or ((d.col5 <> i.col5) or (i.col5 is null) or (d.col5 is null))" to a column that is not nulllable as it will never have a null value.

    instead adding "or ((d.col5 <> i.col5))" would be good enough.

    You need to check for null values in the insert statement DUE TO THE LEFT OUTER JOIN. That is why you need the following code, even IF all columns are not nullable:

    insert dbo.audit_abc (col1,col2,col3,col4,col5,audittype)

    select

    d.col1,

    d.col2,

    d.col2,

    d.col4,

    d.col5,

    case

    when i.col1 is null

    then 'delete'

    else 'update'

    end

    from

    deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where

    ((d.col1 <> i.col1) or (i.col1 is null))

    or ((d.col4 <> i.col4) or (i.col4 is null))

    or ((d.col5 <> i.col5) or (i.col5 is null))

    -- If changes only occurred to col2 or col3, no insert will occur.

    On a delete, there will be NO records on the inserted side of the join.

  • the below one just worked fine. I have to test the performance alone now.

    col1 - primary key

    col2 & col3 - Need not audit

    col4 - nullable column

    col5 - not nullable column

    select

    d.col1,

    d.col2,

    d.col3,

    d.col4,

    d.col5,

    case

    when i.col1 is null

    then 'delete'

    else 'update'

    end

    from

    deleted d

    left outer join inserted i

    on d.col1 = i.col1

    where

    (

    i.col1 is null

    or ((d.col4 <> i.col4)

    or (i.col4 is not null and d.col4 is null)

    or (i.col4 is null and d.col4 is not null))

    or d.col5 <> i.col5

    )

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic. Login to reply