УДАЛИТЬ, ГДЕ НЕ СУЩЕСТВУЕТ Неправильное применение - PullRequest
0 голосов
/ 04 декабря 2018

Я использую NOT EXISTS во время оператора DELETE в хранимой процедуре, а not not не применяется к данным.

Используя следующие данные примера:

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, вы увидите, что процедура не обрабатывает фильтр по регионам.

EG

EXEC udsp_GetOrdersOfXAmount 10,3

Однако, если вы запустите подзапрос, используемый в операторе DELETE, как его собственный запрос, вы увидите, что предоставленная логика предложения WHERE работает.Я не понимаю, почему он не работает при использовании с NOT EXISTS в операторе DELETE.

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

Заранее благодарю за любую помощь, которую вы можете предоставить.

1 Ответ

0 голосов
/ 04 декабря 2018

Вам не нужно объединение во внутреннем запросе.
Тот факт, что вы используете один и тот же псевдоним для внешнего запроса и внутренний, сбивает меня с толку, я предполагаю, что 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
    )
...