如何退出/退出存储过程

我有一个非常简单的问题,但我没有得到任何简单的代码退出 SP 使用 Mysql。 有人能告诉我怎么做吗?

CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
IF tablename IS NULL THEN
#Exit this stored procedure here
END IF;


#proceed the code
END;
119691 次浏览

为什么不这样做:

CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
IF tablename IS NOT NULL THEN
#proceed the code
END IF;
# Do nothing otherwise
END;

为了以一种可移植的方式处理这种情况(例如可以在所有数据库上工作,因为它没有使用 MySQL 标签的“功夫”) ,把这个过程分成逻辑部分,像这样:

CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
IF tablename IS NOT NULL THEN
CALL SP_Reporting_2(tablename);
END IF;
END;


CREATE PROCEDURE SP_Reporting_2(IN tablename VARCHAR(20))
BEGIN
#proceed with code
END;
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
proc_label:BEGIN
IF tablename IS NULL THEN
LEAVE proc_label;
END IF;


#proceed the code
END;
MainLabel:BEGIN


IF (<condition>) IS NOT NULL THEN
LEAVE MainLabel;
END IF;


....code


i.e.
IF (@skipMe) IS NOT NULL THEN /* @skipMe returns Null if never set or set to NULL */
LEAVE MainLabel;
END IF;

如果您希望在没有错误的情况下“提前退出”,那么使用@piotrm 发布的已接受的答案。但是,最典型的情况是,由于错误条件(特别是在 SQL 过程中) ,您将被迫退出。

从 MySQL v5.5开始,您可以抛出异常。否定异常处理程序等,这些异常处理程序将以更清晰、更精确的方式实现相同的结果。

方法如下:

DECLARE CUSTOM_EXCEPTION CONDITION FOR SQLSTATE '45000';


IF <Some Error Condition> THEN
SIGNAL CUSTOM_EXCEPTION
SET MESSAGE_TEXT = 'Your Custom Error Message';
END IF;

注意 SQLSTATE '45000'等同于“未处理的用户定义的异常条件”。默认情况下,这将产生 1644的错误代码(具有相同的含义)。注意,如果需要,可以引发其他条件代码或错误代码(另外还有异常处理的其他详细信息)。

关于这个主题的更多信息,请查看:

Https://dev.mysql.com/doc/refman/5.5/en/signal.html

如何在 MySQL 函数中引发错误

Http://www.databasejournal.com/features/mysql/mysql-error-handling-using-the-signal-and-resignal-statements.html

附录

当我重读这篇文章的时候,我意识到我还有一些东西要补充。在 MySQL v5.5之前,有一种方法可以模拟抛出异常。这完全不是一回事,但这是一个类似的情况: 通过调用一个不存在的过程来创建一个错误。通过一个有意义的名称来调用过程,以获得确定问题所在的有用方法。当错误发生时,您将看到故障行(取决于您的执行上下文)。

例如:

CALL AttemptedToInsertSomethingInvalid;

请注意,在创建过程时,不会对这些内容执行验证。因此,在类似于编译语言的情况下,你永远不能调用不存在的函数,在这样的脚本中,它只会在运行时失败,这正是这种情况所需要的!

这对我有用:

 CREATE DEFINER=`root`@`%` PROCEDURE `save_package_as_template`( IN package_id int ,
IN bus_fun_temp_id int  , OUT o_message VARCHAR (50) ,
OUT o_number INT )
BEGIN


DECLARE  v_pkg_name  varchar(50) ;


DECLARE  v_pkg_temp_id  int(10)  ;


DECLARE  v_workflow_count INT(10);


-- checking if workflow created for package
select count(*)  INTO v_workflow_count from workflow w where w.package_id =
package_id ;


this_proc:BEGIN   -- this_proc block start here


IF  v_workflow_count = 0 THEN
select 'no work flow ' as 'workflow_status' ;
SET o_message ='Work flow is not created for this package.';
SET  o_number = -2 ;
LEAVE this_proc;
END IF;


select 'work flow  created ' as 'workflow_status' ;
-- To  send some message
SET o_message ='SUCCESSFUL';
SET  o_number = 1 ;


END ;-- this_proc block end here


END

如果您稍后可以测试错误字段的值,那么我认为这个解决方案会很方便。通过创建一个临时表并返回一个错误列表,这也是适用的。

DROP PROCEDURE IF EXISTS $procName;
DELIMITER //
CREATE PROCEDURE $procName($params)
BEGIN
DECLARE error INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET error = 1;
SELECT
$fields
FROM $tables
WHERE $where
ORDER BY $sorting LIMIT 1
INTO $vars;
IF error = 0 THEN
SELECT $vars;
ELSE
SELECT 1 AS error;
SET @error = 0;
END IF;
END//
CALL $procName($effp);