私はデータ移行プロジェクトに参加しています。あるテーブルから別のテーブルにデータを挿入しようとすると、次のエラーが発生します(SQL Server 2005)。
メッセージ8152、レベル16、状態13、行1
文字列またはバイナリデータは切り捨てられます。
ソースデータの列がデータ型と一致し、宛先テーブルの列の長さの定義内にあるため、このエラーの原因を突き止められません。
私はデータ移行プロジェクトに参加しています。あるテーブルから別のテーブルにデータを挿入しようとすると、次のエラーが発生します(SQL Server 2005)。
メッセージ8152、レベル16、状態13、行1
文字列またはバイナリデータは切り捨てられます。
ソースデータの列がデータ型と一致し、宛先テーブルの列の長さの定義内にあるため、このエラーの原因を突き止められません。
回答:
問題がどこにあるのかを把握するには、ソーステーブルと宛先テーブルのテーブル定義を送信する必要がありますが、最終的には、ソーステーブルの列の1つが宛先列よりも大きいということです。気づかなかった方法でフォーマットを変更している可能性があります。移行元のデータベースモデルは、それを理解する上でも重要です。
他の人がすでに述べたように、ソーステーブルの列データ型の1つが宛先列より大きいです。
単純な解決策は、警告をオフにして切り捨てを許可することです。したがって、このエラーが表示されても、古いデータベース/テーブルのデータが切り捨てられる(サイズに切り捨てられる)ことが許容できる場合は、次の手順を実行するだけです。
SET ANSI_WARNINGS  OFF;
-- Your insert TSQL here.
SET ANSI_WARNINGS ON;
上記のように、後で警告を再びオンにすることを常に忘れないでください。これがお役に立てば幸いです。
問題は非常に単純です。ソースクエリの1つ以上の列に、宛先列の長さを超えるデータが含まれています。簡単な解決策は、ソースクエリを取得Max(Len( source col ))して各列で実行することです。つまり、
Select Max(Len(TextCol1))
    , Max(Len(TextCol2))
    , Max(Len(TextCol3))
    , ...
From ...
次に、それらの長さを宛先テーブルのデータ型の長さと比較します。少なくとも1つは、宛先列の長さを超えています。
これが当てはまらないことを絶対的に確信していて、当てはまらないことを気にしない場合、別の解決策は、ソースクエリ列を宛先の長さに強制的にキャストすることです(長すぎるデータは切り捨てられます)。
Select Cast(TextCol1 As varchar(...))
    , Cast(TextCol2 As varchar(...))
    , Cast(TextCol3 As varchar(...))
    , ...
From ...
              SQL Server 2019は、より意味のあるエラーメッセージを最終的に返します。
