Справочная информация: я пытался получить случайные «шестнадцатеричные» значения при создании фиктивных данных и придумал такую конструкцию:
SELECT TOP 100
result = (CASE ABS(Binary_Checksum(NewID())) % 16
WHEN -1 THEN 'hello'
WHEN 0 THEN '0'
WHEN 1 THEN '1'
WHEN 2 THEN '2'
WHEN 3 THEN '3'
WHEN 4 THEN '4'
WHEN 5 THEN '5'
WHEN 6 THEN '6'
WHEN 7 THEN '7'
WHEN 8 THEN '8'
WHEN 9 THEN '9'
WHEN 10 THEN 'a'
WHEN 11 THEN 'b'
WHEN 12 THEN 'c'
WHEN 13 THEN 'd'
WHEN 14 THEN 'e'
WHEN 15 THEN 'f'
ELSE 'huh' END)
FROM sys.objects
При запуске этого на моем экземпляре SQL Server 2008 R2 я получаю довольномного «да» записей:
result
------
huh
3
huh
huh
6
8
6
Я действительно не понимаю, почему.Я ожидаю, что произойдет следующее:
- для каждой записи
NewID()
получит новое случайное значение Binary_Checksum()
вычисляет целое число на основеуказанное значение ABS()
делает значение положительным % 16
возвращает остаток от этого положительного значения, если оно будет разделено на 16, которое затем будет значением от 0 до 15 - конструкция
CASE
преобразует значение в соответствующий символ - Поскольку для каждого значения от 0 до 15 существует
WHEN
s, ELSE
никогда не требуется
или, по крайней мере, это то, что я думаю, должно произойти ... но, очевидно, что-то идет не так по дороге ...
При выполнении того же самого в двухступенчатом подходе (черезвременная таблица), да ушли ...
SELECT TOP 100 x = ABS(Binary_Checksum(NewID())) % 16,
result = 'hello'
INTO #test
FROM sys.objects
UPDATE #test
SET result = (CASE x WHEN 0 THEN '0' WHEN 1 THEN '1' WHEN 2 THEN '2' WHEN 3 THEN '3'
WHEN 4 THEN '4' WHEN 5 THEN '5' WHEN 6 THEN '6' WHEN 7 THEN '7'
WHEN 8 THEN '8' WHEN 9 THEN '9' WHEN 10 THEN 'a' WHEN 11 THEN 'b'
WHEN 12 THEN 'c' WHEN 13 THEN 'd' WHEN 14 THEN 'e' WHEN 15 THEN 'f'
ELSE 'huh' END)
SELECT * FROM #test
Кто-нибудь, кто понимает это?Насколько я могу судить, он должен давать один и тот же результат (это действительно копирование-вставка) независимо от того, выполняю ли я это напрямую или через временную таблицу ... Но, очевидно, что-то идет не так, если я делаю это в одном выражении.
PS: мне не нужно «исправлять» для этого, у меня уже есть обходной путь (см. Ниже), я просто надеюсь, что кто-то может объяснить мне, почему это делает то, что он делает.
Обходной путь:
SELECT TOP 100 result = SubString('0123456789abcdef', 1 + (ABS(Binary_Checksum(NewID())) % 16), 1)
FROM sys.objects