我要添加一个计算列,该列应为现有表上的NOT NULL
。
我的计算值的源列当然都是NOT NULL
。我想使计算列不是持久性的,以节省空间,但是我没有这样做:
ALTER TABLE UnitHistory
ADD
[PrefixedUnitId] AS ((UnitHistory.UnitIdPrefix + cast(UnitHistory.UnitId
AS nvarchar(8)))) NOT NULL
GO
给予
在计算时只能创建UNIQUE或PRIMARY KEY约束 列,而CHECK,FOREIGN KEY和NOT NULL约束则需要 计算的列将保留。讯息15135,第16级,状态15 过程sp_addextendedproperty,第72行对象无效。扩展的 “ dbo.UnitHistory.PrefixedUnitId”上不允许使用属性,或者 该对象不存在。
现在,我明白了消息的含义,并且可以肯定的是,使用PERSISTED NOT NULL
确实会产生该列。
但是,为了节省空间,我不想保留该列。
当基础列不是NULL时,是否有一种方法可以使计算列不是NULL,但不是持久性的?
注意:它应该可以在SQL Server 2012 SP2上运行
答案 0 :(得分:1)
这似乎完全多余,但是您可以在check
约束中重复该条件:
ALTER TABLE UnitHistory
ADD PrefixedUnitId AS ( UnitHistory.UnitIdPrefix + cast(UnitHistory.UnitId AS nvarchar(8)) );
ALTER TABLE UnitHistory
ADD CONSTRAINT CHECK ( UnitHistory.UnitIdPrefix + cast(UnitHistory.UnitId AS nvarchar(8)) IS NOT NULL );
但是,由于源列是NOT NULL
,所以结果永远不会是NULL
。
非持久计算列的概念是,它们是根据 output 而不是 input 进行计算的。我认为这可以解释为什么check
约束不合适。
例如,您可以拥有一个表,该表具有一个计算列,该列会生成错误并仍然充分使用该表:
create table t (
id int identity primary key,
x int,
computed as (1 / 0)
);
-- works
insert into t (x) values (1);
-- works
select x
from t;
-- fails
select *
from t;
Here是db <>小提琴。
顺便说一句,总是会产生错误的计算列有一个很好的副作用-如果您要这样做,它将阻止用户使用select *
。