我有下表:

CREATE TABLE [dbo].[EntityAttributeRelship](
    [IdNmb] [int] IDENTITY(1,1) NOT NULL,
    [EntityIdNmb] [int] NOT NULL,
    [AttributeIdNmb] [int] NOT NULL,
    [IsActive] [bit] NOT NULL CONSTRAINT [DF_EntityAttributeRelship_IsActive]  DEFAULT ((0)),
CONSTRAINT [PK_EntityAttributeRelship] PRIMARY KEY CLUSTERED 
([IdNmb] ASC) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]

表格中的部分数据如下所示:

IdNmb    EntityIdNmb    AttributeIdNmb  IsActive
1        22             7               0
2        22             8               0
3        22             9               0
4        22             10              1

我想添加一个约束,以确保没有人添加或更新记录以使IsActive = 1,如果已存在EntityIdNmb的记录,其中IsActive = 1。

我该怎么做?

有帮助吗?

解决方案

如果您使用的是SQLServer,则可以创建聚簇索引视图。

CREATE VIEW dbo.VIEW_EntityAttributeRelship WITH SCHEMABINDING AS
SELECT EntityIdNmb 
FROM dbo.EntityAttributeRelship
WHERE IsActive = 1
GO

CREATE UNIQUE CLUSTERED INDEX UIX_VIEW_ENTITYATTRIBUTERELSHIP 
  ON dbo.VIEW_EntityAttributeRelship (EntityIdNmb)

这确保您的表中只有一个EntityIdNmb,IsActive = 1。

其他提示

听起来你需要实现一个触发器(假设你的db产品支持它)。如果您只需要一个活动条目和一个非活动条目,则唯一索引将起作用。否则,您需要编写某种自定义约束或触发器(可能是2 - 一个用于插入,一个用于更新),以确保您没有2个具有相同ID的记录,其中两个都是活动的。

如果您正在使用MSSQL(我认为这就是您的语法),请创建一个仅包含IsActive = 1的行的视图,然后在视图中的EntityIdNmb上放置一个唯一索引。

在最近我用过的PostgreSQL中,你可以创建一个部分索引: http://www.postgresql.org/docs/8.3/interactive/索引-partial.html

写入触发器的事情是决定是否要拒绝记录,将值更改为0而不是1或将旧记录更新为零,并将其作为一个。如果要删除值为1的记录,是否需要将另一条记录更改为活动记录,如何选择哪一条记录?一旦你可以在触发器中定义你想做的事情,我们就可以帮助你更好地设计这个过程。

我们执行后两步,将任何地址作为数据库中的主要邮寄地址。我们的业务规则是一个且只有一个地址可以是主要地址,如果有任何地址,则必须将其标记为主要地址。这种触发器的关键是要记住插入/更新/删除可以批量发生(即使这不是常规),并确保触发器以基于集合的方式工作。当我到达这里时,我们通过游标实现了多行处理,当我不得不在导入中更新200,000个地址时,这变得很糟糕。 (注意没有经验的人 - 不要在触发器中使用光标!)

非活动记录将用于什么?它们是否未使用,只是为了跟踪以前的活动记录?如果是这样,是否可以将数据拆分为多个表?有点像...

EntityAttributeRelship(IDNmb,EntityIDNmb,AttributeIDNmb)

EntityAttributeRelshipHistory(IDNmb,EntityIDNmb,AttributeIDNmb)

如果它在EntityAttributeRelship表中,则表示它处于活动状态。如果它在历史表中,那么它在某个时刻被激活并且已经被停用了?

如果你确实需要一张桌子中的所有内容,我会选择todd.run建议使用触发器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top