我有一个数据库,用于记录 Microsoft SQL Server 2012 Express 中奶牛的繁殖信息。显然,一头母牛要等到出生后才能繁殖,一生中可能会繁殖多次;我需要在我的数据库中强制执行这些约束。我目前已经根据下图安排了一个架构:DataID 是所有动物的主键。我试图实现 Table-Per-Type 继承,因此 [Animals].[Master] 和 [Animals].[Females] 之间是一对一的关系。由于每个雌性可能会繁殖多次,因此我在 [Animals].[Females] 和 [Breedings].[Breedings] 之间建立了一对多的关系 我的问题是:我怎样才能为所有女性执行 BirthDate Breedings.Date 的规则? 我基本上需要类似于以下伪代码的东西(我实际上已经将其放入 CHECK 约束的“表达式”框中并收到了验证错误):[Animals].[Master].[BirthDate] < [Breedings].[Breedings].[Date]INNER JOIN [Animals].[Master] ON[Breedings].[Breedings].[DataID] = [Animals].[Master].[DataID]我也试过用正确的连接创建一个 View ,但发现 CHECK 约束不能在 View 中使用。那么,有谁知道我如何强制执行这些约束? 编辑 - 我尝试了使用触发器的建议,但无法正确制定触发器语法。这是我的代码:USE [CowInventory];GOCREATE TRIGGER [Breedings].[iCheckBreedingDateAfterBirthDate]ON [Breedings].[Breedings]FOR INSERTASBEGIN DECLARE @CowID UniqueIdentifier SELECT @CowID = DataID FROM inserted; DECLARE @CowBirthDate Date SELECT @CowBirthDate = BirthDate FROM [Animals].[Master] WHERE [Master].[DataID] = @CowID DECLARE @BreedingDate Date SELECT @BreedingDate = Date FROM inserted; IF(@CowBirthDate > @BreedingDate) BEGIN THROW; ENDEND根据我拥有的一本书(SQL Server 2012 Step by Step),这种语法应该可以完美运行。但是,SQL Server 在 THROW 和最后一个 END 下给了我粉红色的线条,说明 Incorrect syntax near 'THROW'. Expecting CONVERSATION, DIALOG, DISTRIBUTED, or TRANSACTION. 和 Incorrect syntax near 'END'. Expecting CONVERSATION. 我已经插入了这些关键字,但它们没有任何改变。 最佳答案 您可以在 Breedings 表上创建触发器来检查此规则。触发器是一个特殊的存储过程,它在某些表的 INSERT\UPDATE\DELETE 上自动执行。因此,您可以编写一个触发器来检查插入到 Breedings 中的所有新行,如果有一行的 Date 小于合适的 BirthDate,则抛出错误。与 UPDATE 相同,如果更改了日期列,请检查相应动物的出生日期并相应地抛出错误。 DELETE 在这件事上是安全的。CHECK 对于涉及其他表的规则不是很好。一般建议是仅将它们用于一张表内的基本检查。稍后编辑试试这个触发器体...BEGIN if exists ( SELECT 1 FROM inserted i join Animals.Females f on i.DataID = f.DataID join Animals.Master m on f.DataID = m.DataID WHERE m.BirthDate > i.Date ) RAISERROR("Trigger iCheckBreedingDateAfterBirthDate - Breedings.Date is wrong", 18, 0)ENDGO关于sql-server - 如何跨多个表强制执行 CHECK 约束,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28172719/
10-11 21:33