[英]How to check if foreign key constraint fails when deleting record
I have created a database in SQL Server and front end is PHP - CodeIgniter.我在 SQL 服务器中创建了一个数据库,前端是 PHP - CodeIgniter。 In the database I have created multiple foreign keys with other tables.
在数据库中,我用其他表创建了多个外键。 Now when the user tries to delete the record, instead of really deleting I want to flag the record as
deleted = 1
, this should only be done when there will be no reference records are available in child table.现在,当用户尝试删除记录时,而不是真正删除我想将记录标记为
deleted = 1
,只有在子表中没有可用的参考记录时才应该这样做。 Below are example tables:以下是示例表:
Parent_Table
Id INT(PK), Name Varchar, deleted INT
Child_Table
Id INT(PK), FK_Parent_Table_ID INT, address varchar, deleted INT
Above is just example of my tables.以上只是我的表格的示例。 Now whenever a user tries to delete a record from the parent table foreign key will check for constraint and then delete the record, here instead of actual deletion I want it flag as
deleted = 1
.现在,每当用户尝试从父表中删除记录时,外键都会检查约束,然后删除记录,在这里,我希望将其标记为
deleted = 1
而不是实际删除。
I have tried using transaction->start
and transaction->complete
so if foreign key fails the transaction gets aborted but here the problem is if the foreign key not failing then the rollback will occur and in that case the PRIMARY KEY
of the record will be changed that should not be done.我尝试过使用
transaction->start
和transaction->complete
,所以如果外键失败,事务将中止,但这里的问题是,如果外键没有失败,那么将发生回滚,在这种情况下,记录的PRIMARY KEY
将是不应该做的改变。
So, I want a way to check the foreign key conflict before transaction starts without actual deletion of the record所以,我想要一种在事务开始之前检查外键冲突而不实际删除记录的方法
To implement what you are asking, just check for the existence of a record in the child table eg要实现您的要求,只需检查子表中是否存在记录,例如
declare @RecordToDelete int = 123;
-- Delete the record if no child records exist
delete
from Parent_Table
where id = @RecordToDelete
and not exists (select 1 from Child_Table where FK_Parent_Table_ID = @RecordToDelete);
-- Flag the record as deleted if child records exist
update Parent_Table set
Deleted = 1
where id = @RecordToDelete
and exists (select 1 from Child_Table where FK_Parent_Table_ID = @RecordToDelete);
Depending on whether you really need to keep the record, because you could always create your foreign keys with a cascade delete.取决于您是否真的需要保留记录,因为您始终可以使用级联删除创建外键。
With 15+ child tables I would seriously consider just always flagging the record as deleted and never bothering to actually delete those without child records.对于 15 个以上的子表,我会认真考虑始终将记录标记为已删除,并且从不费心实际删除那些没有子记录的记录。 A few extra records is unlikely to make much difference to your database.
一些额外的记录不太可能对您的数据库产生太大影响。
Actually in my experience child tables fall into 2 categories:实际上,根据我的经验,子表分为两类:
If this is the case the checks required should become more manageable.如果是这种情况,所需的检查应该变得更易于管理。
Also for these situations I recommend encapsulating the delete logic within a stored procedure in order to keep it all in one place, and be easy to modify if the database schemes changes in future.同样对于这些情况,我建议将删除逻辑封装在存储过程中,以便将其全部保存在一个地方,并且如果将来数据库方案发生更改,则易于修改。
Note: Personally I would make the Deleted
column a bit
rather than an int
as it more accurately reflects the intention.注意:我个人会使
Deleted
列bit
而不是int
,因为它更准确地反映了意图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.