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设置为布尔值。。