Функция 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
Другие вопросы по тегам