MySQL – Creating stored procedures

Published on Author gryzli

Stored Procedures in MySQL are the typical primer for great ideas and bad implementation. Even that I have stored procedures, because of their performance penalties, recently I had to write one. The procedure itself was very simple, but there were some catchy stages I would like to describe in case I need to write such again.

 

1| What is MySQL Stored Procedure

This is the mysql thing for “programming inside mysql” and yes you could write your own functions which are mostly limited to using SQL-derived statements. The functions could be given parameters, could return parameters, exit codes and so on.

If you need “more” on what are Stored Procedures and why do they exists, I’m not the right guy to tell you, so get your ticket to dev.mysql.com or something more eligible resource

 

2| Creating Stored Procedure

The first step you will encounter is to create the procedure.

Comments in SQL and Stored Procedures could be one of these:

/* ….some commented multilined text …..*/ 

— This is one line comment

 

My test procedure (named new_schedule) looked like this:

( I have added comments describing each  row)

-- Drop the procedure if it already exists 
DROP PROCEDURE IF EXISTS new_schedule;

-- Change the line-end delimiter
DELIMITER $$

-- This is the actual create procedure statement
-- Our procedure accepts 2 arguments 
-- IN means we are able only to read the arguments
-- Every argument has also type defined (char(3) or date)
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_schedule`(IN courseCode char(3), IN startDate date)

BEGIN

SELECT * FROM some_table; 

-- End of procedure definition
END$$
DELIMITER ;

 

 

 

From now on, every code example I give is supposed to be inside stored procedure definition, so I won’t add again and again the procedure definitions

3| Variable declarations inside Stored Procedure

As with most of the programming languages, here you could also declare variables. Stored procedures in mysql have “strict type” declarations, which means that you must also mention the type of the variable you are declaring.

[Important Note] It is very important to make sure your variable declarations are at the beginning of the stored procedure. If you try to declare variable later on in the procedure, mysql will throw you some nasty and hard to debug errors.

[/ Important Note]

 

Some example declarations:

DECLARE integer_var INTEGER DEFAULT 0;
DECLARE my_string varchar(100) DEFAULT "";
DECLARE date_var date DEFAULT NULL;
DECLARE varchar_var  varchar(30) DEFAULT "";

-- Assign value to an already defined variable
SET my_string = "Set the variable to some text"

Whatever variable you plan to use inside the procedure, must be firstly defined in the beginning. Later you could assign it a value.

[Important Note]

If you have any cursor or handler declarations ( which are used for looping), you must always use the following declarations order:

  • First must be variable/conditional delcarations
  • Second are cursor declarations
  • Third are handler declarations

[/ Important Note]

 

4| Using IF statements inside Stored Procedure

The next “cool” thing is you have “Flow control statements” or more precisely:

CASE  , IF/THEN/ELSE and even WHILE and LOOP statements.

I will give example for using the IF/THEN/ELSE and also iterating through a LOOP

DECLARE operator VARCHAR(20);
DECLARE m int; 

SET m=5; 

IF m > 3 THEN
   SET s="bigger";
ELSEIF m < 3 THEN
   SET s="smaller";
ELSE
   SET s="equal";
END IF;

 

5| Iterate over SELECT result in a LOOP inside Stored Procedure

One of the thing you will almost 100% need is doing a LOOP. Usually this is when you want to process all result rows from a given select.

Here is one way to use the internal LOOP keyword inside stored procecdure;

First we will declare CURSOR variable which will give us the chance to iterate over result set by using the keyword FETCH . FETCH returns one value at a time.

 

We will also use HANDLER declaration which is used to determine if we have empty result set returned form the SELECT and so don’t iterate into the loop.

Here is the example:

-- Initialize loop_done variable to 0 
DECLARE loop_done INTEGER DEFAULT 0;

-- Temporary variable for iterating days in it 
DECLARE temp_day  INTEGER ;

-- Declare CURSOR 
-- The following SELECT will select for us 7 rows (each containing a DAY) from the day table
DEClARE select_cursor CURSOR FOR  SELECT date FROM days WHERE week='3';

-- Define CONTINUE HANDLER
-- Whenever our result set END after doing the LAST FETCH, our 
-- continue handler will set loop_done to 1 in order to leave the LOOP
DECLARE CONTINUE HANDLER FOR NOT FOUND SET loop_done = 1;


-- Open the CURSOR 
open select_cursor;

-- Start the LOOP 

select_loop: LOOP 
   FETCH select_cursor INTO temp_day;

   IF loop_done = 1 THEN 
     -- LEAVE is a keyword used to END the loop
     LEAVE select_loop;
   END IF; 

   -- Print the day 
   SELECT "We are processing day:", temp_day;

END LOOP select_loop;

-- Don't forget to close the CURSOR
CLOSE select_cursor;

 

6| Exiting a Stored Procedure and Throwing Error Message

Sometimes you may need to exit a procedure in such a way that it will return usable message to the CALLER. The caller could be you if you manually execute the procedure by using CALL() or another stored procedure.

You can exit the procedure and return message by using the “SIGNAL” keyword.

More information on SIGNALs could be found here:

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

 

Here is a simple example I was using in my procedure to return an error:

    IF some_int < 10 THEN 
    SIGNAL SQLSTATE '45001'
        SET MESSAGE_TEXT = 'Some_int is too small and is smaller than 10';
    END IF;