Вызов функции из оператора select - SQL - PullRequest
1 голос
/ 13 мая 2009

У меня есть следующее утверждение:

SELECT CASE WHEN (1 = 1) THEN 10 ELSE dbo.at_Test_Function(5) END AS Result 

Я просто хочу подтвердить, что в этом случае функция не будет выполнена?

Моя причина для того, чтобы спросить, заключается в том, что функция работает особенно медленно, и если критерии верны, я хочу избежать вызова функции ...

Приветствие Anthony

Ответы [ 4 ]

4 голосов
/ 13 мая 2009

Ваше предположение верно - оно не будет выполнено. Я понимаю вашу озабоченность, но конструкция CASE в этом смысле «умна» - она ​​не оценивает никаких условий после первого действительного условия. Вот пример, чтобы доказать это. Если обе ветви этого оператора case будут выполнены, вы получите ошибку «деление на ноль»:

SELECT  CASE
                WHEN 1=1 THEN 1
                WHEN 2=2 THEN 1/0
            END AS ProofOfConcept

Имеет ли это смысл?

3 голосов
/ 13 мая 2009

Не делайте этого предположения, оно НЕПРАВИЛЬНО . Оптимизатор запросов совершенно свободен в выборе порядка оценки, который ему нравится, и SQL как язык НЕ предлагает короткое замыкание оператора. Даже если в ходе тестирования вы можете обнаружить, что функция никогда не оценивается, в процессе работы вы можете время от времени сталкиваться с условиями, которые заставляют сервер выбирать другой план выполнения и сначала оценивать функцию, а затем остальную часть выражения. Типичный пример - когда сервер замечает, что возвращаемая функция является детерминированной и не зависит от данных строки, в этом случае он сначала оценит функцию, чтобы получить значение, и после , который начинает сканирование таблицы и оцените критерии включения WHERE, используя предварительно определенное значение функции.

0 голосов
/ 13 мая 2009

Поместите WaitFor Delay '00:00:05' в функцию. Если инструкция возвращается немедленно, она не выполняется, если для возврата требуется 5 секунд, то она была выполнена.

0 голосов
/ 13 мая 2009

Если вы проводите какое-то тестирование ... Если вы пытаетесь избежать функции at_Test_Function, почему бы просто не закомментировать ее и не сделать

SELECT 10 AS Result
...