Я столкнулся с вводящей в заблуждение ошибкой в SQL Server 2008, и мне интересно, может ли кто-нибудь объяснить, что со мной происходит?
У меня есть хранимая процедура примерно так:
declare @cross_reference table (
context varchar(20) not null
, value1 varchar(10) not null
, value2 varchar(10) not null
)
insert into @cross_reference values ('map', 'from_value', 'to_value')
insert into @cross_reference values ('map', 'from_value', 'to_value')
insert into @cross_reference values ('map', 'from_value_xxxxx', 'to_value_xxxxxxx')
select
t1.field1
, t1.field2
, xref.value2
from table_1 t1
inner join table_2 t2 on t2.id = t1.id
left join @cross_reference xref on xref.context = 'map' and xref.value1 = t2.map_id
Фактическая хранимая процедура более сложна, но суть в этом.
После запуска SP я получаю загрузку выходных строк до того, как появятся ошибки «строка или двоичные данные будут усечены». Конкретные ссылки на строки в ошибке указывали где-то в основном операторе SELECT выше, но после некоторой отладки я обнаружил, что значения, которые я помещал в перекрестную ссылку в начале, были слишком большими, и это исправило это.
Но мои вопросы:
как SQL Server выполнял основной оператор SELECT, не завершив вставку строк перекрестных ссылок? Есть ли какая-то отложенная обработка? Ленивая загрузка табличных переменных?
С какой стати сообщение «строка или двоичные данные будут усечены» не указывает на то, где это происходит на самом деле? Или я делаю это неправильно?
Спасибо, Рэй
РЕДАКТИРОВАТЬ
Я думаю, что это должно быть как-то связано с LEFT JOIN для переменной таблицы и с тем, что ни один из ее столбцов не участвует в предложении WHERE. SQL Server, похоже, оставил подготовку таблицы до тех пор, пока она не понадобится (после завершения ВНУТРЕННИХ СОЕДИНЕНИЙ), и в этот момент произошла ошибка, когда большая часть набора результатов уже готова к SELECT.
Я также заметил, что значения, которые были успешно ВСТАВЛЕНЫ в @cross_reference, действительно отображаются в возвращаемом наборе результатов. В то время как строки, которые не удалось вставить из-за того, что они слишком велики, просто показывают NULL.