2013-07-09 3 views
-1

У меня есть простая таблицаmySqlTrigger изменение та же таблица, что существует

CREATE TABLE `accounting`.`Foo` (
    `ID` INT NOT NULL AUTO_INCREMENT , 
    `This` VARCHAR(45) NULL , 
    `That` VARCHAR(45) NULL , 
    `The_Other` VARCHAR(45) NULL , 
    `Times_altered` INT NULL , 
    PRIMARY KEY (`ID`)); 

Я хочу, чтобы триггер просто подсчитывает ЗАМЕСТИТЕЛЬ раз, что эта запись изменена. Мой «DBA» говорит мне, что я не могу изменить таблицу, в которой я нахожусь в Mysql, с триггером, поскольку это вызовет «цикл».

Я не парень SQL: но мне что-то говорит, что мне нужен новый администратор базы данных.

Действительно ли это так?

Cant Я просто увеличиваю Times_altered INT NULL?

+0

Отрицательная обратная связь по-прежнему лучше и вежливее, чем никакая обратная связь, вы знаете? В конце концов, мы вкладываем время и стараемся помочь вам. – fancyPants

ответ

1

Что-то вроде этого:

CREATE TABLE `accounting`.`Foo` (
    `ID` INT NOT NULL AUTO_INCREMENT , 
    `This` VARCHAR(45) NULL , 
    `That` VARCHAR(45) NULL , 
    `The_Other` VARCHAR(45) NULL , 
    `Times_altered` INT NULL , 
    PRIMARY KEY (`ID`)); 

CREATE TABLE `accounting`.`logs` (
    `ID` INT NOT NULL AUTO_INCREMENT , 
    `table` VARCHAR(45) NULL , 
    `update_count` int NULL , 
    PRIMARY KEY (`ID`)); 

CREATE TRIGGER `update_counter` UPDATE ON `Foo` 
FOR EACH ROW BEGIN 
    INSERT INTO logs SET update_count = update_count + 1 WHERE table = 'Foo'; 
END; 

Примечание: Приведенный выше код не проверяется.
http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html

1

Триггер действительно не правильный выбор. Триггер в MySQL активируется для каждой строки, затронутой вашим оператором обновления, а это означает, что если вы обновляете 10 строк, столбец Times_altered в вашем проекте обновляется 10 раз. И должно ли такое же значение в Times_altered быть во всех строках таблицы или только в одном? В любом случае, не лучший дизайн, на мой взгляд.

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

Я хотел бы предложить, либо вы делаете это так:

CREATE TABLE `accounting`.`Foo` (
    `ID` INT NOT NULL AUTO_INCREMENT , 
    `This` VARCHAR(45) NULL , 
    `That` VARCHAR(45) NULL , 
    `The_Other` VARCHAR(45) NULL , 
    PRIMARY KEY (`ID`)); 

CREATE TABLE `accounting`.`logs` (
    `ID` INT NOT NULL AUTO_INCREMENT , 
    `table` VARCHAR(45) NULL , 
    `update_count` int NULL , 
    PRIMARY KEY (`ID`)); 

SET TRANSACTION ISOLATION LEVEL READ-COMMITED; 
START TRANSACTION; 
UPDATE Foo SET whatever = whatever; 
UPDATE logs SET update_count = update_count + 1 WHERE table = 'Foo'; 
COMMIT; 

Почему сделка? Это необходимо для обеспечения безопасности процесса.

Или использовать хранимую процедуру (что-то вроде этого):

DELIMITER $$ 
CREATE PROCEDURE my_update (IN stmt varchar(1000), IN tablename varchar(100)) 
BEGIN 
SET @sql = stmt; 
PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE stmt; 
SET @sql = CONCAT('UPDATE logs SET update_count = update_count + 1 WHERE table = ', tablename, ';'); 
PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE stmt; 
END $$ 
DELIMITER ; 

Тогда вы бы использовать процедуру, как это:

SET TRANSACTION ISOLATION LEVEL READ-COMMITED; 
START TRANSACTION; 
CALL my_update('UPDATE Foo SET whatever = whatever', 'Foo'); 
COMMIT; 

Или вы положили start transaction в процедуру.

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