Задавайте вопросы, мы ответим
Вы не зашли.
Правильно ли, что отсюда следует, что не выполняется обработка ошибок? То есть при выполнении Хп я не могу послать ответ о состоянии обработки по его коду? Или существует иной способ сообщить клиенту некоторую нештатную ситуацию, возникшую при выполнении ХП.
Неактивен
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
Неактивен
Здесь другие принципы.
http://dev.mysql.com/doc/refman/5.1/en/ … dlers.html
Пример
Неактивен
Да, спасибо. Я как бы могу поставить соответствие кодов ошибок 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`;
Извиняюсь, если пишу глупость.
Неактивен
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.
Неактивен
EugeneTM, а почему не наоборот: 0 - если не нашел, 1 - если нашел.
(я понимаю, что вообще абсолютно два любые числа можно поставить; так, спросил, просто; мало ли скрытый смысл есть какой-то)
Неактивен
LazY написал:
EugeneTM, а почему не наоборот: 0 - если не нашел, 1 - если нашел.
(я понимаю, что вообще абсолютно два любые числа можно поставить; так, спросил, просто; мало ли скрытый смысл есть какой-то)
Тупо экономлю полкопейки.
Так как минимальное значение id = 1, а вернуть хочется константу.
Первое что подвернулось LEAST, сравниваю с 0 и результат возвращаю.
Если наоборот добавится целый оператор, чтоб вернуть 1.
Неактивен
Тут я рассматриваю, что будет происходить со стороны клиента.
Если клиент дергает процедуру и она отрабатывает без ошибок, то клиенту приходит резалтсет
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
Если же с ошибкой, то
SELECT 3000; Это уже мой код ошибки
Это так ?
И как это развести на клиенте?
Не очень то красиво
Неактивен
Igor Panshin написал:
Тут я рассматриваю, что будет происходить со стороны клиента.
Если клиент дергает процедуру и она отрабатывает без ошибок, то клиенту приходит резалтсет
SELECT `ID` , `DataType` , `CreationDate` , `Description` FROM `test`.`dvsys_crypto` WHERE `CryptoID` = CryptoID;
Если же с ошибкой, то
SELECT 3000; Это уже мой код ошибки
Это так ?
И как это развести на клиенте?
Не очень то красиво
В моем случае ХП гарантированно вернет только один результат, поэтому на клиенте все просто.
В ситуациях как у тебя я делаю так
Сразу после DECLARE выполняю SELECT 0, или что мне нужно по ситуации.
Затем пошел селект возвращающий набор записей.
Если происходит ошибка неважно в каком месте ХП - отработчик первым вернет результат, пусть 3000.
На клиенте по multiquery смотрю первый результат. Если он 3000, то дальше обрабатываю ошибку.
Если 0, то обрабатываю второй ...
Неактивен
Если клиент дергает процедуру и она отрабатывает без ошибок, то клиенту приходит резалтсет
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`; ), а на клиенте уже дальше смотреть, что делать.
(имхо основное неудобство на клиенте обычно бывает, если количество столбцов разное)
Неактивен