SQL Server中的函数转换不受影响的情况

时间:2018-12-06 10:19:27

标签: sql sql-server

我尝试如下选择:

CREATE TABLE v_test 
(
    id int,
    name char(4)
);

INSERT INTO v_test
    SELECT 1, NULL
    UNION
    SELECT 2, NULL

SELECT
    id,  
    CASE 
       WHEN name IS NULL
          THEN '   ' 
          ELSE CAST((LEFT(name, 2) + ':' + SUBSTRING(name, 3, 2) + ':00') AS TIME) 
    END AS test,
    name
FROM
    v_test;

SELECT
    id,  
    CASE
       WHEN name IS NULL
          THEN '   ' 
          ELSE '0'
    END AS test,
    name
FROM v_test;

这些查询的结果如下:

enter image description here

您可以看到,在函数转换中不影响结果的情况。有人可以帮我解释一下细节吗?

2 个答案:

答案 0 :(得分:4)

case表达式将仅返回一个type,在您的第一个版本中,您有两个type,一个是varchar,另一个是time

如果我们查看precedence类型,那么time的优先级要高于varchar

因此,您需要进行转换:

select id,  
       (case when name is null 
             then '   ' 
             else cast(CAST((LEFT(name,2)+ ':' + SUBSTRING(name,3,2)+':00') AS TIME) as varchar(255)) 
        end) as test,
       name 
from v_test;

答案 1 :(得分:1)

句子“您可以看到,在函数转换中不受影响的结果情况。” 恐怕没有任何意义。我认为您要问的是为什么值' '显示为00:00:00.0000000

根据文档CASE (Transact-SQL) - Return Types

  

从以下类型的集合中返回最高优先级类型   result_expressions和可选的else_result_expression。欲了解更多   信息,请参阅Data Type Precedence (Transact-SQL)

如果我们也参考上面的链接文档,这将提供(当前)数据类型优先级:

  

SQL Server对数据类型使用以下优先顺序:

     
      
  1. 用户定义的数据类型(最高)
  2.   
  3. sql_variant
  4.   
  5. xml
  6.   
  7. datetimeoffset
  8.   
  9. datetime2
  10.   
  11. 日期时间
  12.   
  13. smalldatetime
  14.   
  15. 日期
  16.   
  17. 时间
  18.   
  19. 浮动
  20.   
  21. 真实
  22.   
  23. 十进制
  24.   
  25. 金钱
  26.   
  27. 小钱
  28.   
  29. bigint
  30.   
  31. int
  32.   
  33. smallint
  34.   
  35. tinyint
  36.   
  37.   
  38. ntext
  39.   
  40. 文本
  41.   
  42. 图片
  43.   
  44. 时间戳
  45.   
  46. uniqueidentifier
  47.   
  48. nvarchar(包括nvarchar(max))
  49.   
  50. nchar
  51.   
  52. varchar(包括varchar(max))
  53.   
  54. char
  55.   
  56. varbinary(包括varbinary(max))
  57.   
  58. 二进制(最低)
  59.   

请注意,time的优先级比varchar高得多,因此您的值' '被隐式转换为timeCONVERT(time,' ') = '00:00:00.0000000'