バイナリデータまたは文字列データが切り捨てられる=>エラーメッセージの機能強化
(本番環境で)エラーが発生した場合、このエラーがどの列または行から発生したのか、および正確に特定する方法はわかりません。
新しい動作を有効にするには、を使用する必要がありますDBCC TRACEON(460)。からの新しいエラーテキストsys.messages:
SELECT * FROM sys.messages WHERE message_id = 2628
2628 –文字列またはバイナリデータは、テーブル '%。* ls'、列 '%。* ls'で切り捨てられます。切り捨てられた値: '%。* ls'。
文字列またはバイナリデータは切り捨てられます:悪名高いエラー8152を置き換えます
この新しいメッセージは、SQL Server 2017 CU12(および今後のSQL Server 2016 SP2 CU)にもバックポートされますが、デフォルトではバックポートされません。セッションレベルまたはサーバーレベルで、メッセージID 8152を2628に置き換えるには、トレースフラグ460を有効にする必要があります。
現時点では、SQL Server 2019 CTP 2.0でも、同じトレースフラグ460を有効にする必要があることに注意してください。SQL Server 2019の今後のリリースでは、デフォルトでメッセージ2628がメッセージ8152に置き換わります。
SQL Server 2017 CU12もこの機能をサポートしています。
改善:SQL Server 2017の拡張情報を含む「文字列またはバイナリデータが切り捨てられる」メッセージのオプションの置き換え
このSQL Server 2017更新プログラムでは、次の追加のコンテキスト情報を含むオプションのメッセージが導入されています。
Msg 2628, Level 16, State 6, Procedure ProcedureName, Line Linenumber String or binary data would be truncated in table '%.*ls', column '%.*ls'. Truncated value: '%.*ls'.新しいメッセージIDは2628です。トレースフラグ460が有効になっている場合、このメッセージはエラー出力のメッセージ8152を置き換えます。
VERBOSE_TRUNCATION_WARNINGS = {ON | オフ}
適用対象:SQL Server(SQL Server 2019(15.x)以降)およびAzure SQLデータベース
新しい文字列またはバイナリデータが切り捨てられるエラーメッセージを有効または無効にすることができます。SQL Server 2019(15.x)では、このシナリオに対して、より具体的な新しいエラーメッセージ(2628)が導入されています。
String or binary data would be truncated in table '%.*ls', column'%.*ls'. Truncated value: '%.*ls'.データベース互換性レベル150でONに設定すると、切り捨てエラーにより新しいエラーメッセージ2628が発生し、より多くのコンテキストが提供され、トラブルシューティングプロセスが簡素化されます。
データベース互換性レベル150でOFFに設定すると、切り捨てエラーにより前のエラーメッセージ8152が発生します。
データベース互換性レベル140以下の場合、エラーメッセージ2628はオプトインエラーメッセージのままで、トレースフラグ460を有効にする必要があり、このデータベーススコープの構成は効果がありません。
この他の考えられる理由の1つは、列の長さを超える列のデフォルト値を設定している場合です。長さ5の列に太い指を太った人がいるようですが、デフォルト値が長さ5を超えていました。挿入しているすべてのものが整数が1の単一の列。テーブルスキーマのデフォルト値に違反しているデフォルト値があったため、すべてが台無しになりました-これは私が学んだ教訓につながると思います-スキーマ内にデフォルト値のテーブルを持つことは避けてください。:)
これは難しいエラーになる可能性があります。https://connect.microsoft.com/SQLServer/feedback/details/339410/からのメモの一部を次に示します。AmirCharaniaのコメントを探してください。
一時的なものではなく、実際のテーブルに選択されたデータに対して、AmirCharaniaによって与えられた回答を調整しました。最初にデータセットを開発テーブルに選択し、次を実行します。
WITH CTE_Dev
AS (
    SELECT C.column_id
        ,ColumnName = C.NAME
        ,C.max_length
        ,C.user_type_id
        ,C.precision
        ,C.scale
        ,DataTypeName = T.NAME
    FROM sys.columns C
    INNER JOIN sys.types T ON T.user_type_id = C.user_type_id
    WHERE OBJECT_ID = OBJECT_ID('YOUR TARGET TABLE NAME HERE, WITH SCHEMA')
    )
    ,CTE_Temp
AS (
    SELECT C.column_id
        ,ColumnName = C.NAME
        ,C.max_length
        ,C.user_type_id
        ,C.precision
        ,C.scale
        ,DataTypeName = T.NAME
    FROM sys.columns C
    INNER JOIN sys.types T ON T.user_type_id = C.user_type_id
    WHERE OBJECT_ID = OBJECT_ID('YOUR TEMP TABLE NAME HERE, WITH SCHEMA')
    )
SELECT *
FROM CTE_Dev D
FULL OUTER JOIN CTE_Temp T ON D.ColumnName = T.ColumnName
WHERE ISNULL(D.max_length, 0) < ISNULL(T.max_length, 999)
              今日、この問題に遭遇しました。この最小限の有益なエラーメッセージへの回答を検索したところ、次のリンクも見つかりました。
