Heads up! This post was written 15 years ago. Some information might be outdated or may have changed since then.
Първо какво са тригерите в Mysql ? В общи линии това са обекти които са асоциирани с таблица и се активират при изпълняването на INSERT, UPDATE, DELETE в асоциираната им таблица. Синтаксиса за създаване на trigger под mysql e
CREATE 
    [DEFINER = { user | CURRENT_USER }] 
TRIGGER trigger_name 
    trigger_time trigger_event 
ON tbl_name 
FOR EACH ROW 
    trigger_body
Какво искам да постигна ... В общи линии целта ми е много проста, имам таблица с езикови низове и при обновяване на даден низ от тази таблица, предишната му стойност да се записва в друга таблица с цел справка при необходимост. Така нека първо да създадем таблицата към която ще "вържем" тригера.
CREATE TABLE `site_languages` (
    `site_languages_id` INT(10) NOT NULL AUTO_INCREMENT,
    `site_languages_key` VARCHAR(250) NOT NULL,
    `site_languages_value` TEXT NULL,
    `site_languages_lang` CHAR(5) NULL DEFAULT NULL,
    `site_languages_file` CHAR(5) NOT NULL,
    PRIMARY KEY (`site_languages_id`),
    INDEX `site_languages_key` (`site_languages_key`),
    INDEX `site_languages_lang` (`site_languages_lang`)
) ENGINE=InnoDB ROW_FORMAT=DEFAULT AUTO_INCREMENT=1
и след това таблицата където ще се пазят старите версии на езиковия низ.
CREATE TABLE `site_languages_versions` (
    `site_languages_id` INT(10) NOT NULL AUTO_INCREMENT,
    `site_languages_lang_id` INT(10) NOT NULL DEFAULT '0',
    `site_languages_key` VARCHAR(250) NOT NULL,
    `site_languages_value` TEXT NULL,
    `site_languages_lang` CHAR(5) NULL DEFAULT NULL,
    `site_languages_timestamp` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`site_languages_id`),
    INDEX `site_languages_key` (`site_languages_key`),
    INDEX `FK_site_languages_versions_site_languages` (`site_languages_lang_id`),
    CONSTRAINT `FK_site_languages_versions_site_languages` FOREIGN KEY (`site_languages_lang_id`)
        REFERENCES `site_languages` (`site_languages_id`) ON UPDATE NO ACTION ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=DEFAULT
пс: в примерния код има добавени и Foreign keys-ове които можете да премахнете :) Така нека създадем и тригера който ще свърши работата :)
DELIMITER //
CREATE TRIGGER `before_site_languages_update` 
BEFORE UPDATE ON `site_languages` 
FOR EACH ROW 
BEGIN 
    INSERT INTO `site_languages_versions` 
    (`site_languages_key`,`site_languages_lang_id`, `site_languages_value`,`site_languages_lang`) 
    VALUES 
    (
        OLD.`site_languages_key`,
        OLD.`site_languages_id`, 
        OLD.`site_languages_value`,
        OLD.`site_languages_lang`
    ); 
END//
DELIMITER ;
Ta нека се опитам да обясня какво се случва ред по ред.
FOR EACH ROW
BEGIN
    IF NEW.is_default = 1 THEN
        UPDATE site_languages 
        SET is_default = 0 
        WHERE site_id = NEW.site_id 
        AND is_default = 1;
    END IF;
END;
С този ред създаваме тригер с име "before_site_languages_update" който ще се задейства преди да се обнови таблицата site_languages, именно този ред " BEFORE UPDATE ON" посочва кога да се задейства въпросния тригер. След това имаме "FOR EACH ROW BEGIN" с който казваме че за всеки ROW
INSERT INTO `site_languages_versions` 
(`site_languages_key`, `site_languages_lang_id`, `site_languages_value`, `site_languages_lang`) 
VALUES 
(OLD.`site_languages_key`, OLD.`site_languages_id`, OLD.`site_languages_value`, OLD.`site_languages_lang`);
Взимаме старата информация с "OLD." и го добавяме в 'site_languages_versions' таблицата. Завършваме с "END//". Ами това е :) Изглежда простичко но върша добра работа. Важно е да се знае че тригерът не може да се асоциира с темп таблица или view, също така създаването на тригери е налично от версия 5.0.2 на Mysql Линкове: http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html

Back to all posts