0

カラムがnvarchar(max)のテーブルがいくつかあります。私は、sql_Variantにセルを格納しようとするトリガを構築しています。 Nvarchar(max)はsql_variantに格納できません。どのようにnvarchar(最大)であるかどうかを確認してからnvarchar(4000)に変換して、これを避けることができますか?SQLトリガ:nvarcharサイズを変更する

EDIT:おそらくエラーが発生し、ここで:

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

@audit_oldvalueが#tempTrigTからsql_variant型が、[ '+ @項目+']であるため、データ型はnvarchar(MAX)することができ

の場合

operand type clash nvarchar(max) is incompatible with sql_variant

テーブル構造::

私はこのエラーを取得する入力テーブルで何かを編集します

入力テーブル

enter image description here

出力テーブル

enter image description here

私が変換したいコード:

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

どのdbmsを使用していますか? – jarlh

+0

@jarih sql server 2012 – aggicd

+0

「CONVERT(nvarchar(4000)、@nvarcharmaxparam)」を試しましたか? –

答えて

1

あなただけのVARCHARとしてそれをキャストすることができるはずです( 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' 

あなただけのこれらの列のためにこれをしたい場合、または(私はそれを信じていないだろう問題はパフォーマンス上の理由がない限り)。

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では、このコードについてさまざまな質問を投稿していますが、何時でも答えを受け付けていませんこれまでのところ(私が見たこと)。実際に必要なものについてOPが明確でないかどうかは不明です。 (申し訳ありませんが適切な場所ではなく、十分な担当者が私の自分の投稿にのみコメントすることができます) – PreQL

+0

あなたに答えていただきありがとうございます。同じコードであってもトピックは異なるので、私は異なる質問をしました。もちろん私は質問を受け入れました。 – aggicd

+0

2番目のスニペットをテストしましたが、同じエラーが再び表示されます。私はVARCHAR(4000)のすべてを変換する必要はありませんなぜスニペット#2を選択したのですか – aggicd

関連する問題