将数据从一个表插入另一个数据将被截断

时间:2016-11-19 02:55:33

标签: sql sql-server

我将数据从一个表插入到另一个表中,新表结构主要是从旧表中派生出来的几个新列,当我运行我的查询时出现错误:

  

字符串或二进制数据将被截断。

我的插入查询中的值来自一个返回70,000行的select语句,因此我不知道如何找出导致错误的数据,有什么办法可以找到吗?

2 个答案:

答案 0 :(得分:2)

目标表中的一个或多个列的类型不是 wide 足以包含源表中的数据,源表列具有其中的数据比目标列可以包含的数据宽。

例如,源表的列X的类型为NVARCHAR(200),并且您尝试将其复制到类型为{{1}的目标表列Y }。源表中至少有一行,NVARCHAR(100)的值大于100个字符。复制该列会丢失您的数据并导致您获得相同的错误。

您需要做的是:

  • 更改目标表中不够宽的列类型
  • 明确是否有数据丢失,并明确使用X。例如,我之前提供的示例CAST

示例:

CAST(X AS VARCHAR(100))

答案 1 :(得分:0)

这是一个轻量级检查(仅限元数据),可以将搜索范围缩小到可能导致问题的列列表 -
目标表中max_length小于源查询中匹配表达式的max_length的列。

根据源查询的结果创建一个空表并比较元数据。

示例:

create table src (str1 varchar(11),str2 varchar(3));
create table trg (str1 varchar(7),str2 varchar(3));    
insert into src values ('Hi','XY'),('Hello world','XY'),('Hi','XYZ')
insert into trg (str1,str2) select str1,str2 + 'D' from src 
  

Msg 8152,Level 16,State 14,Line 10
  字符串或二进制数据将被截断。

select  str1,str2+'D' as str2 into tmp from src where 1=2;
select      *

from       (select      c.name
                       ,min(case o.name when 'tmp' then t.name end)         as tmp_type
                       ,min(case o.name when 'trg' then t.name end)         as trg_type
                       ,min(case o.name when 'tmp' then c.max_length end)   as tmp_max_length
                       ,min(case o.name when 'trg' then c.max_length end)   as trg_max_length

            from                    sys.objects as o
                        join        sys.columns as c
                        on          c.object_id         = o.object_id
                        join        sys.types   as t
                        on          t.system_type_id    = c.system_type_id
                                and t.user_type_id      = c.user_type_id

            where       o.name in ('tmp','trg')
                    and (   c.collation_name is not null 
                        or  c.name in ('binary','varbinary')
                        )

            group by    c.name
            ) c

where       tmp_max_length >  trg_max_length

order by    c.name
;
+------+----------+----------+----------------+----------------+
| name | tmp_type | trg_type | tmp_max_length | trg_max_length |
+------+----------+----------+----------------+----------------+
| str1 | varchar  | varchar  | 11             | 7              |
+------+----------+----------+----------------+----------------+
| str2 | varchar  | varchar  | 4              | 3              |
+------+----------+----------+----------------+----------------+