2010-09-03 1 views
0

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

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

ответ

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'); 

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

ERROR 1366 (HY000): Неверное целочисленное значение: "Вы не можете хранить это значение! для столбца «бар» в строке 1

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); 
    } 
}