3

我有下表:

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。

我该怎么做呢?

4

5 回答 5

6

如果您使用的是 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)

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

于 2009-03-09T15:24:14.110 回答
3

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

于 2009-03-09T15:15:53.160 回答
2

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

在我最近使用较多的 PostgreSQL 中,您可以创建部分索引: http ://www.postgresql.org/docs/8.3/interactive/indexes-partial.html

于 2009-03-09T15:35:26.967 回答
1

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

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

于 2009-03-09T17:32:20.727 回答
0

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

EntityAttributeRelship(IDNmb, EntityIDNmb, AttributeIDNmb)

EntityAttributeRelshipHistory(IDNmb, EntityIDNmb, AttributeIDNmb)

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

如果您确实需要一张表中的所有内容,我会接受 todd.run 的使用触发器的建议。

于 2009-03-09T15:21:11.247 回答