触发在MySQL中更新同一表中的多条记录

触发在MySQL中更新同一表中的多条记录,mysql,Mysql,我有一张简单的桌子: CREATE TABLE `accounting`.`People` ( `ID` INT NOT NULL AUTO_INCREMENT , `Name` VARCHAR(45) NULL , `Property_number` VARCHAR(45) NULL , `People_at_Location` INT NULL , PRIMARY KEY (`ID`) ); INSERT INTO `accounting`.`People` (`Na

我有一张简单的桌子:

CREATE  TABLE `accounting`.`People` (
  `ID` INT NOT NULL AUTO_INCREMENT ,
  `Name` VARCHAR(45) NULL ,
  `Property_number` VARCHAR(45) NULL ,
  `People_at_Location` INT NULL ,
  PRIMARY KEY (`ID`) );

INSERT INTO `accounting`.`People` (`Name`, `Property_number`, `People_at_Location`) VALUES ('Jim', '13', '2');
INSERT INTO `accounting`.`People` (`Name`, `Property_number`) VALUES ('Tony', '16');
INSERT INTO `accounting`.`People` (`Name`, `Property_number`) VALUES ('Alice', '9');
INSERT INTO `accounting`.`People` (`Name`, `Property_number`, `People_at_Location`) VALUES ('Martha', '13', '2');
INSERT INTO `accounting`.`People` (`Name`, `Property_number`) VALUES ('Vandy', '');
在我们的数据中,我们知道每一行/记录的名称。但是当我们开始的时候,我们没有房地产号码。当我们收到客户发来的电子邮件时,我们会得到他们的房产号,并更新记录

我们真正需要的是一个触发器,它查看属性号并查询数据库中有多少其他记录具有相同的属性号,并更新所有记录,因为我们现在知道该属性号上还有一个人

例如(给定上面的示例数据),它看起来像:

ID     Name     Property_number     People_at_location
1      Jim      13                  2
2      Tony     16                  Null
3      Alice    9                   1
4      Martha   13                  2
5      Vandy    Null                Null      
所以我们从Vandy那里得到了新的信息,告诉我们她在13号酒店。我们希望更新记录1、4和5,以反映更新后的地点人数

ID     Name     Property_number     People_at_location
1      Jim      13                  3
2      Tony     16                  Null
3      Alice    9                   1
4      Martha   13                  3
5      Vandy    13                  3      

这个触发器是什么样子的?

一般形式是这样的(从内存中执行,因此可能会有一些语法错误):

对于当前计数为
NULL
(如示例中的ID 2)的记录,这也应该可以正常工作,尽管这些记录在当前数据状态下显然是错误的(我看不出为什么你有一个非
NULL
属性号
,但在某个位置有一个
NULL
人,这毫无意义)


我假设您可能希望在插入新记录时执行相同的计算,在这种情况下,您应该将逻辑提取到存储过程中,并在触发器期间调用该过程,而不是复制代码。

这一答案被标记为已接受,这着实令人惊讶。如果您只是尝试一下(在纠正了一些小错误之后),您应该(而且您会)明显地得到一个“#1442-无法更新存储函数/触发器中的表'People',因为调用此存储函数/触发器的语句已经使用了它。”错误。
CREATE TRIGGER update_people_at_location
    AFTER UPDATE ON People FOR EACH ROW
    BEGIN 
        // make sure we updated the property number from a NULL value to a non null
        // depending on your exact use case you may or may not want that check
        IF (OLD.Property_number IS NULL AND NEW.Property_number IS NOT NULL) THEN
           -- store the count for this property_number
           -- we are in an AFTER UPDATE trigger so the update is already done,
           --   which means this count will include the newly set value
           DECLARE total_people_at_location int;
           SELECT COUNT(*) INTO total_people_at_location FROM People WHERE Property_number = NEW.Propery_number;
           -- update the rows with the proper count
           UPDATE People SET People_at_location = total_people_at_location WHERE Property_number = NEW.Propery_number;
        END IF;
    END