2017-09-12 6 views
0

テーブル内のすべての変更を記録するトリガーを構築しています。テーブルの列がdatetimeの場合、正常に動作します。しかし、私はdateに変更した場合、私は、行を編集するとき、それは、このエラーがスローされます。SQL Server 2012(トリガー)オペランドタイプのクラッシュ:intと日付との互換性がありません

オペランドタイプ衝突:int型は、日付の日付とその場合は、変換する場合、私は確認することができますどのように

と互換性がありません。それは日時ですか?ここで

は(@itemは、各列の名前が含まれている)のコードは次のとおりです。

Select * into #tempTrigT from (select * from deleted where @Action in ('U','D')) A UNION (select * from inserted where @Action ='I') 

set @sql = '' 

if @Action = 'U' 
BEGIN 
Select @sql = @sql + 'Case when IsNull(i.[' + Column_Name + 
'],0) = IsNull(d.[' + Column_name + '],0) then '''' 
else ' + quotename(Column_Name, char(39)) + ' + '',''' + ' end +' 
from information_schema.columns 
where table_name = 'FormFields' and column_name <>'rowguid' and column_name <>'modifieddate' 
--Define output parameter 
set @ParmDefinition = '@OutString varchar(max) OUTPUT' 
--Format sql 
set @sql = 'Select @OutString = ' 
+ Substring(@sql,1 , len(@sql) -1) + 
' From dbo.FormFields i ' --Will need to be updated for target schema 
+ ' inner join #tempTrigT d on 
i.id = d.id' --Will need to be updated for target schema 
--Execute sql and retrieve desired column list in output parameter 
exec sp_executesql @sql, @ParmDefinition, @OutString OUT 

END 

DECLARE @Items VARCHAR(max) 



set @Items = @OutString; 

DECLARE @Item VARCHAR(50) 
DECLARE @Pos INT 
DECLARE @Loop BIT 
SELECT @Loop = CASE WHEN LEN(@OutString) > 0 THEN 1 ELSE 0 END 
WHILE (SELECT @Loop) = 1 
BEGIN 
SELECT @Pos = CHARINDEX(',', @OutString, 1) 
IF @Pos > 0 
BEGIN 
SELECT @Item = SUBSTRING(@OutString, 1, @Pos - 1) 
SELECT @OutString = SUBSTRING(@OutString, @Pos + 1, LEN(@OutString) - @Pos) 
---------------------------------- 

set @audit_field = @Item; 

set @sql = 'select @audit_oldvalue=[' [email protected] +'] from #tempTrigT'; 
EXEC SP_EXECUTESQL @sql,N'@audit_oldvalue sql_variant OUTPUT',@audit_oldvalue OUTPUT -- If inserted @audit_oldvalue gets the new value 

set @sql = 'select @audit_value=i.[' [email protected] +'] from dbo.FormFields i inner join #tempTrigT d on i.id = d.id'; 
EXEC SP_EXECUTESQL @sql,N'@audit_value sql_variant OUTPUT',@audit_value OUTPUT 


if @Action = 'U' 
begin 
    insert into [dbo].[AuditTrailFormFields]([TSid],[TSField],[OldValue],[NewValue],[changedate],[Change_Action],[Change_user],[Columns_Updated]) 
    select id,@audit_field, @audit_oldvalue, @audit_value,getdate(),@Action, coalesce(ModifiedBy,suser_name()), @Items 
    from inserted 

end 
+0

私はあなたの挿入ステートメントは、日付フィールドまたはその逆に整数を入れしようと推測します。あなたの列と注文が一致していますか? –

+0

はい。日付の列をdatetimeに変更してもうまくいけば、 – aggicd

+0

あなたはCDCを調べましたか?このような独自の監査を行うよりも簡単です。 –

答えて

0
Select @sql = @sql + 
    'Case when IsNull(i.[' + Column_Name + 
'],' + CASE DATA_TYPE 
     WHEN 'uniqueidentifier' THEN '''0''' 
     WHEN 'varchar' THEN CHAR(39) + '-' + CHAR(39) 
     WHEN 'nvarchar' THEN CHAR(39) + '-' + CHAR(39) 
     WHEN 'date' THEN CHAR(39) + '1/1/1900' + CHAR(39) 
     WHEN 'datetime' THEN CHAR(39) + '1/1/1900 00:00:00' + CHAR(39) 
     ELSE '0' 
     END + ') = IsNull(d.[' + Column_name + '],'+ 
     CASE DATA_TYPE 
     WHEN 'uniqueidentifier' THEN '''0''' 
     WHEN 'varchar' THEN CHAR(39) + '-' + CHAR(39) 
     WHEN 'nvarchar' THEN CHAR(39) + '-' + CHAR(39) 
     WHEN 'date' THEN CHAR(39) + '1/1/1900' + CHAR(39) 
     WHEN 'datetime' THEN CHAR(39) + '1/1/1900 00:00:00' + CHAR(39) 
     ELSE '0' 
     END + ') then '''' 
else ' + quotename(Column_Name, char(39)) + ' + '',''' + ' end +' 
from information_schema.columns 
where table_name = 'CTFormFields' and column_name <>'rowguid' and column_name <>'modifieddate' 
関連する問題