2014-09-25 66 views
0

在SQL Server 2005数据库上,一直在工作的存储过程开始失败。在存储过程中下面的语句被确定为故障的原因:没有任何行的UPDATE语句失败

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]; 

该错误消息是

消息8152,级别16,状态2,行1 字符串或二进制数据将是截断。 该声明已被终止。

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

+0

与你的问题无关,但值得注意的是:你有没有试过运行'SELECT IsNumeric('1e6')'? – 2014-09-25 21:38:23

+0

你确定你是'select'语句不返回任何结果?这个小提琴可以工作(http://sqlfiddle.com/#!3/8f26d1/1),但是如果你删除'where'标准,它会导致截断错误。 – sgeddes 2014-09-25 21:41:47

+0

'select IsNumeric('1e6')'returns 1 – 2014-09-26 13:43:53

回答

1

你的问题是真的:“?是什么奇怪的这个错误是select语句不返回任何行为什么会有在更新语句截断错误,没有任何行

第一,当你做转换为varchar你应该总是包括长度:

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

SQL Server有在不同环境下不同的默认长度,所以这可能会导致一个问题。不是你所看到的,而是另一个。

我认为,正在发生的事情是,SQL服务器构建的执行计划的查询,并将其过滤前移动的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,但如果你设置一个合适的值,那么它应该工作。

+0

使用目标列的长度添加转换解决了此问题。 'd.location = cast(a。[Name] +' - '+ cast(a.lLocaId as varchar)as varchar(60))' – 2014-09-26 13:46:36