一次仅在一个子记录中将位字段限制为真
Posted
技术标签:
【中文标题】一次仅在一个子记录中将位字段限制为真【英文标题】:Restrict a bit field to true in only one child record at a time 【发布时间】:2020-01-30 06:30:47 【问题描述】:我有一个Person
表,每个人的记录都属于Company
表中的父记录。
一个Person
被指定为其父Company
的“组织者”。最初,我通过从Company
表中识别Person
记录的递归引用来处理这个问题,它是“组织者” - 但是我用来构建我的应用程序层的软件崩溃了 - 它无法处理递归引用.
我改变了策略,并在Person
表中添加了一个位字段来识别此人是否是“组织者”,但需要确保只有一个一个每个 Company
记录的“组织者”。如果我在 Person 表上使用 AFTER UPDATE
触发器,Person
上的更新会触发 Person
上的更新 - 显然我想避免递归触发器。
我如何确保只有一个Person
为其父级Company
标记为“组织者”?
+-----------+---------+---------+-----------+ +-----------+---------+---------+-----------+
| FirstName | Surname | Company | Organizer | | FirstName | Surname | Company | Organizer |
+-----------+---------+---------+-----------+ +-----------+---------+---------+-----------+
| John | Smith | 1 | True | | John | Smith | 1 | True |
| Mike | Jones | 1 | NULL | | Mike | Jones | 1 | NULL |
| Fred | Green | 1 | NULL | | Fred | Green | 1 | NULL |
| James | McMahon | 2 | NULL | | James | McMahon | 2 | NULL |
| Philip | Stills | 2 | NULL | Making Philip organizer ==> | Philip | Stills | 2 | True |
| Hector | Berlioz | 2 | True | 'triggers' this change ==> | Hector | Berlioz | 2 | NULL |
+-----------+---------+---------+-----------+ +-----------+---------+---------+-----------+
【问题讨论】:
带有 where 子句的唯一索引?例如,create unique index ix_your_index_name on Person (Company, Organizer) where Organizer is not null
。
可能不是您想要的,但您是否考虑过在 Company 表中指定一个 Organizer
字段?这样,您可以在那里存储谁是组织者的信息,并在必要时通过连接获取它。此外,您的 person 表是否有唯一的标识符号(类似于 ID?)如果没有,它应该有。
已经提到的唯一索引或带有 udf 的约束,例如:ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [chkUniqueOrganizer] CHECK (([dbo].[CheckUniqueOrganizer](Company)=0))
@Magisch 是的,每个表都有一个 ID,只是为了示例的简单性没有包含它。您的建议正是我最初所做的,但我的客户端软件无法处理递归引用 - 这基本上会使公司成为它自己的子记录之一的子记录。在 SQL Server 中很好,但在应用层中不行。
@user1711390 我不太明白......也许如果你在答案中充实了这个想法?
【参考方案1】:
所以看到这里没有人给出答案,我将发布我最终所做的:
创建了一个名为 Organizer 的单独表,只有两个字段:
CREATE TABLE Organizer (
Company int NOT NULL UNIQUE,
Person int NOT NULL,
CONSTRAINT FK_Organizer_Company FOREIGN KEY (Company) REFERENCES Company(ID) ON DELETE CASCADE,
CONSTRAINT FK_Organizer_Person FOREIGN KEY (Person) REFERENCES Person(ID) ON DELETE CASCADE,
CONSTRAINT PK_Organizer_ID PRIMARY KEY (Company, Person)
);
通过使 Company
字段独一无二,我只能为任何公司拥有一个组织者。
ON DELETE CASCADE
阻止我得到不存在的公司或个人的孤立组织者记录。
不记得为什么我在这两个字段中都设置了PRIMARY KEY
。似乎不痛。
然后只需检查现有的Organizer
记录并更新它是否存在,或者如果不存在则插入一个。我在应用程序层这样做了,尽管我可以轻松地创建一个存储过程,该过程采用 Company.ID
和 Person.ID
参数,使用前者检查 Organizer
记录,并相应地更新表。甚至可以检查 Person 是否真的属于该公司,并相应地向应用程序层返回一个值。
【讨论】:
以上是关于一次仅在一个子记录中将位字段限制为真的主要内容,如果未能解决你的问题,请参考以下文章