我有这个更新触发器,但它会记录列,即使新旧值是相同的值。 (这是因为EntityFramework更新语句的方式)。
set nocount on;
create table #updatedCols (Id int identity(1, 1), updateCol nvarchar(200))
--find all columns that were updated and write them to temp table
insert into #updatedCols (updateCol)
select
column_name
from
information_schema.columns
where
table_name = 'Items'
and convert(varbinary, reverse(columns_updated())) & power(convert(bigint, 2), ordinal_position - 1) > 0
--temp tables are used because inserted and deleted tables are not available in dynamic SQL
select * into #tempInserted from inserted
select * into #tempDeleted from deleted
declare @cnt int = 1
declare @rowCnt int
declare @columnName varchar(1000)
declare @sql nvarchar(4000)
select @rowCnt = count(*) from #updatedCols
--execute insert statement for each updated column
while @cnt <= @rowCnt
begin
select @columnName = updateCol from #updatedCols where id = @cnt
set @sql = N'
insert into [Events] ([RecordId], [EventTypeId], [EventDate], [ColumnName], [OriginalValue], [NewValue], [TenantId], [AppUserId], [TableName])
select
i.Id, 2, GetUTCDate(), ''' + @columnName + ''', d.' + @columnName + ', i.' + @columnName +', i.TenantId, i.UpdatedBy, ''Item''
from
#tempInserted i
join #tempDeleted d on i.Id = d.Id
'
exec sp_executesql @sql
set @cnt = @cnt + 1
end
所以我添加了更新连接以过滤掉值相同的位置:
#tempDeleted d on i.Id = d.Id and isnull(i.' + @columnName + ', '''') <> isnull(d.' +@columnName + ', '''')
但是,我现在收到错误:SqlException: Error converting data type varchar to numeric.
我猜测在某些情况下旧值为null(因此转换为空字符串),新值为int,因此Sql Server尝试将varchar转换为int以便比较它们并抛出错误。
这是对的吗?如果是这样,我该如何解决?
答案 0 :(得分:0)
如果您不想参数化变量,请执行以下操作
isnull(i.' + convert(varchar(100),@columnName) + ', '''')
否则使用参数定义选项