SQL - 触发更新错误

Posted

技术标签:

【中文标题】SQL - 触发更新错误【英文标题】:SQL - Trigger Update Error 【发布时间】:2016-12-20 21:41:30 【问题描述】:

我开始学习 SQL,并创建了一个房屋数据库,其中有一个房屋、房间、走廊等表格。我在房屋中有一个名为 NumberOfRooms 的列,在房间中有一个称为 HouseName 的列。

我正在尝试创建一个触发器,以便在将房间添加到房屋时,房屋属性“NumberOfRooms”会增加。

这是我正在尝试的查询:

CREATE TRIGGER UpdateNoRooms AFTER INSERT AS 
UPDATE Houses SET Houses.NumberOfRooms = SELECT COUNT(Room) 
                                         FROM Rooms 
                                         WHERE Rooms.HouseName = Houses.Name;

,但它不起作用。

这是我收到的错误消息:

ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 mysql 服务器版本相对应的手册,以在第 1 行的“AS UPDATE Houses SET Houses.NumberOfRooms = SELECT COUNT(Room) FROM Rooms WHERE”附近使用正确的语法

关于如何解决此问题的任何想法?提前谢谢你

【问题讨论】:

【参考方案1】:

这是一个快速版本 - 你已经非规范化 - 这不是一个好主意。而是房间数应该留给查询时间。

CREATE TRIGGER UpdateNoRooms AFTER INSERT AS
BEGIN
    UPDATE Houses h
        SET h.NumberOfRooms = h.NumberofRooms+1 WHERE :new.HouseName = h.Name;
END;

【讨论】:

你不应该在new.HouseName之前有: 我有一个问题,“新”从何而来?这是一个 SQL 术语吗? 实际上,很多时候这样做是合适的,因为在查询时执行此操作可能需要很长时间才能报告针对数百万行的查询。通过在触发器中执行此操作,您可以完美地保持数字。但是,如果可以删除记录,您可能还需要删除后触发器。 New 是一个伪表,其中包含插入的结果集。它只能在触发器中访问。对于更新,您将拥有旧表和新表,而删除将只有旧表,其中包含删除之前记录中的数据。..【参考方案2】:

请参阅MySQL documentation 中的语法图。您缺少命令的几个必需部分:

    您需要ON tablename 告诉它应该将触发器附加到哪个表。

    您需要在触发器主体之前使用FOR EACH ROW

    您无需计算房间数。添加房间只会将房间数量增加 1。

应该是这样的:

CREATR TRIGGER UpdateNoRooms 
AFTER INSERT ON Rooms
FOR EACH ROW
    UPDATE Houses AS h
    SET h.NumberOfRooms = h.NumberOfRooms + 1
    WHERE h.HouseName = NEW.HouseName

【讨论】:

以上是关于SQL - 触发更新错误的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 触发器得到一个变异表错误

在 Oracle PL/SQL 中创建触发器时如何解决“编译错误成功”错误?

更新后触发,错误:标量子查询只允许返回单行

更新错误后的 DB2 触发器

MySql 错误:无法更新存储函数/触发器中的表

空字符串无法解释的MySQL错误#1064创建更新触发器后?