【发布时间】:2015-11-27 15:34:08
【问题描述】:
我正在尝试使用来自另一个表的触发器来更新一个表。我认为这将是一个非常简单的查询,但我最初提出的查询不起作用,我不明白为什么。
CREATE TABLE [dbo].[Vehicle](
[id] [int] IDENTITY(1,1) NOT NULL,
[plate] [nvarchar](50) NOT NULL,
[name] [nvarchar](50) NOT NULL,
[dateUsed] [datetime] NULL
)
CREATE TABLE [dbo].[Transaction](
[id] [int] IDENTITY(1,1) NOT NULL,
[vehicleId] [int] NOT NULL,
[quantity] [float] NOT NULL,
[dateTransaction] [datetime] NOT NULL,
)
添加事务后,我希望更新 Vehicle 表。如果添加的dateTransaction 晚于dateUsed,则应更新它,以便dateUsed 字段始终包含该特定车辆的最新日期。
我认为这个触发器应该可以解决问题.. 但它没有:
UPDATE [Vehicle]
SET [dateUsed] =
CASE
WHEN [dateUsed] < [Transaction].[dateTransaction]
OR [dateUsed] IS NULL
THEN [Transaction].[dateTransaction]
ELSE [dateUsed]
END
FROM [Transaction]
WHERE [Vehicle].[id]=[Transaction].[vehicleId]
对我来说看起来不错...它应该遍历所有新插入的记录并更新dateUsed 字段。如果dateTransaction 较新,请使用那个.. 如果不是.. 使用当前的。但我似乎遗漏了一些东西,因为它没有更新到最新日期。它确实与该特定车辆的一项交易匹配,但与最新的交易不匹配。
一个有效的查询:
UPDATE [Vehicle]
SET [dateUsed] = InsertedPartitioned.[dateTransaction]
FROM [Vehicle]
LEFT JOIN (
SELECT
[vehicleId],
[dateTransaction],
ROW_NUMBER() OVER(PARTITION BY [VehicleId] ORDER BY [dateTransaction] DESC) AS RC
FROM [Inserted]) AS InsertedPartitioned
ON InsertedPartitioned.RC=1
AND InsertedPartitioned.[vehicleId]=[Vehicle].[id]
WHERE InsertedPartitioned.[vehicleId] IS NOT NULL
AND ([Vehicle].[dateUsed] IS NULL
OR InsertedPartitioned.[dateTransaction] > [Vehicle].[dateUsed]);
所以我有一个可行的解决方案,它甚至可能会更好(还没有用大插入来计时)但是它让我不知道为什么第一个它不起作用!
任何人都可以“启发我”吗?
【问题讨论】:
-
您使用的是哪种 dbms 产品? (看起来不像 ANSI SQL……而且大多数产品的触发器都不符合 ANSI。)
-
根据使用的语法重新标记为
sql-server
标签: sql-server tsql sql-update database-trigger