删除具有外部约束的行而不使用“on cascade”

时间:2013-02-19 23:54:45

标签: sql tsql with-statement

我是SQL的新手,因为我通常可以通过简单的查询/迁移而不需要深入研究它,但是我有一个更复杂的,不涉及连接,我想知道当有一个时我如何删除不使用级联的外来约束。这是我的查询。我无法通过谷歌搜索找到一个好的答案。

WITH aDeleteVariable AS (SELECT TOP 1 FooID as id FROM [BSystem].[Foo].[bar] order by      
CreateTimeUTC desc)
DELETE FROM [BSystem].[Foo].[fooBar] where FooID = id
DELETE FROM [BSystem].[Foo].[bar] where FooID = id

所以我需要首先删除[BSystem]。[Foo] .fooBar,然后[BSystem]。[Foo]。[bar]这将在运行时执行,因此无法进行硬编码。 “1”确实是n,但是我已经解决了这个问题。

尝试执行此查询时,我得到无效的列名'id'。我该如何解决?

1 个答案:

答案 0 :(得分:1)

您的DELETE语句未引用aDeleteVariableid列仅存在于aDeleteVariable

的上下文中

您需要将aDeleteVariable加入DELETE语句中。此外,您不能重用公用表表达式,因此您必须复制它。

请参阅此SQL Fiddle (with simplified schema/table names),但以下是您的要求。

WITH aDeleteVariable AS (SELECT TOP 1 FooID as id
        FROM [BSystem].[Foo].[bar] order by CreateTimeUTC desc)
DELETE FB 
        FROM [BSystem].[Foo].[fooBar] AS FB
        INNER JOIN aDeleteVariable AS DV ON (FB.FooID = DV.id);
WITH aDeleteVariable AS (SELECT TOP 1 FooID as id
        FROM [BSystem].[Foo].[bar] order by CreateTimeUTC desc)
DELETE B
        FROM [BSystem].[Foo].[bar] AS B
        INNER JOIN aDeleteVariable AS DV ON (B.FooID = DV.id);

当然,加入aDeleteVariable后,您不需要id别名。以下将有效。

WITH aDeleteVariable AS (SELECT TOP 1 FooID
        FROM [BSystem].[Foo].[bar] order by CreateTimeUTC desc)
DELETE FB 
        FROM [BSystem].[Foo].[fooBar] AS FB
        INNER JOIN aDeleteVariable AS DV ON (FB.FooID = DV.FooID);
WITH aDeleteVariable AS (SELECT TOP 1 FooID
        FROM [BSystem].[Foo].[bar] order by CreateTimeUTC desc)
DELETE B
        FROM [BSystem].[Foo].[bar] AS B
        INNER JOIN aDeleteVariable AS DV ON (B.FooID = DV.FooID);

假设存在两个单独的公用表表达式,则存在竞争条件,第二个表达式可能返回不同的FooID(或者当您将其调整为N个记录时为多个)。您可能希望将您的ID选择到表变量中,而不是使用公用表表达式。以下应该有效。

DECLARE @DeleteVariable TABLE (FooID INT);
INSERT INTO @DeleteVariable (FooID)
        SELECT TOP 1 FooID FROM [BSystem].[Foo].[bar]
                ORDER BY CreateTimeUTC DESC;
DELETE FB 
        FROM [BSystem].[Foo].[fooBar] AS FB
        INNER JOIN @DeleteVariable AS DV ON (FB.FooID = DV.FooID);
DELETE B
        FROM [BSystem].[Foo].[bar] AS B
        INNER JOIN @DeleteVariable AS DV ON (B.FooID = DV.FooID);