2013-06-17 14 views
1

У меня есть простая таблица:Trigger обновление нескольких записей в одной таблице в 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` (`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', ''); 

В наших данных мы знаем имя для каждой строки/записи. Но когда мы начали, у нас не было Property_number. Когда мы получаем электронное письмо от наших клиентов, мы получаем их Property_number, и мы обновляем запись.

Что нам действительно нужно, это триггер, который смотрит на Property_number и запросы, чтобы узнать, сколько других записей в базе данных имеет одинаковый номер свойства и обновляет все записи, поскольку мы теперь знаем, что дополнительный человек находится в этом Property_number.

Например (учитывая данные примера выше) это выглядит следующим образом:

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  

Таким образом мы получаем новую информацию из Ванды, которая говорит нам, что она находится в PROPERTY_NUMBER 13. Мы хотим, чтобы обновить запись 1, 4 и 5 чтобы отразить обновленный счет People_at_location.

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  

Как будет выглядеть этот триггер?

ответ

2

Общий вид будет что-то вроде этого (сделано из памяти, так что может быть несколько синтаксических ошибок):

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 

Это также должно работать нормально с записями, которые имеют свой текущий счет на NULL (например, ID 2 в вашем примере), хотя эти данные, очевидно, неверны в вашем текущем состоянии данных (я не вижу причин, по которым у вас есть не Property_number, а NULLPeople_at_location, что не имеет смысла);

Я полагаю, что вы, вероятно, захотите сделать то же вычисление на вставке новой записи, и в этом случае вы должны извлечь логику в хранимую процедуру и вызвать эту процедуру во время триггера вместо дублирования кода.

+0

Удивительно, что этот ответ отмечен как принятый. Если вы просто попробуете (после исправления незначительных ошибок), вы должны (и вы будете), очевидно, получить «# 1442 - Не можете обновить таблицу« Люди »в хранимой функции/триггере, потому что она уже используется выражением, которое вызывается эта сохраненная функция/триггер. " ошибка. –

Смежные вопросы