したがって、マイクロソフトはすぐにエラーメッセージを拡張する予定はないようです。
だから私は他の手段に向けました。
エラーをExcelにコピーしました:
(1行が影響を受けました)
(1行が影響を受けました)
(1行が影響を受けます)メッセージ8152、レベル16、状態14、行13文字列またはバイナリデータは切り捨てられます。ステートメントは終了されました。
(1行が影響を受けました)
Excelの行数をカウントし、問題の原因となったレコードカウンターに近づきました...エクスポートコードを調整して、それに近いSQLを出力しました...次に、問題のSQLの周りに5〜10のSQL挿入を実行し、問題のあるものを特定し、長すぎる文字列を確認し、その列のサイズを大きくすると、大きなインポートファイルは問題なく実行されました。
ちょっとしたハックと回避策ですが、選択肢がほとんどない場合は、できることを実行します。
はい、私もこのような問題に直面しています。
REMARKS VARCHAR(500)
to
REMARKS VARCHAR(1000)
ここでは、REMARKSのファイル長を500から1000に変更しました
うん-「半パイントの鍋にパイントは行きません」。私は、人々が提案したさまざまなSPで(何らかの理由で)あまり運がよかったのですが、2つのテーブルが同じDBにある(または同じDBに入れることができる)限り、INFORMATION_SCHEMAを使用できます。誤ったフィールドを見つけるためのCOLUMNS、つまり:
select c1.table_name,c1.COLUMN_NAME,c1.DATA_TYPE,c1.CHARACTER_MAXIMUM_LENGTH,c2.table_name,c2.COLUMN_NAME, c2.DATA_TYPE,c2.CHARACTER_MAXIMUM_LENGTH
from [INFORMATION_SCHEMA].[COLUMNS] c1
left join [INFORMATION_SCHEMA].[COLUMNS] c2 on 
c1.COLUMN_NAME=c2.COLUMN_NAME
where c1.TABLE_NAME='MyTable1'
and c2.TABLE_NAME='MyTable2'
--and c1.DATA_TYPE<>c2.DATA_TYPE
--and c1.CHARACTER_MAXIMUM_LENGTH <> c2.CHARACTER_MAXIMUM_LENGTH
order by c1.COLUMN_NAME
これにより、フィールドの長さを比較しながら上下にスクロールできます。コメント付きのセクションでは、データ型の不一致があるかどうかを確認できます(コメント解除すると、明らかに)、またはフィールド長が異なるものを具体的に示します-スクロールするのが面倒なので、すべてがソースに基づいていることに注意してくださいターゲットの列名と一致する列名。
テーブルの作成時に空の文字列 ''を使用していて、その後の更新でエラー「Msg 8152、文字列またはバイナリデータが切り捨てられました」を受け取りました。これは、更新値が6文字を含み、予想される列定義よりも大きいために発生していました。これを回避するために "SPACE"を使用したのは、最初のデータ作成後に一括で更新すること、つまり、列が長時間空のままになることはないとわかっていたためです。
ここで重要な警告:これは特に洗練されたソリューションではありませんが、データマイニング用のテーブルを作成し、いくつかの一括処理/解釈を適用して、データセットをまとめる場合に役立ちます。後で比較/マイニングするために、結果の前後に保存します。これは私の仕事で頻繁に発生します。
最初にSPACEキーワードを使用して入力できます。
    select 
           Table1.[column1]
          ,Table1.[column2]
          ,SPACE(10) as column_name
    into table_you_are_creating
    from Table1
    where ...
その後、「column_name」を10文字以下(該当する場合は置換)に更新しても、切り捨てエラーは発生しません。繰り返しますが、これは私の警告に記載されているのと同様のシナリオでのみ使用します。
最小長(min_len)と最大長(max_len)の間で列ごとにいくつかの特性を持つソーステーブルまたはクエリを分析するストアドプロシージャを構築しました。
CREATE PROCEDURE [dbo].[sp_analysetable] (
  @tableName varchar(8000),
  @deep bit = 0
) AS
/*
sp_analysetable 'company'
sp_analysetable 'select * from company where name is not null'
*/
DECLARE @intErrorCode INT, @errorMSG VARCHAR(500), @tmpQ NVARCHAR(2000), @column_name VARCHAR(50), @isQuery bit
SET @intErrorCode=0
IF OBJECT_ID('tempdb..##tmpTableToAnalyse') IS NOT NULL BEGIN
  DROP TABLE ##tmpTableToAnalyse
END
IF OBJECT_ID('tempdb..##tmpColumns') IS NOT NULL BEGIN
  DROP TABLE ##tmpColumns
END
if CHARINDEX('from', @tableName)>0
  set @isQuery=1
IF @intErrorCode=0 BEGIN
  if @isQuery=1 begin
    --set @tableName = 'USE '+@db+';'+replace(@tableName, 'from', 'into ##tmpTableToAnalyse from')
    --replace only first occurance. Now multiple froms may exists, but first from will be replaced with into .. from
    set @tableName=Stuff(@tableName, CharIndex('from', @tableName), Len('from'), 'into ##tmpTableToAnalyse from')
    exec(@tableName)
    IF OBJECT_ID('tempdb..##tmpTableToAnalyse') IS NULL BEGIN
      set @intErrorCode=1
      SET @errorMSG='Error generating temporary table from query.'
    end
    else begin
      set @tableName='##tmpTableToAnalyse'
    end
  end
