删除所有相关记录

时间:2016-04-27 18:07:57

标签: sql sql-server-2008 sql-server-2012

我有几张如下表。

Tables

每个表都有一个主键table2。不幸的是,即使表引用另一个表的主键(例如:table2_1table1.table1_id引用table1_id = 10),其他表上也没有外键设置,而我是现在不允许改变这个设计。

我需要在根据主键从表中删除记录时删除所有相关记录。

插图:

如果我在table1中删除table1_id的记录,我还应该删除table2是表格结构table2_1的其他表格中的记录。在这种情况下table2)。当在table2_id中删除记录时,我还应删除其他表中table3是表结构的一部分的记录(在这种情况下为CREATE TABLE table1 (table1_id INT IDENTITY(10, 1), table1_field1 varchar(100), table1_field2 BIT); CREATE TABLE table2 (table2_id INT IDENTITY(100, 1), table2_field1 varchar(100), table2_field2 BIT, table1_id INT); CREATE TABLE table2_1 (table2_1_id INT IDENTITY(500, 1), table2_1_field1 varchar(100), table2_1_field2 BIT, table1_id INT); CREATE TABLE table3 (table3_id INT IDENTITY(1000, 1), table3_field1 varchar(100), table3_field2 BIT, table2_id INT); CREATE TABLE table4 (table4_id INT IDENTITY(10000, 1), table4_field1 varchar(100), table4_field2 BIT, table3_id INT); CREATE TABLE table5 (table5_id INT IDENTITY(100000, 1), table5_field1 varchar(100), table5_field2 BIT, table4_id INT); INSERT INTO table1(table1_field1, table1_field2) VALUES ('table1_field1_1', 0), ('table1_field1_2', 1), ('table1_field1_3', 0), ('table1_field1_4', 1); INSERT INTO table2(table2_field1, table2_field2, table1_id) VALUES ('table2_field1_1', 0, 10), ('table2_field1_2', 1, 11), ('table2_field1_3', 0, 12), ('table2_field1_4', 1, 13); INSERT INTO table2_1(table2_1_field1, table2_1_field2, table1_id) VALUES ('table2_1_field1_1', 0, 10), ('table2_1_field1_2', 1, 11), ('table2_1_field1_3', 0, 12), ('table2_1_field1_4', 1, 13); INSERT INTO table3(table3_field1, table3_field2, table2_id) VALUES ('table3_field1_1', 0, 100), ('table3_field1_2', 1, 101), ('table3_field1_3', 0, 102), ('table3_field1_4', 1, 103); INSERT INTO table4(table4_field1, table4_field2, table3_id) VALUES ('table4_field1_1', 0, 1000), ('table4_field1_2', 1, 1001), ('table4_field1_3', 0, 1002), ('table4_field1_4', 1, 1003); INSERT INTO table5(table5_field1, table5_field2, table4_id) VALUES ('table5_field1_1', 0, 10000), ('table5_field1_2', 1, 10001), ('table5_field1_3', 0, 10002), ('table5_field1_4', 1, 10003); SELECT * FROM table1 SELECT * FROM table2 SELECT * FROM table2_1 SELECT * FROM table3 SELECT * FROM table4 SELECT * FROM table5 select t.name, c.name, 'DELETE [' + t.name + '] WHERE [' + c.name + '] = 10', 'SELECT t.name [tn], c.name [cn] FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name=''' + t.name + '_id'' and t.name<>''' + t.name + ''' ' from sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name='table1_id' and t.name<>'table1' order by t.name /* Use the SELECT queries to find other dependencies like below */ SELECT t.name [t], c.name [c],'SELECT t.name [tn], c.name [cn] FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name=''' + t.name + '_id'' and t.name<>''' + t.name + '''' FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name='table2_id' and t.name<>'table2' SELECT t.name [tn], c.name [cn], 'SELECT t.name [tn], c.name [cn] FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name=''' + t.name + '_id'' and t.name<>''' + t.name + '''' FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name='table3_id' and t.name<>'table3' SELECT t.name [tn], c.name [cn], 'SELECT t.name [tn], c.name [cn] FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name=''' + t.name + '_id'' and t.name<>''' + t.name + '''' FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name='table4_id' and t.name<>'table4' SELECT t.name [tn], c.name [cn] FROM sys.tables t inner join sys.columns c on t.object_id=c.object_id where c.name='table5_id' and t.name<>'table5' /* I need to run the SQL queries something like below */ DELETE table5 where table4_id in (select table4_id from table4 where table3_id in (select table3_id from table3 where table2_id in (select table2_id from table2 where table1_id=10))) DELETE table4 where table3_id in (select table3_id from table3 where table2_id in (select table2_id from table2 where table1_id=10)) DELETE table3 where table2_id in (select table2_id from table2 where table1_id=10) DELETE table2 where table1_id=10 DELETE table2_1 where table1_id=10 DELETE table1 where table1_id=10 ),我需要遍历,直到没有依赖关系并删除所有相关记录。

我试图生成如下的查询(假设我想删除table1_is = 10的记录):

int

我预计删除后会有以下结果:

Expected Results

注意:

  1. 请注意我知道外键关系在这种情况下如何有用,但我现在不允许更改表结构/设计(即无法添加外键)。

    < / LI>
  2. 我也无法添加触发器。

  3. 我想用T-SQL /动态SQL实现预期的结果。

  4. 我在插图中只使用了5个表,但它可以是类似结构中的n个表。

  5. 任何人都可以建议任何替代方法(或自动化),所以我只是传递table1.table1_id,那么它应该删除所有相关记录吗?

2 个答案:

答案 0 :(得分:0)

解决此问题的标准方法是使用外键/触发器,但只要您不能使用它们,就必须以不同的方式保持完整性:

所以,您需要存储过程来执行以下操作:

delete from table1 where table1_id = ####;
delete from table2 where table1_id not in (select table1_id from table1);
delete from table2_1 where table1_id not in (select table1_id from table1);
delete from table3 where table2_id not in (select table2_id from table2);
delete from table4 where table3_id not in (select table3_id from table3);
delete from table5 where table4_id not in (select table4_id from table4);

这将删除table1中的行,然后全部&#34;无效&#34;来自其他表的行

答案 1 :(得分:0)

如果允许存储过程,则类似这样:

CREATE PROC delrec @id int AS
BEGIN
 DELETE table5 where table4_id in 
  (select table4_id from table4 where table3_id in 
    (select table3_id from table3 where table2_id in 
      (select table2_id from table2 where table1_id=@id)))
 DELETE table4 where table3_id in 
  (select table3_id from table3 where table2_id in 
    (select table2_id from table2 where table1_id=@id))
 DELETE table3 where table2_id in 
  (select table2_id from table2 where table1_id=@id)
 DELETE table2 where table1_id=@id
 DELETE table2_1 where table1_id=@id
 DELETE table1 where table1_id=@id
END