MySQL « Как проконтролировать успешность завершения запроса в MySQL?
Предположим я пытаюсь сделать вставку в таблицу, в случае возникновение каких-то проблем необходимо сделать rollback. Вопрос как перехватить сообщение MySQL о невозможности вставки данных в таблицу?
Для MS SQL Server данная обработка выглядит так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .mysql.geshi_code {font-family:monospace;} .mysql.geshi_code .imp {font-weight: bold; color: red;} .mysql.geshi_code .kw1 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw2 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw3 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw4 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw5 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw6 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw7 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw8 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw9 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw10 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw11 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw12 {color: #009900;} .mysql.geshi_code .kw13 {color: #000099;} .mysql.geshi_code .kw14 {color: #000099;} .mysql.geshi_code .kw15 {color: #000099;} .mysql.geshi_code .kw16 {color: #000099;} .mysql.geshi_code .kw17 {color: #000099;} .mysql.geshi_code .kw18 {color: #000099;} .mysql.geshi_code .kw19 {color: #000099;} .mysql.geshi_code .kw20 {color: #000099;} .mysql.geshi_code .kw21 {color: #000099;} .mysql.geshi_code .kw22 {color: #000099;} .mysql.geshi_code .kw23 {color: #000099;} .mysql.geshi_code .kw24 {color: #000099;} .mysql.geshi_code .kw25 {color: #000099;} .mysql.geshi_code .kw26 {color: #000099;} .mysql.geshi_code .kw27 {color: #00CC00;} .mysql.geshi_code .coMULTI {color: #808000; font-style: italic;} .mysql.geshi_code .co1 {color: #808080; font-style: italic;} .mysql.geshi_code .co2 {color: #808080; font-style: italic;} .mysql.geshi_code .es0 {color: #004000; font-weight: bold;} .mysql.geshi_code .es1 {color: #008080; font-weight: bold;} .mysql.geshi_code .br0 {color: #FF00FF;} .mysql.geshi_code .sy1 {color: #CC0099;} .mysql.geshi_code .sy2 {color: #000033;} .mysql.geshi_code .st0 {color: #008000;} .mysql.geshi_code .nu0 {color: #008080;} .mysql.geshi_code span.xtra { display:block; }
INSERT INTO tableName (columnName_1) VALUES (someValue);
IF @@ERROR <> 0 ROLLBACK TRANSACTION NameOfSavePoint;
Так вот, чем можно заменить @@ERROR?
Для MS SQL Server данная обработка выглядит так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .mysql.geshi_code {font-family:monospace;} .mysql.geshi_code .imp {font-weight: bold; color: red;} .mysql.geshi_code .kw1 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw2 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw3 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw4 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw5 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw6 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw7 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw8 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw9 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw10 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw11 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw12 {color: #009900;} .mysql.geshi_code .kw13 {color: #000099;} .mysql.geshi_code .kw14 {color: #000099;} .mysql.geshi_code .kw15 {color: #000099;} .mysql.geshi_code .kw16 {color: #000099;} .mysql.geshi_code .kw17 {color: #000099;} .mysql.geshi_code .kw18 {color: #000099;} .mysql.geshi_code .kw19 {color: #000099;} .mysql.geshi_code .kw20 {color: #000099;} .mysql.geshi_code .kw21 {color: #000099;} .mysql.geshi_code .kw22 {color: #000099;} .mysql.geshi_code .kw23 {color: #000099;} .mysql.geshi_code .kw24 {color: #000099;} .mysql.geshi_code .kw25 {color: #000099;} .mysql.geshi_code .kw26 {color: #000099;} .mysql.geshi_code .kw27 {color: #00CC00;} .mysql.geshi_code .coMULTI {color: #808000; font-style: italic;} .mysql.geshi_code .co1 {color: #808080; font-style: italic;} .mysql.geshi_code .co2 {color: #808080; font-style: italic;} .mysql.geshi_code .es0 {color: #004000; font-weight: bold;} .mysql.geshi_code .es1 {color: #008080; font-weight: bold;} .mysql.geshi_code .br0 {color: #FF00FF;} .mysql.geshi_code .sy1 {color: #CC0099;} .mysql.geshi_code .sy2 {color: #000033;} .mysql.geshi_code .st0 {color: #008000;} .mysql.geshi_code .nu0 {color: #008080;} .mysql.geshi_code span.xtra { display:block; }
INSERT INTO tableName (columnName_1) VALUES (someValue);
IF @@ERROR <> 0 ROLLBACK TRANSACTION NameOfSavePoint;
Так вот, чем можно заменить @@ERROR?
1 ответов
Можно попробовать объявить Handler:
DECLARE EXIT HANDLER
FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
ROLLBACK;
Подробнее тут.
А вообще есть еще возможность проверять ошибки выполнение в клиентском коде (не Mysql, а тот который его вызывает, например PHP) и так же с помощью перехвата эксепшна делать ROLLBACK.
Вообщем, после нескольких часов гугления, взяв за основу ссылку оставленную doctor-lg (за что ему большое спасибо), создал следующую процедуру (в качестве примера, взята БД из книги "SQL in 10 Minutes", автор Ben Forta):
DELIMITER |
DROP PROCEDURE IF EXISTS `tysql`.`CATCH_TEST` |
CREATE DEFINER = `root`@`localhost` PROCEDURE `CATCH_TEST` ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET @error = 1;
START TRANSACTION;
INSERT
INTO
Customers(
cust_id,
cust_name
)
VALUES(
'1000000208',
'Toys Emporium'
);
SAVEPOINT Savepoint_1;
INSERT
INTO
Orders(
order_num,
order_date,
cust_id
)
VALUES(
20108,
CURDATE(),
'1000000208'
);
IF @error != 0 THEN
ROLLBACK TO Savepoint_1;
END IF;
INSERT
INTO
OrderItems(
order_num,
order_item,
prod_id,
quantity,
item_price
)
VALUES(
20108,
1,
'BR01',
100,
5.49
);
IF @error != 0 THEN
ROLLBACK TO Savepoint_1;
END IF;
SAVEPOINT Savepoint_2;
INSERT
INTO
OrderItems(
order_num,
order_item,
prod_id,
quantity,
item_price
)
VALUES(
201080,
2,
'BR03',
100,
10.99
);
IF @error != 0 THEN
ROLLBACK TO Savepoint_2;
END IF;
COMMIT;
END |
Данный пример работает корректно и если одна из транзакций не выполняется, происходит откат к предыдущей точки сохранения. Единственный минус такого подхода, что необходимо "класть" все запросы в процедуру, как обойти данную проблему, пока так и не придумал.
По поводу обработки на клиентской стороне, конечно я знаю о такой возможности, но необходимость была, обрабатывать ошибки именно в самой БД.