我正在使用mysql,并且我有一个具有以下结构的表(摘要):
CREATE TABLE `costs` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`utility` DECIMAL(9,2) UNSIGNED NOT NULL,
`tax` DECIMAL(9,2) UNSIGNED NOT NULL,
`active` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`),
)
在插入时活动字段默认为1的地方,那么我想在保存新记录时将所有其他行的活动字段更新为0,因此我尝试为此创建一个触发器,但出现了mysql错误。 / p>
DELIMITER //
CREATE TRIGGER after_costs_insert AFTER INSERT ON costs FOR EACH ROW
BEGIN
UPDATE costs SET active = 0 WHERE id <> NEW.id;
END;
//
DELIMITER ;
我认为无法执行此操作,那么如何更新这些行?
答案 0 :(得分:0)
触发器无法操作对其触发的表。这是SQL中的典型限制,主要是为了防止调用时出现无限循环(查询触发触发器,执行查询,触发触发器,等等)。
在这里,我实际上建议使用一个视图来查询查询时动态计算列,而不是实际存储此派生信息。
如果您正在运行MySQL 8.0:
create view costs_view as
select
id,
utility,
tax,
row_number() over(order by id desc) = 1 active,
created_at,
updated_at
from costs
在早期版本中:
create view costs_view as
select
id,
utility,
tax,
id = (select max(id) from costs) active,
created_at,
updated_at
from costs
这将为您提供始终保持最新状态的列,而无需维护。
答案 1 :(得分:0)
如果只需要最近的行,则可以使用:
select c.*
from costs c
order by id desc -- or created_at
limit 1;
这将在视图中起作用。
更常见的情况是,您有一个有效的 per 东西-例如“实用程序”之类的东西。在这种情况下,您可以使用辅助表将每个“内容”中的一行与活动帐户的ID一起存储。触发器可以设定这个想法。
在您的情况下,costs
表中只有一个活动行,因此辅助表可能被认为是多余的。使用上面的查询,您可以轻松获得当前有效值。