end
IF @intErrorCode=0 BEGIN
  SET @tmpQ='USE '+DB_NAME()+';'+CHAR(13)+CHAR(10)+'
  select
    c.column_name as [column],
    cast(sp.value as varchar(1000)) as description,
    tc_fk.constraint_type,
    kcu_pk.table_name as fk_table,
    kcu_pk.column_name as fk_column,
    c.ordinal_position as pos,
    c.column_default as [default],
    c.is_nullable as [null],
    c.data_type,
    c.character_maximum_length as length,
    c.numeric_precision as [precision],
    c.numeric_precision_radix as radix,
    cast(null as bit) as [is_unique],
    cast(null as int) as min_len,
    cast(null as int) as max_len,
    cast(null as int) as nulls,
    cast(null as int) as blanks,
    cast(null as int) as numerics,
    cast(null as int) as distincts,
    cast(null as varchar(500)) as distinct_values,
    cast(null as varchar(50)) as remarks
  into ##tmpColumns'
  if @isQuery=1 begin
    SET @tmpQ=@tmpQ+' from tempdb.information_schema.columns c, (select null as value) sp'
  end
  else begin
    SET @tmpQ=@tmpQ+'
      from information_schema.columns c
      left join sysobjects so    on so.name=c.table_name  and so.xtype=''U''
      left join syscolumns sc    on sc.name=c.column_name and sc.id  =so.id 
      left join sys.extended_properties sp on sp.minor_id = sc.colid AND sp.major_id = sc.id and sp.name=''MS_Description''  
      left join information_schema.key_column_usage kcu_fk    on kcu_fk.table_name = c.table_name     and c.column_name = kcu_fk.column_name
      left join information_schema.table_constraints tc_fk    on kcu_fk.table_name = tc_fk.table_name and kcu_fk.constraint_name = tc_fk.constraint_name
      left join information_schema.referential_constraints rc on rc.constraint_name = kcu_fk.constraint_name
      left join information_schema.table_constraints tc_pk    on rc.unique_constraint_name = tc_pk.constraint_name
      left join information_schema.key_column_usage kcu_pk    on tc_pk.constraint_name = kcu_pk.constraint_name
 '
  end
  SET @tmpQ=@tmpQ+' where c.table_name = '''+@tableName+''''
  exec(@tmpQ)
end
IF @intErrorCode=0 AND @deep = 1 BEGIN
  DECLARE
    @count_rows int,
    @count_distinct int,
    @count_nulls int,
    @count_blanks int,
    @count_numerics int,
    @min_len int,
    @max_len int,
    @distinct_values varchar(500)
  DECLARE curTmp CURSOR LOCAL FAST_FORWARD FOR
    select [column] from ##tmpColumns;
  OPEN curTmp
  FETCH NEXT FROM curTmp INTO @column_name
  WHILE @@FETCH_STATUS = 0 and @intErrorCode=0 BEGIN
    set @tmpQ = 'USE '+DB_NAME()+'; SELECT'+
      '  @count_rows=count(0), '+char(13)+char(10)+
      '  @count_distinct=count(distinct ['+@column_name+']),'+char(13)+char(10)+
      '  @count_nulls=sum(case when ['+@column_name+'] is null then 1 else 0 end),'+char(13)+char(10)+
      '  @count_blanks=sum(case when ltrim(['+@column_name+'])='''' then 1 else 0 end),'+char(13)+char(10)+
      '  @count_numerics=sum(isnumeric(['+@column_name+'])),'+char(13)+char(10)+
      '  @min_len=min(len(['+@column_name+'])),'+char(13)+char(10)+
      '  @max_len=max(len(['+@column_name+']))'+char(13)+char(10)+
      ' from ['+@tableName+']'
    exec sp_executesql @tmpQ,
                       N'@count_rows int OUTPUT,
                         @count_distinct int OUTPUT,
                         @count_nulls int OUTPUT,
                         @count_blanks int OUTPUT,
                         @count_numerics int OUTPUT,
                         @min_len int OUTPUT,
                         @max_len int OUTPUT',
                       @count_rows     OUTPUT,
                       @count_distinct OUTPUT,
                       @count_nulls    OUTPUT,
                       @count_blanks    OUTPUT,
                       @count_numerics OUTPUT,
                       @min_len        OUTPUT,
                       @max_len        OUTPUT
    IF (@count_distinct>10) BEGIN
      SET @distinct_values='Many ('+cast(@count_distinct as varchar)+')'
    END ELSE BEGIN
      set @distinct_values=null
      set @tmpQ = N'USE '+DB_NAME()+';'+
        '  select @distinct_values=COALESCE(@distinct_values+'',''+cast(['+@column_name+'] as varchar),  cast(['+@column_name+'] as varchar))'+char(13)+char(10)+
        '  from ('+char(13)+char(10)+
        '    select distinct ['+@column_name+'] from ['+@tableName+'] where ['+@column_name+'] is not null) a'+char(13)+char(10)
      exec sp_executesql @tmpQ,
                         N'@distinct_values varchar(500) OUTPUT',
                         @distinct_values        OUTPUT
    END
    UPDATE ##tmpColumns SET
      is_unique      =case when @count_rows=@count_distinct then 1 else 0 end,
      distincts      =@count_distinct,
      nulls          =@count_nulls,
      blanks         =@count_blanks,
      numerics       =@count_numerics,
      min_len        =@min_len,
      max_len        =@max_len,
      distinct_values=@distinct_values,
      remarks       =
        case when @count_rows=@count_nulls then 'all null,' else '' end+
        case when @count_rows=@count_distinct then 'unique,' else '' end+
        case when @count_distinct=0 then 'empty,' else '' end+
        case when @min_len=@max_len then 'same length,' else '' end+
        case when @count_rows=@count_numerics then 'all numeric,' else '' end
    WHERE [column]=@column_name
    FETCH NEXT FROM curTmp INTO @column_name
  END
  CLOSE curTmp DEALLOCATE curTmp
