简体   繁体   English

删除所有外键数据,删除主数据或反之亦然

[英]Delete all foreign key data on delete of primary or vice-a-versa

I have table structure like this: 我有这样的表结构:

PrimaryTable -> p_id Here p_id is primary PrimaryTable - > p_id 这里P_ID是主

SecondoryTable -> s_id p_id Here p_id is a foreign key SecondoryTable > s_id p_id 这里p_id是外键

ThirdTable -> t_id s_id Here s_id is foreign key ThirdTable > t_id s_id 这里s_id是外键

FourthTable -> f_id t_id Here t_id is foreign key FourthTable > f_id t_id 这里t_id是外键

So I am deleting one of my p_id from PrimaryTable and want that its SecondoryTable data should also get delete AND ThirdTable data should be deleted with reference to SecondoryTable and FourthTable data should be deleted with reference to ThirdTable 所以我删除了我的一个p_idPrimaryTable ,并希望其SecondoryTable数据应该也会删除和ThirdTable数据应参照被删除SecondoryTableFourthTable数据应参照被删除ThirdTable

I know i can write Delete query from bottom to top, but how to do for so many levels like this?? 我知道我可以从下到上编写Delete查询,但是对于这么多的级别该怎么做?

I found this but not sure on howto: https://stackoverflow.com/a/9847308/1182021 我发现了这个但不确定如何使用: https : //stackoverflow.com/a/9847308/1182021

Because its four level hierarchy i am confused. 由于其四级层次结构,我感到困惑。

EDIT1: 编辑1:

What if I want to delete Primary on Delete of Child 如果我想在删除Child删除Primary Child怎么办

Kindly suggest. 请提示。

As per OP's request, this is an answer for the case when the user wants to delete the row from the parent table when a row is deleted from the child table. 根据OP的请求,这是针对以下情况的答案:当用户希望从子表中删除行时,用户希望从父表中删除行。 The case for recursively deleting all the children when a parent is deleted is working using MySQL ON DELETE CASCADE option. 使用MySQL ON DELETE CASCADE选项可以在删除父级时递归删除所有子级。

The 4 tables would be table1, table2, table3 & table4. 这4个表分别是table1,table2,table3和table4。

If the user wants to delete a row in table2 and also the corresponding row in table1 (parent of table2) then in PHP: 如果用户要删除table2中的行以及table1中的相应行(table2的父级),则在PHP中:

// t2_delete_row_id is the id of the table 2 row to be deleted
// get the the parent of table2
$sql_get_parent = "select p_id from table2 where s_id = 't2_delete_row_id '";
// execute this query using MySQLi/PDO to get id of the parent row to be deleted
// assuming that id is t1_parent_row_id
// now delete the row from table 2:
// note that because of the foreign key constraints, 
// corresponding rows from table3 and table4 would also be deleted
$sql_delete_child = "delete from table2 where s_id = 't2_delete_row_id'";
if (mysqli_query($sql_delete_child)){
    // delete the parent row
    $sql_delete_parent = "delete from table1 where p_id = 't1_parent_row_id'";
}

this logic can be extended so that on deleting table3 row, corresponding parent(table2) and "grand-parent" (table1) rows would be deleted as well. 可以扩展此逻辑,以便在删除table3行时,也将删除相应的parent(table2)和“祖父母”(table1)行。 A bit of recursion might be needed for that case. 在这种情况下,可能需要一点递归。 And this will of course delete the child rows in table4 because of the foreign key constraint. 当然,由于外键约束,这将删除table4中的子行。

If you are not able to use FOREIGN KEYS (ie using MyISAM tables) I would create a TRIGGER for this. 如果您不能使用FOREIGN KEYS(即使用MyISAM表),我将为此创建一个TRIGGER。 Example for first one below ... you will need to make one for each table that's cascading. 下面的第一个示例...您将需要为级联的每个表创建一个。

DELIMITER //
CREATE TRIGGER `pDeleteTrigger` BEFORE DELETE ON `PrimaryTable`
 FOR EACH ROW BEGIN
    DELETE FROM `SecondoryTable` WHERE NEW.`p_id` = `SecondoryTable`.`p_id`
END
//
DELIMITER ;

I have two approachs in my mind (if your language is Tsql) 我有两种方法(如果您的语言是Tsql)

1.- Store procedure 1.-存放程序

The idea is have a procedure "spDelete_PrimaryTable", so that you can delete the registers in the four tables by writinf something in tsql like: 这个想法是有一个过程“ spDelete_PrimaryTable”,以便您可以通过在tsql中写一些东西来删除四个表中的寄存器,例如:

 exec spDelete_PrimaryTable
       @p_id= 25 /* (25 or watever p_id of primary table you want to delete)*/

(yes you can call it from vb.net or watever you want to.) (是的,您可以从vb.net或希望的电话中调用它。)

the code would be something like: 该代码将是这样的:

use [your_database]

CREATE PROCEDURE [dbo].[spDelete_PrimaryTable]
    @p_id nvarchar(MAX)
AS 
 begin  
    SET NOCOUNT ON;

delete from FourthTable where t_id in (
    select ThirdTable.t_id 
    from ThirdTable inner join SecondoryTable on ThirdTable.s_id = SecondoryTable.s_id
    where SecondoryTable.p_id = @p_id
)
go

delete from ThirdTable where s_id in (
    select SecondoryTable.s_id 
    where SecondoryTable.p_id = @p_id
)
go

    /*Lol, I forgot to eliminate from the "SecondoryTable" */
    delete from SecondoryTable.s_id 
    where SecondoryTable.p_id = @p_id

go

delete from PrimaryTable where p_id = @p_id
go

 END


GO

2.- Triggers 2.-触发器

seems like "Christopher Morrissey" have already posted that while i was editing this answer XP 似乎“ Christopher Morrissey”已经发布了我正在编辑此答案时XP

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM