Sql 计算列的数据类型是什么?

Sql 计算列的数据类型是什么?,sql,sql-server,calculated-columns,Sql,Sql Server,Calculated Columns,当您使用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 WH

当您使用
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
创建表OrderDetail
(OrderID INT)
,ProductID INT
,数量整数
,OrderDate日期时间
,发货日期时间
,情况如何
当shipdate为NULL且orderdate

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

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

您可以使用
sql\u variant\u property
确定文本表达式的数据类型。e、 g.
2147483648
被解释为
numeric(10,0)
而不是
bigint


在问题中,SQL Server认识到结果列将为
非空
,但对于计算表达式,通常需要将表达式包装为
ISNULL
,以获得该效果。

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

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
是一个
(如果它与其他
列相邻,则可能是1个字节或更少)。

像往常一样回答质量问题。恭喜你突破了6位数(在我看到你的下一条评论之前你会知道的)。想想2年前我们两人都是同一个目标:)时光飞逝。@Richardakacyberkiwi-谢谢!是的,我记得你比我先过了两万。那真的是两年前吗?时间过得真快!如果你想维护一个非空的契约,你必须把这整件事包装在
ISNULL([CONVERT(…)],0)
中,尽管1或0从不为空。@Joe除了SSMS脆弱的设计人员所展示的,这有什么区别?将非NULL放入实际表的唯一方法是,如果有人修改了计算列定义(在这种情况下,他们同样可能删除ISNULL()包装器,因为在他们看来,它首先出现在表中似乎不符合逻辑)。不确定,可能是一些使用EF将架构拉入EDMX的人。在我的例子中(代码优先+迁移+位计算),我被要求添加转换/转换,因为在输入数据后,EF哭着试图从INT设置布尔值。我一下子添加了外部ISNULL,所以我不确定它是否会同样抱怨为null。大概不会,因为它似乎是类型推断(而且它永远不可能是空的),但也许其他人会发现它很有用。我也没想到EF会抱怨将1/0设置为布尔值。。