END
IF @intErrorCode=0 BEGIN
  select * from ##tmpColumns order by pos
end
IF @intErrorCode=0 BEGIN --Clean up temporary tables
  IF OBJECT_ID('tempdb..##tmpTableToAnalyse') IS NOT NULL BEGIN
    DROP TABLE ##tmpTableToAnalyse
  END
  IF OBJECT_ID('tempdb..##tmpColumns') IS NOT NULL BEGIN
    DROP TABLE ##tmpColumns
  END
end
IF @intErrorCode<>0 BEGIN
  RAISERROR(@errorMSG, 12, 1)
END
RETURN @intErrorCode
この手順をマスターデータベースに保存して、次のようにすべてのデータベースで使用できるようにします。
sp_analysetable 'table_name', 1
// deep=1 for doing value analyses
そして出力は:
column              description constraint_type fk_table        fk_column          pos default       null data_type        length precision radix is_unique min_len max_len nulls blanks numerics distincts distinct_values remarks
id_individual       NULL        PRIMARY KEY     NULL            NULL               1   NULL          NO   int              NULL   10        10    1         1       2       0     0      70       70        Many (70)       unique,all numeric,
id_brand            NULL        NULL            NULL            NULL               2   NULL          NO   int              NULL   10        10    0         1       1       0     0      70       2         2,3             same length,all numeric,
guid                NULL        NULL            NULL            NULL               3   (newid())     NO   uniqueidentifier NULL   NULL      NULL  1         36      36      0     0      0        70        Many (70)       unique,same length,
customer_id         NULL        NULL            NULL            NULL               4   NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
email               NULL        NULL            NULL            NULL               5   NULL          YES  varchar          100    NULL      NULL  0         4       36      0     0      0        31        Many (31)
mobile              NULL        NULL            NULL            NULL               6   NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
initials            NULL        NULL            NULL            NULL               7   NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
title_short         NULL        NULL            NULL            NULL               8   NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
title_long          NULL        NULL            NULL            NULL               9   NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
firstname           NULL        NULL            NULL            NULL               10  NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
lastname            NULL        NULL            NULL            NULL               11  NULL          YES  varchar          50     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
address             NULL        NULL            NULL            NULL               12  NULL          YES  varchar          100    NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
pc                  NULL        NULL            NULL            NULL               13  NULL          YES  varchar          10     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
kixcode             NULL        NULL            NULL            NULL               14  NULL          YES  varchar          20     NULL      NULL  0         NULL    NULL    70    0      0        0         NULL            all null,empty,
date_created        NULL        NULL            NULL            NULL               15  (getdate())   NO   datetime         NULL   NULL      NULL  1         19      19      0     0      0        70        Many (70)       unique,same length,
created_by          NULL        NULL            NULL            NULL               16  (user_name()) NO   varchar          50     NULL      NULL  0         13      13      0     0      0        1         loyalz-public   same length,
id_location_created NULL        FOREIGN KEY     location        id_location        17  NULL          YES  int              NULL   10        10    0         1       1       0     0      70       2         1,2             same length,all numeric,
id_individual_type  NULL        FOREIGN KEY     individual_type id_individual_type 18  NULL          YES  int              NULL   10        10    0         NULL    NULL    70    0      0        0         NULL            all null,empty,
optin               NULL        NULL            NULL            NULL               19  NULL          YES  int              NULL   10        10    0         1       1       39    0      31       2         0,1             same length,
sp_でください。Microsoftはそのプレフィックスを独自に使用するために予約しており(「ストアドプロシージャの名前付け」を参照)、将来、名前が衝突するリスクを負うことになります。また、ストアドプロシージャのパフォーマンスも低下します。単にsp_他のものを単に回避して接頭辞として使用するか、接頭辞をまったく使用しないのが最善です!
                    INSERT SELECTステートメントを使用したときに、テキストの切り捨て(文字列またはバイナリデータが切り捨てられる)の問題を特定して解決するのに役立つ、便利なストアプロシージャを作成しました。エラーの考えられる原因である場合、フィールドCHAR、VARCHAR、NCHARおよびNVARCHARのみを比較し、フィールドごとに評価フィールドを返します。
