0

我有两个表,分别称为 TableA 和 TableB。

表 A 具有以下字段:

TableA_ID
FileName

表 B 具有以下字段:

TableB_ID
TableA_ID
CreationDate

TableA_ID 字段上的两个表之间存在外键链接

我需要从两个表中删除记录。我需要查看 TableB 上的“CreationDate”,如果它在某个日期之后,请删除该记录。我还需要删除 TableA 中与 TableB 中的记录具有相同 TableA_ID 的记录

TableB 中可能有多个使用 TableA_ID 的记录(一对多关系)。因此,如果 TableB 中的条目仍在使用它,我无法删除 TableA 中的记录。

我知道这不能在单个语句中完成,但很高兴在事务中完成。我遇到的问题是我不知道该怎么做。我正在使用 MS SQL server 2008。如果可能的话,我不想使用触发器。

4

3 回答 3

5

表A中是否有记录而表B中没有匹配记录?如果没有,那么我们知道在我们从TableB中删除之后,我们可以删除TableA中任何不匹配的记录:

begin transaction
delete from TableB
where CreationDate > @SomeDate

delete from TableA
where TableA_ID not in (select TableA_ID from TableB)
end transaction

除此以外:

begin transaction
-- Save the TableA_IDs being deleted:
select distinct TableA_ID
into #TableA_Delete
from Table_B
where CreationDate > @Somedate

-- Depending on the expected size of #TableA_Delete, you may want 
-- to create an index here, to speed up the delete from TableA.

delete from TableB
where CreationDate > @SomeDate

delete from TableA
where TableA_id in (select TableA_Id from #TableA_Delete)
and TableA_id not in (select TableA_id from TableB)
commit transaction

注意上述两种解决方案都需要添加错误处理。

此外,请参阅 NYSystemsAnalyst 了解另一种临时存储 ID 的方法。

于 2009-12-17T17:07:07.313 回答
0

删除父行时,参照完整性应删除子行。确保启用了级联删除。

否则,您将不得不放入两个删除语句,一个用于子记录,一个用于父记录。

DELETE FROM TableB INNER JOIN TableA ON TableA.TableAID = TableB.TableAID WHERE CreationDate >= SomeDate

DELETE FROM TableA WHERE TableAID=SomeID
于 2009-12-17T16:45:02.757 回答
0

编辑:对不起,我没有看到您的问题的一部分,说明如果 TableA 条目在 TableB 中有多个记录,则需要保留它们。改用这个:

/* Table valued variable to hold Table A IDs to be deleted. */
DELCARE @IDs AS table
(
    ID int
);

/* Get the TableA IDs that are subject to deletion. */
INSERT INTO @IDs (
    ID
)SELECT TableA_ID
FROM TableB
WHERE CreationDate >= @MyCreationDate)
GROUP BY TableA_ID
HAVING (COUNT(TableA_ID) = 1); /* Only get IDs that appear once in TableB */

/* Delete the TableB records. */
DELETE b
FROM TableB AS b
WHERE CreationDate >= @MyCreationDate);

/* Delete the TableA records. */
DELETE a
FROM TableA AS a
    INNER JOIN @IDs AS c ON (a.TableA_ID = c.ID);

您应该将所有这些包装在事务中以确保数据完整性。

于 2009-12-17T16:48:19.333 回答