Joe Ijam
Joe Ijam

Reputation: 2179

Mysql - How to quit/exit from stored procedure

I have very simple question but i did't get any simple code to exit from SP using Mysql. Can anyone share with me how to do that?

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;

Upvotes: 160

Views: 135210

Answers (8)

bobobobo
bobobobo

Reputation: 67286

You can use a FUNCTION if you want a return statement:

delimiter //

drop function if exists theFunction //

create function theFunction( val int )
returns int
deterministic -- if hits the sql tables, use reads sql data
begin
  if val < 5 then
    return 0;
  end if;
  
  -- other code path falls thru to here:
  return 1;
end //

select theFunction( 2 ); -- 0
select theFunction( 7 ); -- 1

If you still want to use a procedure, you could use piotrm's label approach (though I'd suggest labelling the function with the same name as the function)

Or, you could just use if/else normally:

drop procedure if exists theProc //
create procedure theProc( val int )
deterministic -- if hits sql tables, use reads sql data or modifies sql data
begin
  if val < 5 then
    select 0 as Result; -- "return value" of a stored proc is select
  else
    -- The indentation isn't that bad, it works
    select 1 as Result;
  end if;
end //

delimiter ;

call theProc( 1 );  -- 0
call theProc( 10 ); -- 1

Upvotes: 0

BuvinJ
BuvinJ

Reputation: 11076

If you want an "early exit" for a situation in which there was no error, then use the accepted answer posted by @piotrm. Most typically, however, you will be bailing due to an error condition (especially in a SQL procedure).

As of MySQL v5.5 you can throw an exception. Negating exception handlers, etc. that will achieve the same result, but in a cleaner, more precise manner.

Here's how:

DECLARE CUSTOM_EXCEPTION CONDITION FOR SQLSTATE '45000';

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

Note SQLSTATE '45000' equates to "Unhandled user-defined exception condition". By default, this will produce an error code of 1644 (which has that same meaning). Note that you can throw other condition codes or error codes if you want (plus additional details for exception handling).

For more on this subject, check out:

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

How to raise an error within a MySQL function

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

Addendum

As I'm re-reading this post of mine, I realized I had something additional to add. Prior to MySQL v5.5, there was a way to emulate throwing an exception. It's not the same thing exactly, but this was the analogue: Create an error via calling a procedure which does not exist. Call the procedure by a name which is meaningful in order to get a useful means by which to determine what the problem was. When the error occurs, you'll get to see the line of failure (depending on your execution context).

For example:

CALL AttemptedToInsertSomethingInvalid;

Note that when you create a procedure, there is no validation performed on such things. So while in something like a compiled language, you could never call a function that wasn't there, in a script like this it will simply fail at runtime, which is exactly what is desired in this case!

Upvotes: 25

user1587368
user1587368

Reputation: 316

I think this solution is handy if you can test the value of the error field later. This is also applicable by creating a temporary table and returning a list of errors.

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);

Upvotes: 0

Bohemian
Bohemian

Reputation: 425258

To handle this situation in a portable way (ie will work on all databases because it doesn’t use MySQL label Kung fu), break the procedure up into logic parts, like this:

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;

Upvotes: 15

Devendra  Singraul
Devendra Singraul

Reputation: 951

This works for me :

 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

Upvotes: 5

sdfor
sdfor

Reputation: 6458

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;

Upvotes: 1

piotrm
piotrm

Reputation: 12366

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;

Upvotes: 258

Stephen
Stephen

Reputation: 18964

Why not this:

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

Upvotes: 3

Related Questions