【发布时间】:2014-05-20 20:05:48
【问题描述】:
当我将随机整数生成与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 值。
【问题讨论】:
-
有趣的是,如果您将
DISTINCT 1 + ABS(CRYPT_GEN_RANDOM(8)%5)移动到子查询中并在CHOOSE中使用该子查询中的列,您不会得到空值。 -
@GSerg 我也注意到了这一点,遗憾的是,我在
SELECT中使用了多个CRYPT_GEN_RANDOM(),每个都会生成一个随机数。即:SELECT 1 + ABS(CRYPT_GEN_RANDOM(8)%5), 1 + ABS(CRYPT_GEN_RANDOM(8)%5), 1 + ABS(CRYPT_GEN_RANDOM(8)%5)我可以在我的 cte 中将其中的一些称为不同的列,但这并不理想。 -
@GoatCO 您需要在“理想”和“按预期”之间进行选择。这就是 SQL Server 的工作方式;无论 SQL Server 的设计是否适合您,您都需要解决它。顺便说一句,我将其标记为重复,因为 CHOOSE() 扩展为 CASE 表达式,因此其行为与 Paul 在副本中描述的完全一样。更多在我的 cmets 下面。
-
@AaronBertrand 同意,知道这是设计使然,无论方便如何,都可以轻松解决它。关于它被标记为重复,虽然链接的答案肯定有帮助,但只有在理解
CHOOSE()和CASE在后端的处理方式完全相同时才会有所帮助。 -
不,他们没有,或者至少他们不应该 - 重复是谷歌果汁。 Background
标签: sql sql-server-2012