Как я могу увидеть ошибки хранимой процедуры MySQL?

0

Что касается использования хранимых процедур MySQL с транзакциями, и у меня возникает проблема с получением ошибки.

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

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

Я использую Perl DBI для общения с MySQL. Я использую MySQL 5.0.92 на рабочем сервере и MySQL 5.0.51a на сервере разработки. Переход на более новую версию MySQL политически несостоятелен.

Это упрощенный пример:

DELIMITER //
CREATE PROCEDURE pmt_new(

  app_id            varchar(40),

  out ret           tinyint unsigned,
  out pmt_req_id    int(10) unsigned)
BEGIN

DECLARE v_pmt_req_type int(10) unsigned;

DECLARE exit handler for not found, sqlwarning, sqlexception rollback;

set ret=1;
START TRANSACTION;

  SELECT pmt_type INTO v_pmt_req_type FROM pmt_req_types WHERE pmt_req_name = 'Name 1';

  INSERT INTO pmt_reqs (pmt_req_id,    pmt_req_type,   app_id)
  values               (null,          v_pmt_req_type, app_id);

  set pmt_req_id = last_insert_id();

  INSERT INTO other (pmt_req_id) values (pmt_req_id);

COMMIT;
set ret=0;
END//  
DELIMITER ;
Теги:
stored-procedures
dbi

1 ответ

2

Вместо того, чтобы просто выполнять откат в вашем обработчике выхода, вам нужно что-то вернуть...

В настоящее время у вас есть

DECLARE exit handler for not found, sqlwarning, sqlexception rollback;

Измените его на что-то вроде...

DECLARE exit handler for not found, sqlwarning, sqlexception
  begin
    rollback;
    select "We had to rollback, error!";
  end;

В 5.5 они добавили операторы SIGNAL/RESIGNAL, чтобы вы могли "возвратить" ошибку, но предыдущие версии вы должны отбросить свое собственное решение. Если вам нужно, вы можете объявить несколько обработчиков выходных данных, чтобы лучше адаптировать выход, или настроить собственную таблицу ошибок, из которой вы можете извлечь.

Вы также можете выполнить входное тестирование внутри хранимой процедуры. Хотите узнать, является ли app_id нулевым?

DELIMITER //
CREATE PROCEDURE pmt_new(

  app_id            varchar(40),
  out result        varchar(256),
  out ret           tinyint unsigned,
  out pmt_req_id    int(10) unsigned)
BEGIN

  DECLARE v_pmt_req_type int(10) unsigned;

  DECLARE exit handler for not found, sqlwarning, sqlexception rollback;

  SET ret=1;
  SET result = "";

  IF app_id IS NULL THEN
    set result = "Supplied ID is Null";
  ELSE

    START TRANSACTION;

      SELECT pmt_type INTO v_pmt_req_type FROM pmt_req_types WHERE pmt_req_name = 'Name 1';

      INSERT INTO pmt_reqs (pmt_req_id,    pmt_req_type,   app_id)
      values               (null,          v_pmt_req_type, app_id);

      set pmt_req_id = last_insert_id();

      INSERT INTO other (pmt_req_id) values (pmt_req_id);

    COMMIT;
    set ret=0;
  END IF;
END//  
DELIMITER ;

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

  • 0
    Я уже делаю это, устанавливая выходную переменную "ret".
  • 0
    @NXT Вы просто используете 'ret' как true / false, вы не используете его для предоставления необходимой вам информации. (Как в более подробной информации о сбое). Мой ответ показывает вам способ делать то, что вы хотите. Я отредактирую свой ответ с более подробной информацией, которую вы можете попробовать вместо этого.

Ещё вопросы

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