sql-server – CASE构造的奇怪行为
|
背景:我试图在创建虚拟数据时获得一些随机的“十六进制”值,并提出了这种结构: 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()都会出现一个新的随机值 或者至少,这就是我认为应该发生的事情……但显然在路上出了问题…… 当用两步法(通过临时表)做同样的事情时,哼哼…… 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
解决方法我相信,与 simple CASE expression的描述相反,它实际上为每个input_expression = when_expression比较重新评估input_expression(这通常是安全的,除非在这种情况下,在input_expression中有一个非确定性函数)所以,会发生的事情是,每次比较时它会在0到15之间产生不同的随机数,如果在16次评估/比较之后,它从未生成匹配的数字,那么就会出现问题. 这不会产生什么: SELECT TOP 100
result = (CASE ABS(Binary_Checksum(Value)) % 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 (select NewID() as Value,* from sys.objects ) so (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- SQL Server 数据类型转换的简单示例
- linq-to-sql – 实体类从LINQ到SQL提供者解耦实现
- sql-server – 不能在“插入”和“删除”表中使用
- SQL Server CREATE FUNCTION sqlserver用户定义函
- sql-server – 如何便宜地确定列是否只包含NULL记
- mysql中取系统当前时间,当前日期方便查询判定的
- SQL Server 复合查询条件(AND,OR,NOT)对NULL值的
- sql-server – SQL Server 2008 R2 Varbinary Ma
- sql – 如何选择两个日期之间的所有小时数?
- SQL Server 交叉表查询 case
