Sql 从两个表中删除多条记录

Sql 从两个表中删除多条记录,sql,sql-server,delete-row,Sql,Sql Server,Delete Row,我有两张桌子,分别是TableA和TableB 表A包含以下字段: TableA_ID FileName TableB_ID TableA_ID CreationDate TableB具有以下字段: TableA_ID FileName TableB_ID TableA_ID CreationDate TableA_ID字段上的两个表之间存在外键链接 我需要从两个表中删除记录。我需要查看表B上的“CreationDate”,如果它在某个日期之后,请删除该记录。我还需要删除TableA中与

我有两张桌子,分别是TableA和TableB

表A包含以下字段:

TableA_ID
FileName
TableB_ID
TableA_ID
CreationDate
TableB具有以下字段:

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

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

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


我知道这不能在一个单一的声明中完成,但我很乐意在一个交易中完成。我的问题是我不知道怎么做。我正在使用MS SQL server 2008。如果可能的话,我不想使用触发器。

删除父行时,引用完整性应该删除子行。确保已启用级联删除

否则,您必须输入两个delete语句,一个用于子记录,另一个用于父记录

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

DELETE FROM TableA WHERE TableAID=SomeID

删除父行时,引用完整性应删除子行。确保已启用级联删除

否则,您必须输入两个delete语句,一个用于子记录,另一个用于父记录

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

DELETE FROM TableA WHERE TableAID=SomeID

编辑:对不起,我没有看到您问题中说明如果TableA条目在TableB中有多条记录,则需要保留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);

您应该将所有这些都打包到一个事务中,以确保数据的完整性。

编辑:对不起,我没有看到您问题中说明如果TableA条目在TableB中有多条记录,则需要保留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);

您应该将所有这些都打包到一个事务中,以确保数据的完整性。

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

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
注意上述两种解决方案都需要添加错误处理


另外,有关临时存储ID的另一种方法,请参见NYSystemsAnalyst。

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

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
注意上述两种解决方案都需要添加错误处理


另外,有关临时存储ID的另一种方法,请参见NYSystemsAnalyst。

他不能依赖引用删除级联,因为他不想删除创建状态为OK的TableB条目。级联删除会将它们删除。另外,您发布的两条语句从表B中删除了正确的条目,但是SomeID来自何处?SomeID只是一个参数。我假设他/她对SQL中的参数有某种了解。另外,有很多理由不使用级联删除。最好不要依赖于能够设置它,因为它可能会产生严重的性能问题。他不能依赖于引用删除级联,因为他不想删除创建的TableB条目Date是OK的。级联删除会将它们删除。另外,您发布的两条语句从表B中删除了正确的条目,但是SomeID来自何处?SomeID只是一个参数。我假设他/她对SQL中的参数有某种了解。另外,有很多理由不使用级联删除。最好不要依赖于能够设置它,因为它会造成严重的性能问题。填充@IDs的选择将不起作用。1) OP并没有说TableB中没有多行是按照TableA_ID被删除的。2)HAVING子句(逻辑上)发生在WHERE子句之后,因此如果有TableB记录没有被删除,HAVING子句将不会看到它们,也不会对它们进行计数。1)原始post状态“TableB中可能有多个记录使用TableA_ID(一对多关系)。因此,如果TableB中的条目仍然使用它,我就不能删除TableA中的记录。“因此,如果表B中有未被删除的条目,则无法删除表A记录。填充@IDs的选择将不起作用。1) OP并没有说TableB中没有多行是按照TableA_ID被删除的。2)HAVING子句(逻辑上)发生在WHERE子句之后,因此如果有TableB记录没有被删除,HAVING子句将不会看到它们,也不会对它们进行计数。1)原始post状态“TableB中可能有多个记录使用TableA_ID(一对多关系)。因此,如果表B中的条目仍在使用,我就不能删除表A中的记录。”因此,如果表B中的条目未被删除,则不能删除表A记录。+1 Shannon的解决方案解决了我下面的解决方案中WHERE…GROUP BY子句的缺点。由于某种原因,由于最后一个“WHERE”而无法保存“声明。我会摆弄它,但有人能发现是不是少了什么吗?@Retrocoder:对不起,最后一个地方是积垢留下的,没有用。编辑以修复。+1 Shannon的解决方案解决了下面我的解决方案中WHERE…GROUP BY子句的缺点。由于某种原因,由于最后一个“WHERE”语句,无法保存。我会摆弄它,但有人能发现是不是少了什么吗?@Retrocoder:对不起,最后一个地方是积垢留下的,没有用。编辑以修复。