我有一张表,其中定义了员工关系。 即。
EmpID Name SeniorId
-----------------------
1 A NULL
2 B 1
3 C 1
4 D 3
依旧......
其中,高级ID是外键,其主键表与引用列EmpId相同 我想清除此表中的所有行而不删除任何约束。我怎么能这样做?
删除需要像这样执行 4,3,2,1
我该怎么做
修改
Jhonny的答案对我有用,但哪些答案更有效。
答案 0 :(得分:16)
我不知道我是否遗漏了某些东西,但也许你可以尝试一下。
UPDATE employee SET SeniorID = NULL
DELETE FROM employee
答案 1 :(得分:3)
如果表非常大(基数为数百万),并且不需要记录DELETE事务,则删除约束和TRUNCATEing并重新创建约束是迄今为止最有效的方法。此外,如果其他表中存在外键(并且在此特定表设计中似乎是这样),那么在所有情况下都必须首先删除这些行。
规范化没有提及递归/层次/树关系,所以我相信这是你回答DVK建议将其拆分成自己的表时的红色鲱鱼 - 这个表的垂直分区肯定是可行的还要考虑你是否可以利用它来获得我在下面列出的任何其他好处。正如DVK所暗示的,在这个特定的设计中,我经常看到一个单独的链接表来记录自我关系和其他类型的关系。这有很多好处:
当然,与这种关系有关的信息越多,就越强烈地表明关系本身就是一个表(即它是关系数据库中使用的真正意义上的“关系” - 相关数据存储在与主键相关的关系或表中,因此关系的正常形式可能强烈表明在employee表中创建关系表而不是简单的外键关系。
好处还包括其简单的删除方案:
DELETE FROM EmployeeRelationships;
DELETE FROM Employee;
你会注意到SO上接受的答案的惊人等价,因为在你的情况下,没有高级关系的员工有一个NULL - 所以在那个答案中,海报首先将所有设置为NULL以消除关系,然后删除员工。
TRUNCATE可能有适当的用法取决于约束(EmpployeeRelationships通常可以是TRUNCATEd,因为它的主键通常是复合而不是任何其他表中的外键)。
答案 2 :(得分:2)
试试这个
DELETE FROM employee;
答案 3 :(得分:1)
在循环内部,运行一个命令,删除具有未引用的EmpID的所有行,直到剩下零行为止。编写内部DELETE命令有多种方法:
DELETE FROM employee WHERE EmpID NOT IN (SELECT SeniorID FROM employee)
DELETE FROM employee e1 WHERE NOT EXISTS
(SELECT * FROM employee e2 WHERE e2.SeniorID = e.EmpID
可能是使用JOIN的第三个,但我不熟悉SQL Server语法。
答案 4 :(得分:1)
一种解决方案是通过将“高级”关系拆分为单独的表来规范化。为了一般性,请将第二个表格设为“empID1 | empID2 | relationship_type”。
除此之外,您需要循环执行此操作。一种方法是:
declare @count int
select @count=count(1) from table
while (@count > 0)
BEGIN
delete employee WHERE NOT EXISTS
(select 1 from employee 'e_senior'
where employee.EmpID=e_senior.SeniorID)
select @count=count(1) from table
END