我插入数据从一个表到另一个,新的表结构主要是从旧表与几个新的列,当我运行我的查询我得到的错误:从一个表插入数据到另一个数据将被截断
String or binary data would be truncated.
我插入查询中的值来自一个SELECT语句返回70000行,所以我不知道如何找出什么样的数据导致了错误,有没有办法找出?
我插入数据从一个表到另一个,新的表结构主要是从旧表与几个新的列,当我运行我的查询我得到的错误:从一个表插入数据到另一个数据将被截断
String or binary data would be truncated.
我插入查询中的值来自一个SELECT语句返回70000行,所以我不知道如何找出什么样的数据导致了错误,有没有办法找出?
这是一个轻量级的检查(仅元数据),以缩小搜索到可能导致问题的列的列表 -
列其中靶表中的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
String or binary data would betruncated.
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 |
+------+----------+----------+----------------+----------------+
目标表中的一个或多个列的类型不是宽足以包含来自源表的数据,和源表列中的数据比其中的数据更宽目标列可以包含。
例如源表有一栏X
是NVARCHAR(200)
类型和你想的是复制到目标表列Y
是NVARCHAR(100)
类型。源表中至少有一行,其值为X
,宽度大于100个字符。复制该列会丢失数据,并且会导致出现相同的错误。
你需要做的是两种:
CAST
明确地类型的列。例如我之前给出的例子,CAST(X AS VARCHAR(100))
。实施例:
DECLARE @s TABLE(x NVARCHAR(20));
INSERT INTO @s(x)VALUES(N'123456789'); -- data in source column wider than what the target column can contain
DECLARE @t TABLE(y NVARCHAR(10)); -- target column is less wide than source column
INSERT INTO @t(y) SELECT x FROM @s; -- this statement will fail with the same error as you have
INSERT INTO @t(y) SELECT CAST(x AS NVARCHAR(10)) FROM @s; -- this statement succeeds, only use if data loss is intended
这不回答OP问题。他不是问为什么他得到这个错误,而是如何找到导致这个错误的数据。 –
@DuduMarkovitz我要说的是,他不应该首先寻找导致错误的数据。他应该改变自己的工作方式:或者让目标表的列至少与源文件一样宽,或者在数据丢失的情况下进行明确的转换。因为一旦他运行一个脚本来找到罪魁祸首的列/数据,他会做什么? –
@DuduMarkovitz虽然=)不要误解我的意思,但你确实有一点。但是你的答案是“找出导致错误的数据”*? –
上有SO一些其它问题:http://stackoverflow.com/questions/6388756/sql-server-string-or-binary-data-would -be截断。你也可以看看这里:http://blogs.lessthandot.com/index。php/datamgmt/datadesign/how-to-find-what-column/ – Klinger