21

当您CREATE TABLE使用CASE表达式创建计算列时,您没有显式定义此列的数据类型:

CREATE TABLE OrderDetail
( OrderID INT
, ProductID INT
, Qty INT
, OrderDate DATETIME
, ShipDate DATETIME
, STATUS AS CASE
       WHEN shipdate is NULL AND orderdate < DATEADD( dd, -7, GETDATE()) THEN 3 
       WHEN shipdate is NOT NULL THEN 2 
       ELSE 1
   end
 )
GO

SQL Server 如何决定该列的数据类型?

4

2 回答 2

27

另外,如果你想强制一个特定的数据类型而不是依赖于数据类型的优先级,你可以在计算中使用CONVERTorCAST来强制它(假设所有潜在的结果都与你选择的类型兼容)。这在默认情况下最终得到比预期更宽的数据类型的情况下非常有用;我见过的最常见的用例是当你最终得到一个 INT 而不是一个 BIT 时:

Active1 AS CASE WHEN something THEN 1 ELSE 0 END,
Active2 AS CONVERT(BIT, CASE WHEN something THEN 1 ELSE 0 END)

在这种情况下Active1是一个INT(4 个字节),Active2而是一个BIT(1 个字节 - 或更少,如果它与其他BIT列相邻)。

于 2012-09-23T17:13:46.580 回答
16

对于CASE表达式,它是具有最高数据类型优先级的分支。在您的示例中,所有三个分支都是在将被解释为整数的范围内的文字,因此列的类型将是int

根据我在此处的回答,您可以使用sql_variant_property来确定文字表达式的数据类型。eg被解释为而不是.2147483648numeric(10,0)bigint

在问题中的情况下,SQL Server 认识到结果列将是NOT NULL但通常对于计算表达式,有必要将表达式包装在 anISNULL中以获得该效果。

于 2012-09-23T17:09:39.280 回答