Во-первых, позвольте мне сказать, что я полностью знаю, что сервер SQL не оценивает короткое замыкание Он может, если посчитает нужным, из-за плана выполнения, но лучше не догадываться.
Мне интересно, может ли оно быть принудительным в каких-либо конкретных ситуациях, связанных с нулем - например, динамическая загрузка всех клиентов в этом запросе
declare @customerId int
set @customerId = null
select * from customer where ( (@customerId Is Null) Or CustomerId=@customerId)
CustomerId - это PK (int), не обнуляемый
ВОПРОС: Кто-нибудь знает, будет ли двигатель всегда выбирать левую сторону в этом случае или мы действительно закончим проверкой, если CustomerId = null с правой стороны для каждой строки.
Я предполагаю, что это не гарантированно сработает, так как правая часть может быть «менее избирательной», но мне любопытно, если sql-сервер видит нулевое значение и знает в каждом случае, как это, использовать левую часть из-за нулевого значения заявление.
Я считаю, что это лучше всего сделать в качестве примера ниже (если вы можете улучшить запрос ниже, пожалуйста, сделайте!), Но мне просто любопытно в этом случае для целей обучения, если кто-нибудь знает о последовательном внутреннем поведении здесь. Он работает во всех моих случаях, но также является первичным ключом, который не обнуляется, поэтому может быть, это всегда работает. если это обнуляемый тип, то правая часть может быть менее избирательной, чем левая, и мы сейчас имеем дело с другой ситуацией.
Мой план выполнения в обоих запросах выглядит одинаково.
в любом случае - потенциально лучший способ написать это (пожалуйста, улучшите его, если можете)
declare @customerId int
set @customerId = null
select * from Customer
where
case
when @customerId is null then 1
end = 1
or
case
when @customerId is not null then @customerId
else -1
end = CustomerId
Идея заключается в том, чтобы обойти динамический SQL - поэтому я просто хочу убедиться, что я в курсе всех ситуаций.
спасибо!