【问题标题】:DELETE WHERE NOT EXISTS Not Being Applied CorrectlyDELETE WHERE NOT EXISTS 未正确应用
【发布时间】:2018-12-04 16:12:37
【问题描述】:

我在存储过程的 DELETE 语句期间使用 NOT EXISTS,并且未将不存在应用于数据。

使用以下示例数据:

CREATE TABLE Region
(
    RegionID INT IDENTITY(1,1)
    ,RegionName VARCHAR(25)
)

GO

INSERT INTO Region(RegionName)
VALUES ('East Coast')
    ,('Mid West')
    ,('West Coast')

GO

CREATE TABLE Customer
(
    CustomerID INT IDENTITY(1,1)
    ,FirstName VARCHAR(5)
    ,Region INT
)

GO 

INSERT INTO Customer(FirstName,Region)
VALUES('Tom',1)
    ,('Mike',2)
    ,('Jean',3)

GO

CREATE TABLE Orders
(
    OrderID INT IDENTITY(1,1)
    ,CustomerID INT
    ,OrderAmount INT
    ,OrderDate DATE
)

GO 

INSERT INTO Orders(CustomerID,OrderAmount,OrderDate)
VALUES(1,10,'2018-11-30')
    ,(2,12,'2018-11-30')
    ,(2,15,'2018-12-01')
    ,(2,8,'2018-12-02')
    ,(2,11,'2018-12-03')
    ,(3,13,'2018-12-01')
    ,(3,20,'2018-12-03')

GO

使用该数据,我正在尝试创建一个执行以下操作的过程:

CREATE PROCEDURE udsp_GetOrdersOfXAmount @OrderAmount INT, @RegionID INT = 0
AS
BEGIN

DECLARE @ProcedureTemp TABLE
(
    OrderID INT
    ,CustomerID INT
    ,OrderAmount INT
    ,OrderDate DATE
)

INSERT INTO @ProcedureTemp(OrderID,CustomerID,OrderAmount,OrderDate)
SELECT * FROM Orders WHERE OrderAmount >= @OrderAmount

--Do several other UPDATES/ DELETES to @ProcedureTemp

--This is where the issue lies
IF @RegionID > 0 
BEGIN
    DELETE T FROM @ProcedureTemp T
    WHERE NOT EXISTS
        (
            SELECT *
            FROM Customer C
                JOIN @ProcedureTemp T ON T.CustomerID = C.CustomerID
            WHERE C.Region = @RegionID
        )
END

SELECT * FROM @ProcedureTemp

END

GO

如果您在填充了@RegionID 参数的情况下执行该过程,您将看到该过程不支持按区域筛选。

例如

EXEC udsp_GetOrdersOfXAmount 10,3

但是,如果您将 DELETE 语句中使用的子查询作为其自己的查询运行,您将看到提供的 WHERE 子句逻辑正在运行。我不明白为什么它在 DELETE 语句中与 NOT EXISTS 一起使用时不起作用。

DECLARE @OrderAmount INT = 10, @RegionID INT = 3

DECLARE @ProcedureTemp TABLE
(
    OrderID INT
    ,CustomerID INT
    ,OrderAmount INT
    ,OrderDate DATE
)

INSERT INTO @ProcedureTemp(OrderID,CustomerID,OrderAmount,OrderDate)
SELECT * FROM Orders WHERE OrderAmount >= @OrderAmount

SELECT *
FROM Customer C
    JOIN @ProcedureTemp T ON T.CustomerID = C.CustomerID
WHERE C.Region = @RegionID

提前感谢您提供的任何帮助。

【问题讨论】:

    标签: tsql sql-delete exists


    【解决方案1】:

    您不需要内部查询中的联接。
    您对外部查询和内部查询使用相同的别名这一事实让我感到困惑,我猜 SQL Server 也应该有问题。 试试这样写:

    DELETE T 
    FROM @ProcedureTemp T
    WHERE NOT EXISTS
        (
            SELECT *
            FROM Customer C
            -- You already have the T from the outer statement
            WHERE T.CustomerID = C.CustomerID
            AND C.Region = @RegionID
        )
    

    【讨论】:

    • 感谢 m8,工作就像一个魅力。另外,我尝试根据您的评论更改原始子查询中连接的别名,效果也很好。
    • 很高兴为您提供帮助 :-)
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2016-05-19
    • 2018-01-08
    • 2012-01-19
    相关资源
    最近更新 更多