如何检查主表的记录是否被子表使用/引用
在我的 ERP 应用程序中,我将一个名为“IsRemoved”的额外字段作为布尔值。每当用户删除任何记录时,该记录都不会被删除 - 只有其“IsRemoved”列的值为“true”。它可以帮助我们在需要时恢复数据,并且工作正常。
问题是,当用户删除主表的记录时,我们如何检查其所有子表都没有引用该记录(因为我们不执行物理删除,我们只是将“isremoved”字段标记为true)?
请向我提供任何查询或 sp,我可以从中检查主记录是否在其任何子记录中使用。
In my ERP application, I am taking a extra field named 'IsRemoved' as boolean. Whenever a user deletes any record, the record is not deleted - only its "IsRemoved" column gets value 'true'. It helps us to be able to recover data when ever we want, and its working fine.
The problem is that when ever user deletes record of Master Table, how can we check that all its child table not referring this record (because we do not preform physical deletion, we just mark "isremoved" field as true)?
Please provide me any query or sp from which I can do check that master record is used in any of its child or not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据经验,我必须告诉你这个设计很难使用。考虑更改设计以将数据复制到“审核跟踪”表,然后从主表中物理删除它。
如果您不考虑这一点,至少将其隐藏在
VIEW
中,并尽一切努力避免将其暴露给任何想要查询数据库的人,使用INSTEAD OF
> 如有必要,在VIEW
上触发。否则,应用程序可能会频繁出现错误,因为有人忘记添加使用此表的每个查询所需的AND isremoved = 0
谓词。是的。对此感到抱歉。但有时你必须治愈疾病,而不仅仅是治疗症状。
设计是妥协的:表应该对单个实体类型进行建模,而这是对两个实体类型进行建模。我怎么知道?因为OP已经声明,一旦“删除”实体就有不同的数据要求,通过说“问题是......我们如何检查其所有子表不引用此记录”。
所以“真正的”答案是:将实体移动到另一个不同的表。
但是,如果您从事治疗症状的业务,那么这里有一个答案:
IsRemoved
列添加到您的所谓的“子”表,带有
DEFAULT false
并确保它是
NOT NULL
。CHECK
约束所谓的“子”表来测试
isremoved = false
(或者其他什么'boolean' 在你的 SQL 中意味着
产品)。
UNIQUE
或PRIMARY KEY
)到您的所谓的“主”表
(IsRemoved, <现有关键列
,或更改现有密钥此处>)
因此。
FOREIGN KEY
约束所谓的“子”表可供参考
上面创建的复合键。
From experience I have to tell you this design is horrible to work with. Consider changing the design to copy the data to an 'audit trail' table then physically remove it from the main table.
If you won't consider this, at the very least bury this in a
VIEW
and do everything you can to avoid exposing this to anyone wanting to query the database, usingINSTEAD OF
triggers on theVIEW
if necessary. Otherwise, expect applications to have frequent bugs because someone forgot to add theAND isremoved = 0
predicate required by every query that uses this table.Yes. Sorry 'bout that. But sometimes you have to cure the disease rather than merely treat the symptoms.
The design is compromised: a table should model a single entity type, whereas this is modelling two. How can I tell? Because the OP has stated that once 'removed' the entity has different data requirement, by saying "The problem is ... how can we check that all its child table not referring this record".
So the 'real' answer is: move the entity to another distinct table.
But if you are in the business of treating symptoms then here's an answer:
IsRemoved
column to yourso-called 'child' tables, with
DEFAULT false
and ensureit is
NOT NULL
.CHECK
constraint to eachso-called 'child' table to test
isremoved = false
(or whatever'boolean' means in your SQL
product).
UNIQUE
orPRIMARY KEY
) to yourso-called 'master' table on
(IsRemoved, <existing key columns
, or alter an existing keyhere>)
accordingly.
FOREIGN KEY
constraints to eachso-called 'child' table to reference
the compound key created above.
我认为对这个问题本身的评论是非常中肯的。目前,这个问题还很模糊。
但是,假设子表也有一个 IsRemoved 字段 - 毕竟,如果主记录被标记为已删除,子记录仍然可用又有什么意义呢? - 为什么不在 Master 上实现一个触发器,如果 IsRemoved 更改,也会更改 Child 上的 IsRemoved 标志?
这样,就完全消除了检查子节点上主节点状态的需要,因为它们将在涉及活动或非活动状态时保持同步。
I think the comments on the question itself are quite pertinent. The question, at this point, is vague.
But, assuming that the child table also has a IsRemoved field - after all what would be the point of the child records remaining available if the master record is marked as removed? - why don't you implement a trigger on Master that, if IsRemoved is changed, also changes the IsRemoved flag on the Child?
This way the need to check the status of the master on the child is completely eliminated as they will be in sync as it pertains to the active or inactive status.
您能否在事务中插入除 IsRemove='true' 之外所有值都相同的替换记录,然后删除原始记录?这将为替换记录生成一个新的主键,以便旧的引用无法保留。
我假设您希望检测子项引用已删除记录的情况,并将其视为错误。
Can you, within a transaction, insert a replacement record with all values the same other than IsRemove='true', then remove the original record? This will generate a new primary key for the replacement record, so that old references cannot remain.
I assume you wish to detect the condition that child references a deleted record, and treat this as an error.
如果我们使用以下查询在所有子表中放置了适当的外键约束,则可以找到主数据表的引用表:
此查询在 Oracle 中有效。我不确定其他数据库。
找到引用表后,您需要查找引用表中是否存在要删除的主数据记录。如果子表中存在活动记录,则可以抛出异常。这里的关键是仅找到引用的记录是不够的。我们可能会遇到这样的情况:在子表中找到主记录引用,但子记录也已被取消。我们使用上述概念编写了一个用于主数据删除预检查的实用程序。
You can find the referenced table of master data table if we have put proper foreign key constraint in all the child tables using following query:
This query works in oracle. I am not sure about other databases.
Once you have found the referenced table, you need to find whether the master data record you are trying to delete exists in the referenced table or not. If the active record exists in the child table, you can throw an exception. The key thing here is that finding the referenced record alone is not sufficient. We might have cases where we find the master record reference in the child table, but the child record has also been cancelled. We have written an util for the delete pre check of master data using above concept.
使用这个逻辑:
USING THIS LOGIC: