2017-09-04 4 views
1

私はすべての変更は、別のテーブル内のテーブルで発生したセーブ監査トリガーを書いています。SQL Server 2012の - トリガー:オペランドタイプ衝突:intは一意の識別子と互換性がありません

オペランドタイプ衝突:intは、一意の識別子

Usersテーブルは、とりわけ、uniqueidentifier列が含まれているとは互換性がありません。しかし、私はUsersテーブルを変更しようとしています。このエラーが発生します。ここで

は、エラーが発生したコードの一部です:

ALTER TRIGGER [dbo].[UsersLogger] 
ON [dbo].[Users] 
FOR INSERT, DELETE, UPDATE 
AS 
BEGIN 
    DECLARE @audit_oldvalue sql_variant; 
    DECLARE @audit_value sql_variant; 
    DECLARE @audit_field varchar(100); 
    DECLARE @sql nvarchar(max); 
    DECLARE @ParmDefinition nvarchar(max) ; 
    DECLARE @OutString varchar(max) ; 
    DECLARE @converted_uid nvarchar(50); 

    DECLARE @qid int ; 
    DECLARE @Cinfo VARBINARY(128) 

    SELECT @Cinfo = Context_Info() 

    IF @Cinfo = 0x55555 
     RETURN 

    DECLARE @Action as char(1); 
    SET @Action = (CASE WHEN EXISTS(SELECT * FROM INSERTED) 
         AND EXISTS(SELECT * FROM DELETED) 
         THEN 'U' -- Set Action to Updated. 
         ELSE NULL -- Skip. It may have been a "failed delete". 
        END) 

    SET @OutString = '' 

    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 = 'Users' and column_name <>'rowguid' and column_name <>'modifieddate' 
set @ParmDefinition = '@OutString varchar(max) OUTPUT' 
set @sql = 'Select @OutString = ' 
+ Substring(@sql,1 , len(@sql) -1) + 
' From dbo.Users i ' 
+ ' inner join #tempTrigT d on 
i.id = d.id' 
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) 

IF (TRY_CONVERT(UNIQUEIDENTIFIER, @Item) is not null) 
begin 
    select @Item = convert(nvarchar(50), @Item) 
end 
+0

このコードのどこに誤りがありますか? – GuidoG

+0

は、SQLを実行したときに、おそらく...知らないけど – aggicd

+0

イムわからないあなたはSSMS – GuidoG

答えて

1

私は推測していた場合、私はあなたがISNULLをやっているためです

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 = 'Users' and column_name <>'rowguid' and column_name <>'modifieddate' 

にそれを非難したいですUNIQUEIDENTIIFIER列の値をINTに設定します。ただし、ISNULL(i.[ColumnName], 0)からISNULL(i.[ColumnName], '')に変更することができます。これは、テーブル内のすべての列が文字列適用可能なデータ型であると仮定しています。そうでなければ、そのテーブルの[DATA_TYPE]列を使用して、ISNULL関数の置換値に条件付きロジックを実行できます。

+0

と...文字列を構築するので、私は単一引用符を使用傾ける...私は... IsNullのことを試してみました(D。[「+ Column_nameの+ 『]、』 + 『』 +」0)されます確かに問題があると思う。しかし、列がGUIDであるかどうかを確認する方法はありますか? – aggicd

+0

'information_schema.columns'テーブルには、カラムが' VARCHAR、INT、UNIQUEIDENTIFIER'などであるかどうかを知らせる '[DATA_TYPE]'カラムがあります。編集:戻って、本当にあなたが何をやろうとしているかに依存します。エラーを克服し、 'ISNULL'に文字列' 0 'を設定しなければ、データ型に基づいていくつかの面白い切り替えを行う。クエリの目的が謎のときに助言を与えるのは難しいです。 – PreQL

+0

列がヌル値を含む場合、空の文字列を設定することを目的としています。しかし、GUID列でチェックすると、intに変換できないため失敗します。だから、GUID列に空の値があり、空文字列を設定すると条件を書いてみたいと思います。 – aggicd

関連する問題