MySQL создает сбой триггера «перед вставкой» и вызывает ошибки в триггерах

0

Я успешно создал вставку перед триггером в таблице, используя механизм innodb, который "выдает" ошибку, выполняя вставку в несуществующей таблице. Проблема в том, что при попытке запустить создание базы данных script на производственном сервере это не удается, потому что таблица вставки не существует. Однако тот же самый script отлично работает на моей рабочей станции, что заставляет меня думать, что существует параметр конфигурации MySQL, вызывающий сбой создания script.

Вопрос, который возникает у моей проблемы, заключается в том, является ли производственный сервер компилятором триггера, а моя рабочая станция не является (или компилируется во время выполнения). В производственной среде я бы предпочел, чтобы SQL был скомпилирован при создании.

Теги:
error-handling
triggers

2 ответа

0

Оказывается, длина имени таблицы вызывала проблему. Две версии сервера были из разных выпусков, причем сервер был предыдущим выпуском (5.0 против 5.1).

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

Как только ошибка встречается (ожидаемая ошибка), я устанавливаю переменную сеанса (имя переменной с префиксом @) с отображаемым сообщением об ошибке. Как только сообщение об ошибке установлено, я вставляю в несуществующую таблицу Die, чтобы вызвать ошибку в MySQL.

Затем приложение захватывает ошибку базы данных и выполняет запрос в переменной сеанса ошибки. Основываясь на результате, я либо выдаю исключение из сообщения об ошибке, либо сообщение об ошибке базы данных, либо спокойно запрашивает запрос, оставляя вызывающий код обрабатывать сбойный запрос.

MySQL Trigger:

CREATE TRIGGER Error_Trigger 
BEFORE INSERT ON Fubar 
FOR EACH ROW
BEGIN
    if DataIsBad then
        set @Err = 'The data is fubared.';
        insert into Die values (1);                
    end if;    
END$$

Код приложения:

public function getDatabaseErrorMessage($AdminMessage = false){
    if ($this->db->_error_number() != 0){
        $AdminError = $this->db->_error_message();
        $Query = $this->db->query("select @Err");
        if ($Query){
            $Error = $Query->row_array();
        }
        if (isset($Error["@Err"]) && $Error["@Err"] != ""){
            $Error = $Error["@Err"];
            $this->db->query("set @Err = ''");
        } else {
            if ($AdminMessage){
                $Error = $AdminError;
            } else {
                return false;
            }
        }
        throw new Exception($Error);
    }
}
0

Мой метод моделирования повышения ошибки в триггере - это DECLARE целочисленная переменная и сохранение в ней строки. Если у вас есть SQL_MODE = STRICT_ALL_TABLES, это вызывает ошибку. В противном случае возникает предупреждение.

use test;

drop table if exists foo;
create table foo (id serial primary key, bar varchar(10));

drop trigger if exists RaiseError;

delimiter //

create trigger RaiseError before insert on foo
for each row
begin
  declare bar int;
  if new.bar = 'boom' then
    set bar = 'You cannot store that value!';
  end if;
end //

delimiter ;

set sql_mode = strict_all_tables;

insert into foo (bar) values ('boom');

Обратите внимание: я назвал свою локальную переменную той же, что и столбцовую панель, которую я хочу протестировать. Таким образом, имя переменной появляется в сообщении об ошибке, оно совпадает с именем столбца:

ОШИБКА 1366 (HY000): Неверное целочисленное значение: "Вы не можете сохранить это значение!" для столбца 'bar' в строке 1

Ещё вопросы

Сообщество Overcoder
Наверх
Меню