Похоже, что с поля, в котором я делаю хэшбайты, является 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
Вы неправильно поняли. 8000 символов не проблема. Файлы MY тестовых данных имеют ограничение только 1k или 2k, но, тем не менее, поскольку столбец определяется как varchar (max), он выдает эту ошибку. Столбец определяется как varchar (max), потому что в будущем мы можем или не можем иметь более крупные файлы, и мы отправимся на SQL Server 2016. – John
@John Да, я неправильно понял, но это из-за того, что вы заявляете в вопросе " _ASCII текстовый файл многих K_ "_and_ ошибка, которую вы описываете, не представляется возможной, учитывая детали, которые вы только что разъяснили в комментарии выше. Я обновил свой ответ, чтобы добавить пример в конце, показывающий, что это работает. Как я, так и документация, укажите: вывод 'HASHBYTES' всегда' VARBINARY (8000) '. Также невозможно получить ошибку усечения из возвращаемого значения в простой инструкции SELECT. Возвращаемое значение может получить только ошибку усечения при вставке в поле, меньшее, чем заданное значение. –