1

我有 2 张桌子:AB

A包含以下列:

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

B包含以下内容:

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

BA来自A_id列 (FK)的引用

问题:我想从表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 的记录。

4

3 回答 3

3

试试这个:

首先从tableB中删除:

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

然后从tableA中删除:

delete from tableA where checkpointId <= 1000
于 2012-08-07T13:08:27.500 回答
1

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

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

完成后,您可以通过检查不再在表 B 中的 ID 从表 A 中删除

delete from tableA where Id not in (select A_id from tableB)
于 2012-08-07T13:13:37.593 回答
1

您的第二个查询有一些缺陷:

  • 它是EXISTS而不是EXIST

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

  • 为表设置别名也是有用的,以减少代码并使其更具可读性,尤其是对于这么长的名称

  • 将 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 ;
于 2012-08-07T13:37:57.850 回答