更新语句失败,没有任何行

时间:2014-09-25 21:34:19

标签: sql sql-server-2005

在SQL Server 2005数据库上,一直运行失败的存储过程。存储过程中的以下语句被确定为失败的原因:

update d set
d.location=a.[Name]+'-'+cast(a.lLocaId as varchar)
--select d.logical_name,d.location,a.[Name]+'-'+cast(a.lLocaId as varchar) as location
from hpsmp.dbo.device2m1 d
inner join hpsmp.dbo.locm1 s
on d.location=s.location
inner join hpamp.dbo.amLocation a
on s.location_code=a.lLocaId
where isnumeric(s.location_code)=1
and s.location_name<>a.[Name];

错误消息是

Msg 8152,Level 16,State 2,Line 1 字符串或二进制数据将被截断。 声明已经终止。

这个错误的奇怪之处在于select语句没有返回任何行。为什么在没有任何行的更新语句中会出现截断错误?这张桌子上没有触发器。

1 个答案:

答案 0 :(得分:1)

你的问题确实是:“这个错误的奇怪之处在于select语句没有返回任何行。为什么在没有任何行的update语句中会出现截断错误?”< / p>

首先,当你转换为varchar时,总是包含一个长度:

set d.location = a.[Name] + '-' + cast(a.lLocaId as varchar(255))

SQL Server在不同的上下文中具有不同的默认长度,因此这可能会导致问题。不是你看到的那个,而是另一个。

我相信发生的事情是SQL Server为查询构建执行计划,并在过滤之前移动location 的新值的计算。换句话说,它可以在读取hpamp.dbo.amLocation时进行计算,因为这是新值所需的唯一表格。

然后,即使在未更新的行上也会出错。

这是一个猜测,但SQL Server确实在其他地方表现出这种行为。当你这样做时,一个臭名昭着的问题就是出错:

select cast(col as datetime)
from table t
where isdate(col) = 1;

是的,这也会因无效日期和同样的原因而产生错误。

在您的情况下,我不确定解决问题的最佳方法是什么。你可以尝试类似的东西:

set d.location = (case when len(a.name) < 8 then a.[Name] + '-' + cast(a.lLocaId as varchar(255)) end)

我编号为8,但是如果你设置了一个合适的值,那么它应该有效。