计算列的数据类型是啥?

Posted

技术标签:

【中文标题】计算列的数据类型是啥?【英文标题】:What is the data type of a computed column?计算列的数据类型是什么? 【发布时间】:2012-09-15 06:43:50 【问题描述】:

当您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 如何决定该列的数据类型?

【问题讨论】:

【参考方案1】:

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

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

在这种情况下,Active1INT(4 字节),而 Active2BIT(1 字节 - 或更少,如果它与其他 BIT 列相邻,则可能更少)。

【讨论】:

如果你想维护一个非空合约,你必须将整个东西包裹在 ISNULL( [CONVERT(..)], 0) 中,尽管 1 或 0 永远不会为空。 @Joe 除了 SSMS 脆弱的设计师所展示的东西之外,它还有什么不同?您可以在实际表中获取非 NULL 的唯一方法是,如果有人修改了计算列定义(在这种情况下,他们很可能会删除 ISNULL() 包装器,因为这对他们来说可能不合逻辑它首先就在那里)。 不确定,也许对于某些使用 EF 将架构拉入 EDMX 的人来说。在我的情况下(代码优先 + 迁移 + 位计算),我需要添加 CONVERT/CAST,因为在输入数据后,EF 哭着试图从 INT 设置布尔值。一下子我添加了外部 ISNULL,所以我不确定它是否同样会抱怨可空性。大概不会,因为它似乎是类型推断(而且它永远不会为空),但也许其他人会发现它很有用。我也不会想到 EF 会抱怨将 1/0 设置为 bool ..【参考方案2】:

对于CASE 表达式,它是带有highest datatype precedence 的分支。在您的示例中,所有三个分支都是在将被解释为整数的范围内的文字,因此列的类型将为 int

您可以使用sql_variant_property 来确定文字表达式是什么数据类型as per my answer here。例如2147483648 被解释为numeric(10,0) 而不是bigint

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

【讨论】:

像往常一样高质量的回答马丁。并祝贺你打破 6 位数(在我看到你的下一条评论之前你会的)。想想我们在 2 年前就差不多了 :) 时间过得真快。 @Richardakacyberkiwi - 谢谢!是的,我记得你在我之前通过了 20K。真的是两年前吗?时光荏苒!

以上是关于计算列的数据类型是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中使用 SQLsave 创建的表的列的数据类型是啥

IDentity 是啥意思

如何控制计算列的数据类型?

Sybase 中神秘的“时间戳”数据类型是啥?

Laravel Schema 中的 MySQL 数据类型 SET 等价物是啥?

如何在单个查询中计算不同类型列的流数据帧的统计信息?