我有两个名为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.如果可能,我不想使用触发器。
答案 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);
您应该在事务中包装所有这些以确保数据完整性。