我在数据库中有两个实体,它们表现为父/子关系。
我有两个触发器
业务应用程序允许用户同时更新这两个。例如,我可以添加父总计,并在同一表单提交中添加子行项目。或者我可以在同一笔交易中增加/减少现有数量的两面。
当用户想要将父项清零并将其所有子项清零时,会出现问题。事务通过尝试将父进程清零来触发违规,然后回滚事务。
所以你可以说只是颠倒顺序。但是,如果我尝试插入子项而不先插入父项,那么在用户创建新记录的情况下,我也会违反其他触发器。
我正在寻找的是,是否存在等同于延迟触发器的东西(我认为没有)。我也可以完全删除触发器,在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
答案 0 :(得分: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,这些存储过程将事务中的操作包装起来并在提交之前进行完整性检查。
答案 1 :(得分:0)
我打算将此评论作为答案,因为我相信它可以解决所提出的问题,并使用触发器:
The problem occurs when the user wants to zero-out a parent and zero-out all its children...
暂时忽略父/子ERD,此要求中唯一有问题的词是“全部”。您可以“清零”未消耗的数量,这可能不是全部,因为您正在处理现实世界中的项目。您将小部件分配给销售代表。销售代表销售其中的50%并将其运送给客户。你不能解除分配100%,因为只剩下一半的小部件。
要处理分配的“撤消”(即撤消或减少),您可以使用 AllocationAdjustments 表来调整条目。您在 AllocationConsumption 上的触发器(即销售代表使用分配给他们的商品)可以通过查看分配和分配调整来计算总可用分配,以及拒绝让销售代表消耗的数量大于目前可用的数量。您在 AllocationAdjustments 上的触发器可以查看分配和 AllocationConsumption ,以确保大于或等于所需减量的数量仍为未使用。< / p>