2014-09-25 3 views
0

В базе данных 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, уровень 16, состояние 2, строка 1 Строка или двоичные данные будут усеченный. Заявление было прекращено.

Что странно в этой ошибке, так это то, что оператор select не возвращает никаких строк. Почему в инструкции обновления может быть ошибка усечения без каких-либо строк? На этой таблице нет триггеров.

+0

Не связано с вашей проблемой, но стоит отметить: вы когда-нибудь пытались запустить 'SELECT IsNumeric ('1e6')'? –

+0

Вы уверены, что вы 'select', оператор не возвращает никаких результатов? Эта скрипка работает (http://sqlfiddle.com/#!3/8f26d1/1), но если вы удалите критерии 'where', это приведет к ошибке усечения. – sgeddes

+0

'select IsNumeric ('1e6')' возвращает 1 –

ответ

1

Ваш вопрос действительно: «? Что странно, об этой ошибке, что оператор выбора не возвращает ни одной строки, почему бы там быть ошибка усечения в операторе обновления без каких-либо строк»

Первый , когда вы делаете преобразование в 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, но если установить соответствующее значение, то он должен работать.

+0

. Добавление роли с использованием длины столбца адресата разрешило эту проблему. 'd.location = cast (a. [Name] + '-' + cast (a.lLocaId как varchar) как varchar (60))' –

Смежные вопросы