我有几张如下表。
每个表都有一个主键table2
。不幸的是,即使表引用另一个表的主键(例如:table2_1
,table1.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
我预计删除后会有以下结果:
注意:
请注意我知道外键关系在这种情况下如何有用,但我现在不允许更改表结构/设计(即无法添加外键)。
< / LI>我也无法添加触发器。
我想用T-SQL /动态SQL实现预期的结果。
我在插图中只使用了5个表,但它可以是类似结构中的n个表。
任何人都可以建议任何替代方法(或自动化),所以我只是传递table1.table1_id,那么它应该删除所有相关记录吗?
答案 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