2012-08-07 115 views
0

我有2个表:A和BDELETE FROM表A和B的多条记录与一个FK表B

A包含以下几列:

Id [uniqueIdentifier] -PK 
checkpointId [numeric(20,0)] 

B包含以下内容:

Id [uniqueIdentifier] – PK 
A_id (FK, uniqueIdentifier) 

B具有从A_ID柱(FK)

问题至A的引用: 我想从表A中删除所有的记录,他们的checkpoint_id是小于X

delete from CheckpointStorageObject where checkpointIdentifierIdentifier <= 1000 

但我不能这样做,因为"The primary key value cannot be deleted because references to this key still exist"

我试过的B表先删除没有加入:

DELETE FROM CheckpointToProtectionGroup 
WHERE EXIST (SELECT * from CheckpointStorageObject 
      WHERE CheckpointStorageObject.CheckpointIdentifierIdentifier <= 1000) 

但它没有奏效。

我该怎么办? 是否可以使用一个执行命令从两个表中删除?

结果删除的记录可能非常大 - 每张表中超过30K条记录。

回答

2

试试这个:

首先从tableB的删除:

delete from tableB where A_id IN (Select Id from tableA where checkpointId <= 1000) 

然后再从表A中删除:

delete from tableA where checkpointId <= 1000 
0

您必须首先从表B中删除的条目

delete from tableB where A_id IN (Select Id from tableA where checkpointIdentifierIdentifier <= 1000) 

一旦做到这一点,你可以从表A中删除,通过检查不再在表B中的ID

delete from tableA where Id not in (select A_id from tableB) 
0

你的第二个查询有一定的缺陷:

  • EXISTS而不是EXIST

  • 您需要指定2个表格之间的连接条件。在相关子查询像这样的,你WHERE条款

  • 它也usfeul有别名为表,以减少代码,并使其更具可读性,尤其是在这么长的名字

  • 围在添加THI scondition事务中的2条语句,以确保它成功 - 并从两个表中删除 - 或者失败并删除任何内容。如果您不使用事务,则第二次删除可能会失败,如果在两次删除之间的一小段时间内,在表B处插入一行并引用表A中第二条语句将尝试删除的行。

所以,从表B中先删除(CheckpointToProtectionGroup):

BEGIN TRANSACTION 

    DELETE FROM CheckpointToProtectionGroup AS b 
    WHERE EXISTS         --- EXISTS 
      (SELECT * 
      FROM CheckpointStorageObject AS a 
      WHERE a.id = b.A_id     --- join condition 
       AND a.CheckpointId <= 1000 
     ) ; 

,然后从表A(CheckpointStorageObject):

DELETE FROM CheckpointStorageObject 
    WHERE CheckpointId <= 1000 ; 

COMMIT TRANSACTION ; 
+0

我editted到存在EXIST – Haimon 2012-08-07 14:04:16