我参与了一个数据迁移项目。当我试图将数据从一个表插入到另一个表(SQL Server 2005)时,我得到以下错误:

编号8152,16层,状态13,1线 字符串或二进制数据将被截断。

源数据列与数据类型匹配,并且在目标表列的长度定义内,因此我不知道是什么原因导致了这个错误。


当前回答

我今天遇到了这个问题,在我搜索这个信息量最小的错误消息的答案时,我还发现了这个链接:

https://connect.microsoft.com/SQLServer/feedback/details/339410/please-fix-the-string-or-binary-data-would-be-truncated-message-to-give-the-column-name

所以微软似乎没有计划在短时间内扩展错误信息。

所以我转向了其他方法。

我把错误复制到excel中:

(1行受影响)

(1行受影响)

(1行受影响) 编号8152,16层,14号状态,13行 字符串或二进制数据将被截断。 声明已终止。

(1行受影响)

计算excel中的行数,接近导致问题的记录计数器…调整我的导出代码打印出SQL接近它…然后运行5 - 10个SQL插入问题SQL,并设法查明问题之一,看到字符串太长,增加该列的大小,然后大导入文件运行没有问题。

这是一种破解和变通方法,但当你别无选择时,你只能做你能做的。

其他回答

当您没有足够的权限时,也会发生这种情况

这可能是一个具有挑战性的错误。以下是AmirCharania在https://connect.microsoft.com/SQLServer/feedback/details/339410/网站上发表的评论。

我调整了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)

如果你使用的是SQL Server 2016-2017: 要修复此问题,请打开跟踪标志460

DBCC TRACEON(460, 1);
GO

确保你在以下情况下将其关闭:

DBCC TRACEOFF(460, 1);
GO

问题很简单:源查询中的一个或多个列包含的数据超过了目标列的长度。一个简单的解决方案是使用源查询并在每一列上执行Max(Len(source col))。也就是说,

Select Max(Len(TextCol1))
    , Max(Len(TextCol2))
    , Max(Len(TextCol3))
    , ...
From ...

然后将这些长度与目标表中的数据类型长度进行比较。至少有一个超出了其目标列的长度。

如果你绝对肯定情况不应该是这样,也不关心是不是这样,那么另一个解决方案是强制强制转换源查询列到它们的目标长度(这将截断任何太长的数据):

Select Cast(TextCol1 As varchar(...))
    , Cast(TextCol2 As varchar(...))
    , Cast(TextCol3 As varchar(...))
    , ...
From ...

请尝试以下代码:

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]