EXEC dbo.GetFieldStringTruncate SourceTableName, TargetTableName
このストアドプロシージャは、INSERT SELECTステートメントが作成されたときのテキストの切り捨ての問題を対象としています。
このストアドプロシージャの操作は、問題のあるINSERTステートメントを以前に特定したユーザーに依存します。次に、ソースデータをグローバル一時テーブルに挿入します。SELECT INTOステートメントをお勧めします。
SELECTステートメントの各フィールドのエイリアスで、宛先テーブルのフィールドと同じ名前を使用する必要があります。
機能コード:
DECLARE @strSQL nvarchar(1000)
IF NOT EXISTS (SELECT * FROM dbo.sysobjects where id = OBJECT_ID(N'[dbo].[GetFieldStringTruncate]'))
    BEGIN
        SET @strSQL = 'CREATE PROCEDURE [dbo].[GetFieldStringTruncate] AS RETURN'
        EXEC sys.sp_executesql @strSQL
    END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
------------------------------------------------------------------------------------------------------------------------
    Description:    
                    Syntax 
                    ---------------
                    dbo.GetFieldStringTruncate(SourceTable, TargetTable)
                    +---------------------------+-----------------------+
                    |   SourceTableName         |   VARCHAR(255)        |
                    +---------------------------+-----------------------+
                    |   TargetTableName         |   VARCHAR(255)        |
                    +---------------------------+-----------------------+
                    Arguments
                    ---------------
                    SourceTableName
                    The name of the source table. It should be a temporary table using double charp '##'. E.g. '##temp'
                    TargetTableName
                    The name of the target table. It is the table that receives the data used in the INSERT INTO stament.
                    Return Type
                    ----------------
                    Returns a table with a list of all the fields with the type defined as text and performs an evaluation indicating which field would present the problem of string truncation.
                    Remarks
                    ----------------
                    This stored procedure is oriented to the problem of text truncation when an INSERT SELECT statement is made.
                    The operation of this stored procedure depends on the user previously identifying the INSERT statement with the problem. Then inserting the source data into a global temporary table. The SELECT INTO statement is recommended.
                    You must use the same name of the field of the destination table in the alias of each field of the SELECT statement.
                    Examples
                    ====================================================================================================
                    --A. Test basic
                        IF EXISTS (SELECT * FROM sys.objects  WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[tblDestino]') AND TYPE IN (N'U'))
                            DROP TABLE tblDestino
                        CREATE TABLE tblDestino
                        (
                            Id INT IDENTITY,
                            Field1 VARCHAR(10),
                            Field2 VARCHAR(12),
                            Field3 VARCHAR(11),
                            Field4 VARCHAR(16),
                            Field5 VARCHAR(5),
                            Field6 VARCHAR(1),
                            Field7 VARCHAR(1),
                            Field8 VARCHAR(6),
                            Field9 VARCHAR(6),
                            Field10 VARCHAR(50),
                            Field11 VARCHAR(50),
                            Field12 VARCHAR(50)
                        )
                        INSERT INTO dbo.tblDestino
                        (
                             Field1 ,
                             Field2 ,
                             Field3 ,
                             Field4 ,
                             Field5 ,
                             Field6 ,
                             Field7 ,
                             Field8 ,
                             Field9 ,
                             Field10 ,
                             Field11 ,
                             Field12
                            )
                        SELECT 
                             '123456789' , -- Field1 - varchar(10)
                             '123456789' , -- Field2 - varchar(12)
                             '123456789' , -- Field3 - varchar(11)
                             '123456789' , -- Field4 - varchar(16)
                             '123456789' , -- Field5 - varchar(5)
                             '123456789' , -- Field6 - varchar(1)
                             '123456789' , -- Field7 - varchar(1)
                             '123456789' , -- Field8 - varchar(6)
                             '123456789' , -- Field9 - varchar(6)
                             '123456789' , -- Field10 - varchar(50)
                             '123456789' , -- Field11 - varchar(50)
                             '123456789'  -- Field12 - varchar(50)
                        GO  
                    Result:
                        String or binary data would be truncated
                    *Here you get the truncation error. Then, we proceed to save the information in a global temporary table. 
                    *IMPORTANT REMINDER: You must use the same name of the field of the destination table in the alias of each field of the SELECT statement.
                    Process:
                        IF OBJECT_ID('tempdb..##TEMP') IS NOT NULL DROP TABLE ##TEMP
                        go
                        SELECT 
                             [Field1] = '123456789' ,
                             [Field2] = '123456789' ,
                             [Field3] = '123456789' ,
                             [Field4] = '123456789' ,
                             [Field5] = '123456789' ,
                             [Field6] = '123456789' ,
                             [Field7] = '123456789' ,
                             [Field8] = '123456789' ,
                             [Field9] = '123456789' ,
                             [Field10] = '123456789' ,
                             [Field11] = '123456789' ,
                             [Field12] = '123456789'  
                        INTO ##TEMP
                    Result:
                    (1 row(s) affected)
                    Test:
                        EXEC dbo.GetFieldStringTruncate @SourceTableName = '##TEMP', @TargetTableName = 'tblDestino'
                    Result:
                        (12 row(s) affected)
                        ORIGEN Nombre Campo        ORIGEN Maximo Largo  DESTINO Nombre Campo     DESTINO Tipo de campo   Evaluación
                        -------------------------- -------------------- ------------------------ ----------------------- -------------------------
                        Field1                     9                    02 - Field1              VARCHAR(10)             
                        Field2                     9                    03 - Field2              VARCHAR(12)             
                        Field3                     9                    04 - Field3              VARCHAR(11)             
                        Field4                     9                    05 - Field4              VARCHAR(16)             
                        Field5                     9                    06 - Field5              VARCHAR(5)              possible field with error
                        Field6                     9                    07 - Field6              VARCHAR(1)              possible field with error
                        Field7                     9                    08 - Field7              VARCHAR(1)              possible field with error
                        Field8                     9                    09 - Field8              VARCHAR(6)              possible field with error
                        Field9                     9                    10 - Field9              VARCHAR(6)              possible field with error
                        Field10                    9                    11 - Field10             VARCHAR(50)             
                        Field11                    9                    12 - Field11             VARCHAR(50)             
                        Field12                    9                    13 - Field12             VARCHAR(50)             
                    ====================================================================================================
    ------------------------------------------------------------------------------------------------------------
    Responsible:    Javier Pardo 
    Date:           October 19/2018
    WB tests:       Javier Pardo 
    ------------------------------------------------------------------------------------------------------------
*/
ALTER PROCEDURE dbo.GetFieldStringTruncate
(
    @SourceTableName AS VARCHAR(255)
    , @TargetTableName AS VARCHAR(255)
)
AS
BEGIN
    BEGIN TRY
        DECLARE @colsUnpivot AS NVARCHAR(MAX),
            @colsUnpivotConverted AS NVARCHAR(MAX),
           @query  AS NVARCHAR(MAX)
        SELECT @colsUnpivot = stuff((
                    SELECT DISTINCT ',' + QUOTENAME(col.NAME)
                    FROM tempdb.sys.tables tab
                    INNER JOIN tempdb.sys.columns col
                        ON col.object_id = tab.object_id
                    INNER JOIN tempdb.sys.types typ
                        ON col.system_type_id = TYP.system_type_id
                    WHERE tab.NAME = @SourceTableName
                    FOR XML path('')
                    ), 1, 1, '')
                ,@colsUnpivotConverted = stuff((
                    SELECT DISTINCT ',' + 'CONVERT(VARCHAR(MAX),' + QUOTENAME(col.NAME) + ') AS ' + QUOTENAME(col.NAME)
                    FROM tempdb.sys.tables tab
                    INNER JOIN tempdb.sys.columns col
                        ON col.object_id = tab.object_id
                    INNER JOIN tempdb.sys.types typ
                        ON col.system_type_id = TYP.system_type_id
                    WHERE tab.NAME = @SourceTableName
                    FOR XML path('')
                    ), 1, 1, '')
        --/programming/11158017/column-conflicts-with-the-type-of-other-columns-in-the-unpivot-list
        IF OBJECT_ID('tempdb..##TablaConMaximos') IS NOT NULL DROP TABLE ##TablaConMaximos
        set @query 
          = 'SELECT u.d AS colname, MAX(LEN(u.data)) as [maximo_largo]
            INTO ##TablaConMaximos
            FROM 
            (
                SELECT ' + @colsUnpivotConverted + '
                FROM ' + @SourceTableName + '
            ) T
            UNPIVOT
             (
                data
                for d in ('+ @colsunpivot +')
             ) u
             GROUP BY u.d'
        PRINT @query
        exec sp_executesql @query;
        ------------------------------------------------------------------------------------------------------------
        SELECT --'Nombre de campo' = RIGHT('00' + ISNULL(CONVERT(VARCHAR,col.column_id),''),2) + ' - ' + col.name + ' '
            --, 'Tipo de campo' = ISNULL(CONVERT(VARCHAR,upper(typ.name)),'') + '(' + ISNULL(CONVERT(VARCHAR,col.max_length),'') + ')'
            [ORIGEN Nombre Campo] = tcm.colname
            , [ORIGEN Maximo Largo] = tcm.maximo_largo
            , [DESTINO Nombre Campo] = DESTINO.[Nombre de campo]
            , [DESTINO Tipo de campo] = DESTINO.[Tipo de campo]
            , [Evaluación] = CASE WHEN DESTINO.maximo_largo < tcm.maximo_largo THEN 'possible field with error' ELSE '' END
            --, * 
        FROM tempdb.sys.tables tab
            INNER JOIN tempdb.sys.columns col
                ON col.object_id = tab.object_id
            INNER JOIN tempdb.sys.types typ
                ON col.system_type_id = TYP.system_type_id
            RIGHT JOIN 
                (
                    SELECT column_id
                        , [Nombre de campo] = RIGHT('00' + ISNULL(CONVERT(VARCHAR,col.column_id),''),2) + ' - ' + col.name + ' '
                        , [Tipo de campo] = ISNULL(CONVERT(VARCHAR,upper(typ.name)),'') + '(' + ISNULL(CONVERT(VARCHAR,col.max_length),'') + ')'
                        , [maximo_largo] = col.max_length
                        , [colname] = col.name
                    FROM sys.tables tab
                        INNER JOIN sys.columns col
                            ON col.object_id = tab.object_id
                        INNER JOIN sys.types typ
                            ON col.system_type_id = TYP.system_type_id
                    WHERE tab.NAME = @TargetTableName
                ) AS DESTINO
                    ON col.name = DESTINO.colname
            INNER JOIN ##TablaConMaximos tcm
                ON tcm.colname = DESTINO.colname
        WHERE tab.NAME = @SourceTableName
            AND typ.name LIKE '%char%'
        ORDER BY col.column_id
    END TRY
    BEGIN CATCH
        SELECT 'Internal error ocurred' AS Message
    END CATCH   
END
現時点では、データ型CHAR、VARCHAR、NCHARおよびNVARCHARのみがサポートされています。このコードの最後のバージョンは、以下の次のリンクで見つけることができ、私たちはお互いにそれを改善するのを助けます。GetFieldStringTruncate.sql
https://gist.github.com/jotapardo/210e85338f87507742701aa9d41cc51d
これは、適切な権限がない場合にも発生する可能性があります
同様の問題がありました。名前を除いて、1つのテーブルから同じテーブルにデータをコピーしていました。
最終的に、SELECT INTOステートメントを使用してソーステーブルを一時テーブルにダンプしました。
SELECT *
INTO TEMP_TABLE
FROM SOURCE_TABLE;
ソーステーブルのスキーマを一時テーブルと比較しました。varchar(4000)期待していたときに、列の1 つがであることがわかりましたvarchar(250)。  
更新:興味がある場合は、varchar(4000)の問題をここで説明できます。
Nvarchar(Max)の場合、TSQLで4000文字しか取得できません。
お役に立てれば。
次のコードを試してください:
CREATE TABLE [dbo].[Department](
    [Department_name] char(10) NULL
)
INSERT INTO [dbo].[Department]([Department_name]) VALUES  ('Family Medicine')
--error will occur
 ALTER TABLE [Department] ALTER COLUMN [Department_name] char(50)
INSERT INTO [dbo].[Department]([Department_name]) VALUES  ('Family Medicine')
select * from [Department]