0

我在数据库中有两个实体,它们以父/子关系运行。

  • 父表中的记录包含总量
  • 子表中的记录总和必须小于/等于父总数

我有两个触发器

  • 父表触发器检查更改不违反基于子值的约束
  • 子表触发器检查更改是否违反基于父值的约束

业务应用程序允许用户同时更新两者。例如,我可以添加父总计,并在同一个表单提交中添加子行项目。或者我可以在同一笔交易中增加/减少现有数量的双方。

当用户想要将父级归零并将其所有子级归零时,就会出现问题。事务首先尝试将触发违规的父级归零,然后回滚事务。

所以你可能会说只是颠倒顺序。但是,如果我尝试在不先插入父项的情况下插入子项,那么在用户创建新记录的情况下,我也会违反另一个触发器。

我正在寻找的是是否有与延迟触发器等效的东西(我认为没有)。我也可以完全删除触发器,在 SP 中执行规则,但这是最好的选择吗?我很犹豫是否让表格像那样打开而不检查数据。

编辑 - 添加触发器示例

列名不准确,但逻辑与我使用的相同。

CREATE TRIGGER trg_child ON tbl_child
AFTER UPDATE,INSERT AS

BEGIN

IF EXISTS (SELECT PARENT_ID,ParentQty FROM (SELECT PARENT_ID, SUM(QTY) AS ChildQty FROM INSERTED GROUP BY PARENT_ID) 
        JOIN tbl_parent WHERE ChildQTY>ParentQty)
BEGIN
    RAISERROR('Child quantities exceed parent',16,1)
    ROLLBACK TRANSACTION
END 
ELSE
END
4

2 回答 2

0

我打算将此评论作为答案,因为我相信它解决了所提出的问题,并且它使用了触发器:

The problem occurs when the user wants to zero-out a parent and zero-out all its children...

暂时忽略父/子 ERD,此要求中唯一有问题的词是“全部”。您可以仅将未消耗的数量“归零” ,这可能不是全部,因为您正在处理现实世界中的物品。您将小部件分配给销售代表。销售代表销售其中的 50% 并将它们运送给客户。您不能 100% 解除分配,因为只剩下一半的小部件。

要处理分配的“撤销”(即撤销或减少),您可以使用AllocationAdjustments表来调整条目。您的AllocationConsumption触发器(即销售代表使用分配给他们的项目)可以通过查看AllocationAllocationAdjustments来计算总可用分配,并拒绝让销售代表消耗大于当前可用的数量。您的AllocationAdjustments触发器可以查看AllocationAllocationConsumption以确保大于或等于所需减量的数量保持未消耗。

于 2013-05-01T12:10:09.803 回答
0

I could also remove the triggers altogether, enforce the rules within the SP, but is that the best option here? I'm hesitant to leave the tables open like that without checks on the data.

对于像 OrderHeader 和 OrderDetail 这样的表,这是一个由来已久的难题。纯粹主义者会说,将订单项总数存储在父项中是一种非规范化,并告诉您您已经铺好床,所以睡在上面。我建议取消对表的所有直接更新/插入/删除权限,通过存储过程处理所有与写入相关的 I/O,这些存储过程将操作包装在事务中并在提交前进行完整性检查。

于 2013-04-30T19:35:43.087 回答