0

Ich habe mehrere Tabellen mit Spalten nvarchar (max). Ich baue einen Trigger, der versucht, die Zellen in sql_Variant zu speichern. Nvarchar (max) kann nicht in sql_variant gespeichert werden. Wie kann ich prüfen, ob es nvarchar (max) ist und dann in nvarchar (4000) konvertieren, damit ich das vermeiden kann?SQL-Trigger: nvarchar Größe ändern

EDIT: Wahrscheinlich tritt der Fehler hier:

set @sql = 'select @audit_oldvalue=[' [email protected] +'] from #tempTrigT'; 

Da @audit_oldvalue sql_variant ist aber [ '+ @ Artikel +'] von #tempTrigT kann nvarchar (max)

werden, wenn ich habe etwas in der Eingabetabelle bearbeiten ich diesen Fehler:

operand type clash nvarchar(max) is incompatible with sql_variant

Tabellen Struktur:

Eingabetabelle

enter image description here

Ausgabetabelle

enter image description here

-Code, wo ich konvertieren wollen:

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

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 = 'Forms' 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.Forms 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 


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'; --ERROR LINE 
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.Forms 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].[AuditTrailForms]([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 

    END 
ELSE 
BEGIN 
SELECT @Item = @OutString 
SELECT @Loop = 0 
END 
END 
+0

Welche DBMS verwenden Sie? – jarlh

+0

@jarih sql server 2012 – aggicd

+0

Haben Sie versucht "CONVERT (nvarchar (4000), @ nvarcharmaxparam)"? –

Antwort

1

Sie sollten nur als VARCHAR in der Lage zu werfen (4000).

Select @sql = @sql + 'Case when IsNull(CAST(i.[' + Column_Name + 
'] AS VARCHAR(4000)),0) = IsNull(CAST(d.[' + Column_name + '] AS VARCHAR(4000)),0) then '''' 
else ' + quotename(Column_Name, char(39)) + ' + '',''' + ' end +' 
from information_schema.columns 
where table_name = 'Forms' and column_name <>'rowguid' and column_name <>'modifieddate' 

Oder wenn Sie nur das für diese Spalten tun wollen (ich glaube es nicht wäre ein Problem, es sei denn aus Performance-Gründen).

Select @sql = @sql + 'Case when IsNull(' 
    + CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN 'CAST(' ELSE '' END 
    + 'i.[' + Column_Name + ']' 
    + CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN ' AS VARCHAR(4000))' ELSE '' END + 
    ',0) = IsNull(' 
    + CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN 'CAST(' ELSE '' END 
    + 'd.[' + Column_name + ']' 
    + CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN ' AS VARCHAR(4000))' ELSE '' END + 
    + ',0) then '''' else ' 
    + quotename(Column_Name, char(39)) + ' + '',''' + ' end +' 
from information_schema.columns 
where table_name = 'Forms' and column_name <>'rowguid' and column_name <>'modifieddate' 
+0

OP hat Fragen zu diesem Stück Code eine Reihe von Zeiten, wenn auch andere Fragen, aber keine Antwort in irgendeiner akzeptiert so weit (das habe ich gesehen). Nicht sicher, ob OP klar ist, was tatsächlich benötigt wird. (Entschuldigung, wenn nicht an der richtigen Stelle, nicht genug rep so kann nur auf meine eigenen Beiträge kommentieren) – PreQL

+0

danke für Ihre Antworten. Ich habe verschiedene Fragen gestellt, weil es im gleichen Code aber unterschiedlichen Themen gab. Natürlich habe ich Fragen angenommen. – aggicd

+0

Ich habe das zweite Snippet getestet, aber ich erhalte wieder den gleichen Fehler. Ich möchte nicht alles in VARCHAR konvertieren (4000), deshalb wählte ich Snippet # 2 – aggicd