Функция SQL HASHBYTES возвращает странный вывод при использовании в CASE WHEN/IIF
Я написал хранимую процедуру, которая хэширует значение определенного столбца. Мне нужно использовать эту функцию HASHBYTES в выражении CASE WHEN или IIF, например так:
DECLARE @Hash varchar(255) = 'testvalue'
SELECT IIF(1=1, HASHBYTES('SHA1',@Hash), @Hash)
SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) END AS Hashcolumn
Я не могу понять, почему я получаю разные результаты из вышеупомянутых запросов? кажется, что всякий раз, когда я добавляю ELSE в оператор CASE WHEN / IIF, он возвращает строку странных символов (например, ü<þ+OUL'RDOk{\Ìø
в приведенном выше примере).
Может кто-нибудь сказать мне, почему это происходит? Мне нужно использовать ДЕЛО КОГДА или IIF.
Спасибо, парни
2 ответа
IIF
возвращает тип данных с наивысшим приоритетом из типов в true_value и false_value. В этом случае это @Hash1
который varchar(255)
так что ваш результат будет приведен к varchar(255)
, Увидеть ниже.
DECLARE @Hash varchar(255) = 'testvalue'
SELECT cast(HASHBYTES('SHA1',@Hash) as varchar(255))
Так же, CASE
работает так же. Однако, если вы не добавите ELSE
или другой WHEN
это будет конфликтовать с типом данных, это будет работать. Это потому что ELSE NULL
подразумевается. т.е.
SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) END
Тем не менее, если вы добавите еще одну проверку, приоритет вступит в силу, и он будет преобразован.
SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) WHEN 1=2 THEN @Hash END AS Hashcolumn
SELECT CASE WHEN 1=1 THEN HASHBYTES('SHA1',@Hash) ELSE @Hash END AS Hashcolumn
Результатом запроса выбора является виртуальная таблица. В реляционном БД столбец таблицы ограничен одним типом данных... поэтому здесь происходит неявное преобразование, выполняемое порядком ядра сервера для рендеринга типа sigle, и, следовательно, возвращаются странные символы.
Природа преобразования такова, что @scsimon говорит, что она соответствует наивысшему порядку приоритета.
Следующий запрос должен помочь.
DECLARE @Hash varchar(255) = 'testvalue'
SELECT IIF(1=1, CONVERT(VARCHAR(255),HASHBYTES('SHA1',@Hash),2), @Hash)
SELECT CASE WHEN 1=2 THEN CONVERT(VARCHAR(255),HASHBYTES('SHA1',@Hash),2)
ELSE @Hash END AS Hashcolumn