2011-03-19 131 views
1

嗨,请帮助我。
我有一个有很多表的数据库。我必须从整个数据库中删除其studentId不在给定10个ID中的所有记录(除了10个给定的studentID)。 studentID是表中的主键和大量表中的外键。我不确定即使其他表可能具有相同的studentID,现在我想编写一个脚本来执行此任务,这将从父表中删除所有记录以及子表(sql server 2008)。从数据库中删除记录

+0

当数据库处于“SINGLE_USER”模式时,您是否可以执行此操作,或者您是否需要在线执行数据库并行操作? – 2011-03-19 22:50:00

回答

5

对于外键约束,您必须首先从子表执行删除操作。

它会是这样的,因为你已经有了StudentID,所以父表不需要连接到父表。

Delete child1 Where studentID not in (1,2,4,5,6,77,122,123,1222,12121,99999) 
Delete child2 Where studentID not in (1,2,4,5,6,77,122,123,1222,12121,99999) 
Delete child3 Where studentID not in (1,2,4,5,6,77,122,123,1222,12121,99999) 
Delete students Where studentID not in (1,2,4,5,6,77,122,123,1222,12121,99999) 

如果你有一个“孙子”表,例如学生 - >账户 - > AccountHistory,那么你会以相反的顺序取下,例如:

Delete AccountHitory 
where AccountID not in (
    select AccountID 
    From Account 
    Where studentID in (1,2,4,5,6,77,122,123,1222,12121,99999)) 

Delete Account Where studentID not in (1,2,4,5,6,77,122,123,1222,12121,99999) 

Delete Student Where studentID not in (1,2,4,5,6,77,122,123,1222,12121,99999) 


要找出的外键连接的层次结构,您可以使用此查询

示例表

create table student (studentid int identity primary key) 
create table student_class (id int primary key, studentid int references student(studentid)) 
create table student_class_attendance (student_classid int references student_class(id), attended datetime) 
create table invoice (id int primary key, studentid int references student(studentid), due datetime, amount money) 

查询找到链接表

;with tmp(lvl,FK,PK) As (
    SELECT 1, FK.TABLE_NAME, PK.TABLE_NAME 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C 
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME 
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME 
    WHERE PK.TABLE_NAME = 'student' 
    UNION ALL 
    SELECT lvl+1, FK.TABLE_NAME, PK.TABLE_NAME 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C 
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME 
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME 
    INNER JOIN tmp on tmp.FK = PK.TABLE_NAME 
) 
SELECT * 
FROM tmp 
order by lvl desc 
+0

感谢您的快速响应,帮助了我。还有一个问题 。有没有什么办法可以让脚本搜索表名并搜索studentid,然后从grandchild中删除它,然后删除child,最后从parent删除。我想这样做,因为数据库是巨大的(超过200个表),我不知道哪些是相互依赖的表。 – Tenzin 2011-03-19 22:35:22

+0

@Pritesh - 答案更新 – RichardTheKiwi 2011-03-19 22:47:36

+0

多数民众赞成在精彩的脚本。非常感谢。现在我该如何使用这些知识将与所有studentid相关的记录从一个表中删除到数据库中所有表的其余部分。我是否必须逐一去所有的桌子,或者有办法通过编写脚本来做到这一点,以便我不必查找表格并删除记录,直到我完成了所有的表格。 – Tenzin 2011-03-19 23:05:35