Безопасно ли преобразование типов во внутреннем объединении, если оно зависит от фильтрации данных / строк? - PullRequest
1 голос
/ 28 июня 2019

Если условие соединения выполняет преобразование данных, которое допустимо только для некоторых строк, но ваше условие where фильтрует строки по «действительным» строкам, это «безопасное» условие соединения?

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

Я пытался это найти, но ничего конкретного не видел

SELECT *
  FROM (SELECT 1 AS ID) a
       JOIN (SELECT '1' AS ID,
                    'Y' AS FILTER
             UNION
             SELECT 'NOT_AN_INT' AS ID,
                    'N'          AS FILTER) b
         ON a.ID = CONVERT(INT, b.ID)
 WHERE b.FILTER = 'Y' 


SELECT *
  FROM (SELECT 1 AS ID) a
       JOIN (SELECT '1' AS ID,
                    'Y' AS FILTER
             UNION
             SELECT 'NOT_AN_INT' AS ID,
                    'N'          AS FILTER) b
         ON a.ID = CONVERT(INT, b.ID)
            AND b.FILTER = 'Y' 

Насколько я понимаю, условия соединения должны быть коммутативными при внутреннем соединении, и оба этих запроса должны быть эквивалентны друг другу. Однако второй взрывается из-за проблем приведения типов. Означает ли это, что это плохая практика, и вы должны сделать безопасное преобразование идентификатора a в varchar вместо идентификатора b в int? Или есть какая-то спецификация ANSI, гарантирующая, что это нормально?

1 Ответ

1 голос
/ 28 июня 2019

Нет.SQL не гарантирует, что предложение WHERE выполняется «до» других предложений.Фильтрация может происходить перед другими операциями.Фильтрация может не выполняться.

Это относится и к CTE, и к подзапросам.Оптимизатор SQL может переупорядочивать операции.SQL является описательным языком, а не процедурным языком.Запрос описывает набор результатов, а не то, как он создается.

Ваш код выглядит как код SQL Server.Если это так, просто используйте TRY_CONVERT() вместо CONVERT().Если преобразование завершается неудачно, результатом является NULL, что не удается при большинстве сравнений с WHERE -клазами.

Лично я считаю такое поведение ошибками преобразования типа ошибок в отфильтрованных строках.Я не знаю, есть ли в стандарте SQL спецификации на эту тему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...