从两个表中删除多个记录

时间:2009-12-17 16:41:36

标签: sql sql-server delete-row

我有两个名为TableA和TableB的表。

TableA包含以下字段:

TableA_ID
FileName

TableB包含以下字段:

TableB_ID
TableA_ID
CreationDate

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

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

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

我知道这不能在一个声明中完成,但很高兴在交易中这样做。我遇到的问题是我不知道该怎么做。我正在使用MS SQL server 2008.如果可能,我不想使用触发器。

3 个答案:

答案 0 :(得分:5)

TableA中是否有记录,TableB中没有匹配的记录?如果没有,那么我们知道从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的另一种方法。

答案 1 :(得分:0)

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

否则,你必须为子记录输入一个删除语句,为父记录输入一个。

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

DELETE FROM TableA WHERE TableAID=SomeID

答案 2 :(得分:0)

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

/* 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);

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

相关问题