2014-09-25 67 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