2016-07-30 4 views
4

Использование SQL Server 2014 У меня есть таблица, в которой есть столбец nvarchar(max) с именем [ASCII File], который может содержать текстовый файл ASCII для многих K. Затем я хочу сделать хэш-файл MD5 в этом файле, и результирующий хеш всегда должен быть 20 байтов.SQL Server 2014 Hashbytes из nvarchar (max) результат nvarchar (max)

Ну, когда я делаю выбор из hashbytes('MD5', [ASCII File]) я получаю запрос с ошибками

Msg 8152, уровень 16, состояние 10, строка 4
Строка или двоичные данные будут усечены.

Я получаю такое же сообщение, когда я пытаюсь

left(hashbytes('MD5', [ASCII File]), 50) 

Я получаю такое же сообщение, когда я пытаюсь

convert(varchar(50), hashbytes('MD5', [ASCII File])) 

Похоже, так как колонки я делаю hashbytes на это nvarchar(max) , результатом функции hashbytes также является nvarchar(max).

Можете ли вы рассказать мне, как я могу получить результат в ожидании 20 долгих, а не что-то такое долгое время, которое нужно усечь?

ответ

8

Похоже, что с поля, в котором я делаю хэшбайты, является nvarchar (max), результат хэш-байт - nvarchar (max).

Нет, это не представляется возможным, тем более, что возвращаемое значение HASHBYTES является VARBINARY. Кроме того, поскольку ваши тесты были просто операторами SELECT, а не инструкцией INSERT, для возвращаемого значения невозможно получить ошибку усечения. Ошибка усечения исходит от значения . Как указано на этой связанной странице MSDN для HASHBYTES (для SQL Server 2012 и 2014):

Допустимые входные значения ограничены 8000 байтами. Выход соответствует стандарту алгоритма: 128 бит (16 байт) для MD2, MD4 и MD5; 160 бит (20 байтов) для SHA и SHA1; 256 бит (32 байта) для SHA2_256 и 512 бит (64 байта) для SHA2_512.

Это действительно говорит все: вход ограничен 8000 байтами, а выход представляет собой фиксированное количество байтов на основе указанного алгоритма.

Обновленная документация для SQL Server 2016 (который снял ограничение 8000 байт), утверждает:

Для SQL Server 2014 и выше, допустимые значения входных ограничены до 8000 байт.

Вы можете запустить простой тест:

DECLARE @Test NVARCHAR(MAX) = REPLICATE(CONVERT(NVARCHAR(MAX), N't'), 50000); 
SELECT LEN(@Test); 
SELECT HASHBYTES('MD5', @Test); 

возвращений:

50000 

Msg 8152, Level 16, State 10, Line 3 
String or binary data would be truncated. 

Если вы хотите передать в более чем 8000 байт в хэш-функции в версии SQL Server предварительного до 2016, тогда вам нужно использовать SQLCLR. Вы можете написать свою собственную функцию, или вы можете скачать и установить бесплатную версию библиотеки SQL# SQLCLR (который я создал), и использовать Util_Hash и Util_HashBinary функции:

DECLARE @Test NVARCHAR(MAX) = REPLICATE(CONVERT(NVARCHAR(MAX), N't'), 50000); 
SELECT LEN(@Test); 
SELECT SQL#.Util_Hash('MD5', CONVERT(VARBINARY(MAX), @Test)); 
SELECT SQL#.Util_HashBinary('MD5', CONVERT(VARBINARY(MAX), @Test)); 

Возвраты:

50000 
40752EB301B41EEAEB309348CE9711D6 
0x40752EB301B41EEAEB309348CE9711D6 

UPDATE

В случае использования VARCHAR(MAX) столбца или переменной, но с 8000 или меньшим количеством символов (или в NVARCHAR(MAX) колонке или переменной с 4000 или менее символов), то не будет никакой проблемы, и все будет работать, как ожидалось:

DECLARE @Test VARCHAR(MAX) = REPLICATE('t', 5000); 
SELECT LEN(@Test) AS [Characters], 
     HASHBYTES('MD5', @Test) AS [MD5]; 
Возвращает:

5000 0x6ABFBA10B49157F2EF8C85862B6E6313 
+0

Вы неправильно поняли. 8000 символов не проблема. Файлы MY тестовых данных имеют ограничение только 1k или 2k, но, тем не менее, поскольку столбец определяется как varchar (max), он выдает эту ошибку. Столбец определяется как varchar (max), потому что в будущем мы можем или не можем иметь более крупные файлы, и мы отправимся на SQL Server 2016. – John

+1

@John Да, я неправильно понял, но это из-за того, что вы заявляете в вопросе " _ASCII текстовый файл многих K_ "_and_ ошибка, которую вы описываете, не представляется возможной, учитывая детали, которые вы только что разъяснили в комментарии выше. Я обновил свой ответ, чтобы добавить пример в конце, показывающий, что это работает. Как я, так и документация, укажите: вывод 'HASHBYTES' всегда' VARBINARY (8000) '. Также невозможно получить ошибку усечения из возвращаемого значения в простой инструкции SELECT. Возвращаемое значение может получить только ошибку усечения при вставке в поле, меньшее, чем заданное значение. –

1

предел длины входного 8000 байт для функции HASHBYTES (Transact-SQL) удаляется в SQL 2016

на основе алгоритма ниже являются й e размер выходных данных 128 бит (16 байт) для MD2, MD4 и MD5; 160 бит (20 байтов) для SHA и SHA1; 256 бит (32 байта) для SHA2_256 512 бит (64 байта) для SHA2_512.

4

В SQL Server 2016 у нас больше нет проблемы с длиной входного параметра для функции HASHBYTES.

DECLARE @Test NVARCHAR(MAX); 
SET @Test = REPLICATE(CONVERT(NVARCHAR(MAX), N't'), 50000000); 
SELECT LEN(@Test); 
SELECT HASHBYTES('SHA2_512', @Test); 

HASHBYTES (Transact-SQL)

Смежные вопросы