如何跨多个表强制执行 CHECK 约束

Mil*_*n X 3 t-sql database sql-server check-constraints

我有一个数据库,用于记录 Microsoft SQL Server 2012 Express 中奶牛的繁殖信息。显然,一头母牛要等到出生后才能繁殖,一生中可能会繁殖多次;我需要在我的数据库中强制执行这些约束。我目前已经根据下图安排了一个架构:

Cow 数据库架构图

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]
Run Code Online (Sandbox Code Playgroud)

我也试过用正确的连接创建一个视图,但发现 CHECK 约束不能在视图中使用。

那么,有谁知道我如何强制执行这些约束?

编辑- 我尝试了使用触发器的建议,但无法正确制定触发器语法。这是我的代码:

USE [CowInventory];
GO
CREATE TRIGGER [Breedings].[iCheckBreedingDateAfterBirthDate]
ON [Breedings].[Breedings]
FOR INSERT
AS
BEGIN
    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;
        END
END
Run Code Online (Sandbox Code Playgroud)

根据我拥有的一本书(SQL Server 2012 Step by Step),这种语法应该可以完美运行。而是,SQL服务器让我在粉红色的线THROW,最后END,陈述Incorrect syntax near 'THROW'. Expecting CONVERSATION, DIALOG, DISTRIBUTED, or TRANSACTION.Incorrect syntax near 'END'. Expecting CONVERSATION.我已经插入这些关键字,但他们改变什么。

小智 6

我不会使用触发器。使用检查约束。干净多了。记住一个检查约束可以调用一个函数。编写一个函数来检查另一个表。然后从检查约束调用该函数。这是实现多表检查约束的最佳方式。

  • 当心; 似乎带有 UDF 的“CHECK CONSTRAINT”不可靠:https://dba.stackexchange.com/questions/12779/how-are-my-sql-server-constraints-being-bypassed (2认同)