Функция SQL HASHBYTES возвращает странный вывод при использовании в CASE WHEN / IIF - PullRequest
0 голосов
/ 08 мая 2018

Я написал хранимую процедуру, которая хэширует значение определенного столбца. Мне нужно использовать эту функцию 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 ]

0 голосов
/ 08 мая 2018

Результатом запроса выбора является виртуальная таблица. В реляционной базе данных столбец таблицы ограничен одним типом данных ... так что здесь происходит неявное преобразование, выполняемое механизмом ядра сервера для рендеринга типа 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
0 голосов
/ 08 мая 2018

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 
...