背景:私はダミーデータを作成しながら、いくつかのランダムな「進」の値を取得しようと、この建設を思い付いた:奇妙な行動
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()
が正の値になるとに基づいて、INTを計算% 16
は、16で除算される場合、その正の値の残りの部分を返します。0から15までの値になります。- th
WHEN
sが、ELSE
が少なくとも
かを必要とするべきではありません0と15の間のすべての値のためにそこにあるので、電子CASE
建設は、関連する文字
...
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
これを理解している人は誰ですか?限り、私はそれを直接または一時テーブルを介してそれに関係なく、私はそれが同じ結果(それは実際にコピー貼りです)を与える必要があると言うことができます...しかし、明らかに何かが間違って行く私は1つのステートメントでそれを行う。
PS:これには「修正」は必要ありません。私はすでに回避策を講じています(下記参照)。
回避策:
SELECT TOP 100 result = SubString('abcdef', 1 + (ABS(Binary_Checksum(NewID())) % 16), 1)
FROM sys.objects
PS:面白い可能性のあるSQL Serverの異なるバージョンで誰かがこれをテストできたら... – deroby
あなたの回避策はオリジナルよりも簡潔に見えます... – Russell
この男を説明するThx ... Damiensの回答これにつまずく可能性のある人にとってはもう少し冗長であるからです。 (そして、彼は一番上に1分速かった= P) – deroby