选择()不按预期工作

时间:2014-05-20 20:05:48

标签: sql sql-server-2012

当我将随机整数生成与CHOOSE()结合使用时,我得到了意外的NULL值。

以下内容只应返回a - e字母,而NULL也包含在值中:

查询:

;WITH cte AS (SELECT 1 RN
              UNION  ALL 
              SELECT RN + 1 
              FROM cte
              WHERE RN < 100)
SELECT DISTINCT CHOOSE(1 + ABS(CRYPT_GEN_RANDOM(8)%5),'a','b','c','d','e','f')
FROM cte

结果:

NULL
a
b
c
d
e

预期结果:

a
b
c
d
e

随机数生成按预期工作,仅返回值1-5:

;WITH cte AS (SELECT 1 RN
              UNION  ALL 
              SELECT RN + 1 
              FROM cte
              WHERE RN < 50)
SELECT 1 + ABS(CRYPT_GEN_RANDOM(8)%5)
FROM cte

演示:SQL Fiddle

CHOOSE()的工作原理如下(索引从1开始):

SELECT CHOOSE(3,'dog','cat','horse','fish')  
-- horse
SELECT CHOOSE(8,'dog','cat','horse','fish')  
-- NULL

在函数中使用随机数生成适用于LEFT()RIGHT()CHAR()等。 解决方法没问题,但我很好奇为什么我会得到NULL值。

1 个答案:

答案 0 :(得分:1)

这很奇怪,可能属于错误类别。当然,你所做的是奇怪的,因为你将一个随机的位模式视为一个数字。应该是有效的,但可能会产生意想不到的后果。并且,这不是溢出问题。它与8的其他值一起出现。

见证以下内容(在SQL Fiddle上):

WITH cte AS (SELECT 1 RN
              UNION  ALL 
              SELECT RN + 1 
              FROM cte
              WHERE RN < 100)
SELECT  CHOOSE(1 + ABS(n),'a','b','c','d','e','f'),
        CHOOSE(1 + abs(CRYPT_GEN_RANDOM(8)%5),'a','b','c','d','e','f')
FROM (select abs(CRYPT_GEN_RANDOM(8)%5) as n
      from cte
     ) n
order by 1

第一列是从不 NULL。第二列定期NULL。换句话说,如果将值赋给另一个变量,则会有所不同。我可以想象一些8字节大整数的模式代表NaN,但并不是说这种情况发生了太多。

鉴于它在直接调用时失败但在有中间变量时起作用,我得出的结论是这可能是某种错误。我想知道它是否在某处记录。