SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 04.06.2008 14:25:25

Igor Panshin
Завсегдатай
Зарегистрирован: 04.06.2008
Сообщений: 62

RETURN не используется в ХП

Правильно ли, что отсюда следует, что не выполняется обработка ошибок? То есть при выполнении Хп я не могу послать ответ о состоянии обработки по его коду? Или существует иной способ сообщить клиенту некоторую нештатную ситуацию, возникшую при выполнении ХП.

Неактивен

 

#2 04.06.2008 15:43:09

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5827

Re: RETURN не используется в ХП

RETURN действительно используется только в хранимых функциях.
Однако в процедурах есть обработчик событий (в частности ошибка тоже является событием)
См. примеры на форуме:
http://sqlinfo.ru/forum/viewtopic.php?pid=3813#p3813
http://sqlinfo.ru/forum/viewtopic.php?pid=565#p565

Мануал:
http://dev.mysql.com/doc/refman/5.0/en/handler.html

Неактивен

 

#3 04.06.2008 15:47:00

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: RETURN не используется в ХП

Здесь другие принципы.

http://dev.mysql.com/doc/refman/5.1/en/ … dlers.html

Пример


DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`existslogin`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`.`existslogin`(
   lguser VARCHAR(15)
   )
BEGIN
DECLARE islg INT;
DECLARE isnotlogin CONDITION FOR 1329; # Объявляем кондишен для ошибки 1329, нечего выдать
DECLARE EXIT HANDLER FOR isnotlogin SELECT 1; # Если возникла ошибка прицепленная к кондишену isnotlogin - возвращаем 1
DECLARE EXIT HANDLER FOR SQLWARNING, NOT FOUND, SQLEXCEPTION SELECT -1; # При всех других ошибках получаем -1 и админу пишем в мыло
SELECT LEAST(test.lg.id, 0) FROM test.lg
   WHERE test.lg.hash = MD5(LOWER(lguser)) INTO islg; # Присваиваем islg найденное значение hash
SELECT islg; # Возвращаем найденное значение, если не найдено - возникает ошибка 1329 и дальше isnotlogin
END$$
DELIMITER ;
 

Неактивен

 

#4 05.06.2008 10:45:54

Igor Panshin
Завсегдатай
Зарегистрирован: 04.06.2008
Сообщений: 62

Re: RETURN не используется в ХП

Да, спасибо. Я как бы могу поставить соответствие кодов ошибок Mysql  и своих кодов ошибок

DECLARE isnotlogin CONDITION FOR 1329; # Это код ошибки Mysql
DECLARE EXIT HANDLER FOR isnotlogin SELECT 3000; Это уже мой код ошибки

Однако, если процедура выдает резалтсет типа

CREATE PROCEDURE `test`.`dvsys_crypto_getinfo` ( CryptoID CHAR(36) )
BEGIN
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
IF ROWCOUNT = 0
THEN
RETURN 0x5A0
END;
то тогда мне делать объявление выхода в соответствии с резалтсетом?

DECLARE EXIT HANDLER FOR isnotlogin SELECT  null as `ID` , null as `DataType` , null as `CreationDate` , 'код ошибки
3000' as `Description`;

Извиняюсь, если пишу глупость.

Неактивен

 

#5 05.06.2008 11:35:23

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: RETURN не используется в ХП

Igor Panshin написал:

Да, спасибо. Я как бы могу поставить соответствие кодов ошибок Mysql  и своих кодов ошибок

DECLARE isnotlogin CONDITION FOR 1329; # Это код ошибки Mysql
DECLARE EXIT HANDLER FOR isnotlogin SELECT 3000; Это уже мой код ошибки

Однако, если процедура выдает резалтсет типа

CREATE PROCEDURE `test`.`dvsys_crypto_getinfo` ( CryptoID CHAR(36) )
BEGIN
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
IF ROWCOUNT = 0
THEN
RETURN 0x5A0
END;
то тогда мне делать объявление выхода в соответствии с резалтсетом?

DECLARE EXIT HANDLER FOR isnotlogin SELECT  null as `ID` , null as `DataType` , null as `CreationDate` , 'код ошибки
3000' as `Description`;

Извиняюсь, если пишу глупость.

ROWCOUNT  в MySQL выдает количество записей которые были либо удалены, либо вставлены, либо изменены, но не выбраны селектом.
http://dev.mysql.com/doc/refman/5.1/en/ … _row-count

В своем примере я делаю следующее

Так как у меня уникальное значение поля lguser, то больше одной записи получено по запросу быть не может.
Поэтому найденный id я присваиваю локальной переменной. Точнее 0 если нашлось (LEAST(test.lg.id, 0)).
В случае если не найдено ни одной записи, переменной не присваивается ничего.

Затем я пытаюсь выполнить селект этой переменной.
Если ей было присвоено значение , то все Ок и процедура возвращает 0. То что получилось в результате SELECT islg;
Если мы ничего не нашли и пытаемся выполнить селект переменной не имеющей значения, возникает ошибка MySQL 1329.
На перехват которой объявлен isnotlogin CONDITION FOR 1329.
Если данная ситуация возникла, объявлен обработчик для нее
DECLARE EXIT HANDLER FOR isnotlogin SELECT 1;
Он возвращает 1.
Ничто не мешает написать SELECT 3000 и он вернет 3000.

Неактивен

 

#6 05.06.2008 13:37:18

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 845

Re: RETURN не используется в ХП

EugeneTM, а почему не наоборот: 0 - если не нашел, 1 - если нашел.
(я понимаю, что вообще абсолютно два любые числа можно поставить; так, спросил, просто; мало ли скрытый смысл есть какой-то)

Неактивен

 

#7 05.06.2008 14:21:02

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: RETURN не используется в ХП

LazY написал:

EugeneTM, а почему не наоборот: 0 - если не нашел, 1 - если нашел.
(я понимаю, что вообще абсолютно два любые числа можно поставить; так, спросил, просто; мало ли скрытый смысл есть какой-то)

Тупо экономлю полкопейки.
Так как минимальное значение id = 1, а вернуть хочется константу.
Первое что подвернулось LEAST, сравниваю с 0 и результат возвращаю.
Если наоборот добавится целый оператор, чтоб вернуть 1. smile

Неактивен

 

#8 05.06.2008 14:28:40

Igor Panshin
Завсегдатай
Зарегистрирован: 04.06.2008
Сообщений: 62

Re: RETURN не используется в ХП

Тут я рассматриваю, что будет происходить со стороны клиента.
Если клиент дергает процедуру и она отрабатывает без ошибок, то клиенту приходит резалтсет
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
Если же с ошибкой, то
SELECT 3000; Это уже мой код ошибки

Это так ?
И как это развести на клиенте?
Не очень то красиво

Неактивен

 

#9 05.06.2008 14:41:04

EugeneTM
Гуру
Зарегистрирован: 11.04.2008
Сообщений: 89

Re: RETURN не используется в ХП

Igor Panshin написал:

Тут я рассматриваю, что будет происходить со стороны клиента.
Если клиент дергает процедуру и она отрабатывает без ошибок, то клиенту приходит резалтсет
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
Если же с ошибкой, то
SELECT 3000; Это уже мой код ошибки

Это так ?
И как это развести на клиенте?
Не очень то красиво

В моем случае ХП гарантированно вернет только один результат, поэтому на клиенте все просто.

В ситуациях как у тебя я делаю так

Сразу после DECLARE выполняю SELECT 0, или что мне нужно по ситуации.
Затем пошел селект возвращающий набор записей.
Если происходит ошибка неважно в каком месте ХП - отработчик первым вернет результат, пусть 3000.
На клиенте по multiquery смотрю первый результат. Если он 3000, то дальше обрабатываю ошибку.
Если 0, то обрабатываю второй ...

Неактивен

 

#10 08.06.2008 03:27:00

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 845

Re: RETURN не используется в ХП

Если клиент дергает процедуру и она отрабатывает без ошибок, то клиенту приходит резалтсет
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
Если же с ошибкой, то
SELECT 3000; Это уже мой код ошибки

Это так ?
И как это развести на клиенте?

Почему бы не обрабатывать приходящий из процедуры результат на клиенте?
Например, возвращать NULL как ID в случае неудачи (у Вас хорошо в этом отношении написано DECLARE EXIT HANDLER FOR isnotlogin SELECT  null as `ID` , null as `DataType` , null as `CreationDate` , 'код ошибки
3000'
as `Description`;
), а на клиенте уже дальше смотреть, что делать.
(имхо основное неудобство на клиенте обычно бывает, если количество столбцов разное)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson