DELETE WHERE NOT EXISTS 应用不正确
DELETE WHERE NOT EXISTS Not Being Applied Correctly
我在存储过程中的 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
提前感谢您提供的任何帮助。
您不需要在内部查询中加入。
您对外部查询和内部查询使用相同的别名这一事实让我感到困惑,我猜 SQL 服务器也应该有问题。
试试这样写:
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
)
我在存储过程中的 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
提前感谢您提供的任何帮助。
您不需要在内部查询中加入。
您对外部查询和内部查询使用相同的别名这一事实让我感到困惑,我猜 SQL 服务器也应该有问题。
试试这样写:
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
)