我创建了一个以计算列为主键的表。 表创建得很好。这里是脚本..
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ARITHABORT ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [planning.A062].[RMAllocation](
[Id] [int] IDENTITY(100,1) NOT NULL,
[RMAllocatonId] AS ('RMA_'+CONVERT([nvarchar](100),[Id])) PERSISTED NOT NULL,
[RequsitionNo] [nvarchar](100) NULL,
[RMDemandId] [nvarchar](104) NULL,
[HierarchyId] [nvarchar](102) NULL,
[Season] [nvarchar](50) NULL,
[VendorSupplierNo] [nvarchar](100) NULL,
[Year] [int] NULL,
[Month] [int] NULL,
[Week] [int] NULL,
[Day] [int] NULL,
[PlannedQty] [int] NULL,
[ConfirmedQty] [int] NULL,
[Status] [int] NULL,
[CreatedBy] [int] NULL,
[SyncId] [nvarchar](100) NULL,
[CreatedOn] [datetime2](7) NULL,
[UpdatedBy] [int] NULL,
[UpdatedOn] [datetime2](7) NULL,
[IsActive] [bit] NULL,
[RecordDateTime] [datetime2](7) NULL,
CONSTRAINT [PK_RMAllocation] PRIMARY KEY CLUSTERED
(
[RMAllocatonId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
问题是当我使用Designer View更改此表(添加/编辑列)时,它会给我以下错误。
错误
Unable to create index 'PK_RMAllocation'.
Cannot define PRIMARY KEY constraint on nullable column in table 'RMAllocation'.
Could not create constraint. See previous errors.
当我使用脚本进行修改时,它可以工作。甚至我已将计算列声明为NOT NULL
。怎么会发生这种情况?
答案 0 :(得分:12)
评论太长了。设计师出了点问题。 SQL Server在文档中非常清楚,计算列可以用于主键(例如,here)。
我的猜测是,设计人员正在删除表中的所有约束并将其重新添加。最终以错误的顺序添加它们,因此主键在计算列的not null
之前分配。除了显而易见的不使用设计师之外,我不知道是否有任何解决方法。
答案 1 :(得分:5)
根据the documentation(强调我的)
计算列不能用作DEFAULT或FOREIGN KEY 约束定义或使用NOT NULL约束定义。
因此,即使在TSQL中也可以使用它,这有点令人惊讶。
当设计人员通过重新创建表来实现更改时,它会丢失列定义上的NOT NULL
。
[Id] [int] IDENTITY(100,1) NOT NULL,
[RMAllocatonId] AS ('RMA_'+CONVERT([nvarchar](100),[Id])) PERSISTED,
[RequsitionNo] [nvarchar](100) NULL,
从语义上讲,NOT NULL
常量和NOT NULL
列的连接永远不会是NULL
。
另一种可以说服SQL Server列NOT NULL
的方法 - 即使在没有NOT NULL
的情况下也可以将定义包装在ISNULL
中。
以下适用于设计师
[RMAllocatonId] AS (ISNULL('RMA_'+CONVERT([nvarchar](100),[Id]),'')) PERSISTED
答案 2 :(得分:0)
在插入时,系统不知道新的[id]值。您需要一个稍后更新该值的触发器。
答案 3 :(得分:0)
当两个Id
值相同时,相应的RMAllocatonId
值将相同。如果两个Id
值不同,则相应的RMAllocatonId
值将不同。因此,使Id
唯一等同于使RMAllocatonId
唯一。
如果你问我,只需将PRIMARY KEY放在它所属的Id
上并完成它......