我是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'。我该如何解决?
答案 0 :(得分:1)
您的DELETE
语句未引用aDeleteVariable
。 id
列仅存在于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);