2017-09-04 47 views
1

我在寫一個審計觸發器,它將另一個表中發生的每一個變化都保存在表中。但我收到的時候我試圖改變Users表這個錯誤:SQL Server 2012 - 觸發器:操作數類型衝突:int與唯一標識符不兼容

操作數類型衝突:int是具有獨特標識符

Users表包含uniqueidentifier列,以及其他不兼容。

這裏是哪裏發生錯誤的部分代碼:

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

如果我猜的話,我會責怪

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' 

這是因爲你在做一個ISNULLUNIQUEIDENTIIFIER列上並將該值設置爲INT。但是,您可以將ISNULL(i.[ColumnName], 0)更改爲ISNULL(i.[ColumnName], ''),假設您的表中的所有列都是適用於字符串的數據類型。否則,可以使用該表中的[DATA_TYPE]列,對ISNULL函數的替換值執行一些條件邏輯。

+0

I認爲確實存在這個問題。但我如何檢查列是否是GUID? – aggicd

+0

在你的'information_schema.columns'表中,你有一個'[DATA_TYPE]'列,可以讓你知道列是否是'VARCHAR,INT,UNIQUEIDENTIFIER'等等。編輯:收回它,真的取決於你想要做什麼,如果你只需要克服這個錯誤,然後將'ISNULL'中的'0'設置爲一個字符串,即'0',否則,你將擁有根據數據類型做一些奇特的切換。當查詢的目的有點神祕時,很難給出建議。 – PreQL

+0

目的是在列中包含空值時設置空字符串。但是,當檢查與GUID列失敗,因爲它不能將其轉換爲int。所以我想寫一個條件,如果有GUID列有空值,然後設置空字符串 – aggicd

相關問題