Home Forums SQL Server 2008 T-SQL (SS2K8) comparison in the merge statement about null values RE: comparison in the merge statement about null values

  • Sure understood. Here is an example script that shows what I want.

    Basically, I want to only create an audit when a user changes data for the table "tableName". I use the output clause right now to determine if a change was made. The audit trail that this query outputs will ignore the initial inserts of null (which is what I want), and report the changes that each of the users made and when they made them. This should be a self-contained repo. The procedure is pretty similar to what is actually called.

    I absolutely despise how verbose the way the is variable changed check is

    convert(binary(1),isnull(nullif(inserted.col1,deleted.col1),nullif(deleted.col1,inserted.col1))),

    [/sql]

    It would be much simpler to have something like convert(binary(1),(select inserted.col1 intersect inserted.col2))

    use tempdb;

    GO

    if (object_id('tableName') is not null)

    drop table tableName

    create table tableName

    (

    id int not null identity primary key clustered,

    col1 int null,

    col2 varchar(255) null,

    isActive bit not null default (1)

    )

    if (object_id('auditName') is not null)

    drop table tableName

    create table audit

    (

    auditId int not null identity primary key clustered,

    tableName sysname not null,

    attribute sysname not null,

    value sql_variant null,

    tableId int not null,

    auditUser sysname not null,

    auditdate datetime not null

    )

    if(object_id('upsertTableName') is not null)

    drop procedure upsertTableName

    Go

    create procedure upsertTableName

    (

    @Id int,

    @col1 int,

    @col2 varchar(255),

    @isActive bit,

    @userName varchar(255)

    )

    AS

    BEGIN

    declare @auditDate datetime = getdate();

    declare @ai table(

    id int,

    col1 bit,

    col2 bit,

    isActive bit

    )

    begin tran

    ;merge tableName as target

    using (select @Id [id],

    @col1 [col1],

    @col2 [col2],

    @isActive [isActive]) src

    on target.id=src.id

    when matched then

    update set

    target.col1 = src.col1,

    target.col2 = src.col2,

    target.isActive = src.isActive

    when not matched by target then

    insert(col1,col2,isActive)

    values(col1,col2,isActive)

    output

    inserted.$identity [id],

    convert(binary(1),isnull(nullif(inserted.col1,deleted.col1),nullif(deleted.col1,inserted.col1))),

    convert(binary(1),isnull(nullif(inserted.col2,deleted.col2),nullif(deleted.col2,inserted.col2))),

    convert(binary(1),isnull(nullif(inserted.isActive,deleted.isActive),nullif(deleted.isActive,inserted.isActive)))

    into @ai(id,col1,col2,isActive)

    output inserted.id [id];

    insert into audit(TableName,attribute,Value,TableId,auditdate,auditUser)

    select 'TableName',target.attribute,target.value,z.id,@auditDate,@userName

    from @ai z

    cross apply (VALUES

    ('col1',convert(sql_variant,@col1),z.col1),

    ('col2',convert(sql_variant,@col2),z.col2),

    ('isActive',convert(sql_variant,@isActive),z.isActive)

    ) target (attribute,value,includeIfNotNull)

    where target.includeIfNotNull is not null

    commit

    END

    GO

    declare @t table(id int)

    declare @id int;

    insert @t

    exec upsertTableName null,null,null,1,'jim'

    select @id = (select * from @t)

    waitfor delay '00:00:00.5'

    ;exec upsertTableName @id,1,'a',1,'eric'

    waitfor delay '00:00:00.5'

    ;exec upsertTableName @id,2,'a',1,'susan'

    waitfor delay '00:00:00.5'

    ;exec upsertTableName @id,null,null,0,'john'

    select attribute,value,audituser FROM audit

    where tableId = @id

    and tableName = 'tableName'

    order by auditDate

    /*

    attributevalueaudituser

    isActive1jim

    col11eric

    col2aeric

    col12susan

    col1NULLjohn

    col2NULLjohn

    isActive0john

    */

    drop table audit

    drop table tableName

    drop procedure upsertTableName