0% found this document useful (0 votes)
39 views

Week9 DB Stored

This document provides an overview of stored routines in databases. It discusses how stored routines are named sets of SQL statements that are stored on the server and can be called by a single call. Stored routines include stored procedures, which do not return values but can assign them to variables, and stored functions, which do return values. The document outlines the basic syntax for creating stored procedures and functions, and how they can make use of input and output parameters as well as local variables when containing multiple SQL statements.

Uploaded by

Fred
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views

Week9 DB Stored

This document provides an overview of stored routines in databases. It discusses how stored routines are named sets of SQL statements that are stored on the server and can be called by a single call. Stored routines include stored procedures, which do not return values but can assign them to variables, and stored functions, which do return values. The document outlines the basic syntax for creating stored procedures and functions, and how they can make use of input and output parameters as well as local variables when containing multiple SQL statements.

Uploaded by

Fred
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

Databases - Stored Routines

Jianxin Li

School of Computer Science & Software Engineering


University of Western Australia

Jianxin Li (UWA) Stored routines 1 / 31


This lecture

We continue our coverage of the fundamentals of SQL/MySQL with stored


routines.

(This material will appear in the remaining lab sessions, but will not be on the
final exam.)

Jianxin Li (UWA) Stored routines 2 / 31


Stored Routines

Stored Routines

A stored routine is a named set of SQL statements that is stored on the server
and which can be initiated by a single call.
Normally, we imagine the stored routine as being written by the DBA and
called by the client programs.
Stored routines are further subdivided into:
Stored procedures do not return anything
Stored procedures can however assign values to variables etc.
Stored functions that return values to the client

Jianxin Li (UWA) Stored routines 3 / 31


Stored Routines

Rationale for stored routines

A stored routine is maintained on the server, which has various consequences


both positive and negative:
A complex sequence of SQL statements can be prepared once by a
professional DBA and then made available to all client programs
Stored routines can access confidential or sensitive tables without
exposing them to client programs
Processing becomes more centralized with the server taking on a greater
computational load

Jianxin Li (UWA) Stored routines 4 / 31


Stored Routines

Basic Syntax

The basic syntax for creating the simplest possible procedure, one with no
parameters and consisting of a single SQL statement is as follows:
CREATE PROCEDURE myproc()
/* An SQL statement */

For example, in the world database we could issue the command:


CREATE PROCEDURE listCapitals()
SELECT C.name, T.name
FROM country C, city T
WHERE C.capital = T.id;

So the procedures name is listCapitals and its body is the single


SELECT statement.

Jianxin Li (UWA) Stored routines 5 / 31


Stored Routines

Calling a user-defined procedure

CALL listCapitals();
+-----------------------------+-----------------------------------+
| name | name |
+-----------------------------+-----------------------------------+
| Aruba | Oranjestad |
| Afghanistan | Kabul |
| Angola | Luanda |
| Anguilla | The Valley |

A stored procedure belongs to a specific database, namely the one that was
being used when CREATE PROCEDURE command was issued.

Jianxin Li (UWA) Stored routines 6 / 31


Stored Routines

Procedure parameters

In order to do anything more useful than just saving typing, a procedure will
have parameters that the user will specify on calling the procedure
CREATE PROCEDURE listOneCapital(cntry VARCHAR(50))
SELECT C.name, T.name
FROM country C, city T
WHERE C.capital = T.id
AND C.name = cntry;

This procedure has one parameter called cntry which is of type


VARCHAR(50).

Jianxin Li (UWA) Stored routines 7 / 31


Stored Routines

Calling the procedure

When the procedure is called the caller specifies an actual value, known as
the argument to the procedure.
CALL listOneCapital(Uganda);
+--------+---------+
| name | name |
+--------+---------+
| Uganda | Kampala |
+--------+---------+

Inside the procedure, the argument in this case Uganda will be used
wherever the variable cntry occurs.

Jianxin Li (UWA) Stored routines 8 / 31


Stored Routines

Output Parameters

A procedure has no RETURN statement and doesnt return a value to the caller.
However the caller can specify a user-variable in the parameter list and the
procedure can assign a value to that variable.
CREATE PROCEDURE regionPop(rgn TEXT, OUT rpop INT)
SELECT SUM(population)
FROM country C
WHERE C.region = rgn
INTO rpop;

The output parameter rpop is indicated by the keyword OUT and the SELECT
statement performs the selection INTO the variable.

Jianxin Li (UWA) Stored routines 9 / 31


Stored Routines

Using output parameters

When this procedure is called the user must


Specify an actual value for each input variable
Specify a variable name for each output variable
CALL regionpop(North America, @napop);

Nothing appears on the terminal, but the variable @napop has had a value
assigned to it, which can subsequently be used.
SELECT @napop;
+-----------+
| @napop |
+-----------+
| 309632000 |
+-----------+

Jianxin Li (UWA) Stored routines 10 / 31


Stored Routines

Multiple statements

To enhance our procedures further we need to be able to perform a sequence


of SQL statements inside a procedure, not just a single statement.
This can be done by putting the statements between BEGIN and END.
CREATE PROCEDURE myproc()
BEGIN

/* A whole bunch of MySQL statements */

END

One problem that immediately arises is how to terminate each of the


statements inside the BEGIN / END area if we just use the semicolon then
MySQL will think that the procedure definition has terminated.

Jianxin Li (UWA) Stored routines 11 / 31


Stored Routines

Temporarily change delimiters

The solution to this is to temporarily change the delimiter so that we can enter
the entire procedure.
DELIMITER ++
CREATE PROCEDURE myproc()
BEGIN

/* A whole bunch of MySQL statements */


/* each terminated with the usual semicolon */

END++
DELIMITER ;

The first line temporarily changes the delimiter to ++, then the entire
procedure is entered, and finally the delimiter is changed back again.

Jianxin Li (UWA) Stored routines 12 / 31


Stored Routines

Procedure Variables

Of course, in order to use multiple statements effectively it helps to be able to


use local variables within the procedure1 .
CREATE PROCEDURE regionSummary(rgn TEXT)
BEGIN
DECLARE rp INT;
CALL regionPop(rgn, rp);
END

This fragment creates a local variable called rp and then calls the previously
defined procedure to assign the total population of the specified region to that
variable.

1
Henceforth I will not include the DELIMITER statements
Jianxin Li (UWA) Stored routines 13 / 31
Stored Routines

Multiple statements

We can complete this procedure fragment by using the variable that we have
just evaluated in a subsequent SQL statement.
CREATE PROCEDURE regionSummary(rgn TEXT)
BEGIN
DECLARE rp INT;
CALL regionPop(rgn,rp);
SELECT C.name, C.population,
C.population / rp * 100 as perc
FROM country C
WHERE C.region = rgn
ORDER BY C.population
DESC LIMIT 5;
END

This has simply added one more SELECT statement that performs another
query to list the five most populous countries in that region.

Jianxin Li (UWA) Stored routines 14 / 31


Stored Routines

Calling this procedure

mysql> CALL regionSummary("Caribbean");


+--------------------+------------+---------+
| name | population | perc |
+--------------------+------------+---------+
| Cuba | 11201000 | 29.3681 |
| Dominican Republic | 8495000 | 22.2732 |
| Haiti | 8222000 | 21.5574 |
| Puerto Rico | 3869000 | 10.1442 |
| Jamaica | 2583000 | 6.7724 |
+--------------------+------------+---------+

Jianxin Li (UWA) Stored routines 15 / 31


Programming Routines

Other constructs

In addition to this basic functionality, stored procedures can also perform


rudimentary selection and repetition with constructs such as
IF-THEN-ELSE
WHILE...END WHILE
REPEAT...END REPEAT
LOOP...END LOOP

Jianxin Li (UWA) Stored routines 16 / 31


Programming Routines

Largest and Smallest

Suppose that instead of the top five countries for the specified region, we
wanted to list the most populous and least populous.
We could do this with three SELECT statements one to find the minimum
and maximum country populations in that region, then one each to find which
country has the minimum and the maximum population.
However we could do this with just one SELECT statement provided we
could process the results afterwards.

Jianxin Li (UWA) Stored routines 17 / 31


Programming Routines

The algorithm

The basic idea is simple:


Suppose I were to read out a sequence of 750 numbers, and then ask you what
the biggest number was? How would you approach this without remembering
all the 750 numbers?

Jianxin Li (UWA) Stored routines 18 / 31


Programming Routines

The algorithm

The basic idea is simple:


Suppose I were to read out a sequence of 750 numbers, and then ask you what
the biggest number was? How would you approach this without remembering
all the 750 numbers?

Always remember the biggest so far, and as each new number comes
along, compare it to the number that is being remembered and update the
remembered number only if the new number is bigger.

Jianxin Li (UWA) Stored routines 18 / 31


Programming Routines

A stored procedure

DELIMITER ++
CREATE PROCEDURE regionLimits(rgn TEXT)
BEGIN SET numDone = 1;

DECLARE numRows INT; WHILE numDone < numRows DO


DECLARE numDone INT; FETCH regionOnly INTO cname, cpop;
DECLARE minP INT; IF (cpop < minP) THEN
DECLARE maxP INT; SET minP = cpop;
DECLARE minC VARCHAR(50); SET minC = cname;
DECLARE maxC VARCHAR(50); END IF;
DECLARE cname VARCHAR(50); IF (cpop > maxP) THEN
DECLARE cpop INT; SET maxP = cpop;
SET maxC = cname;
DECLARE regionOnly CURSOR FOR END IF;
SELECT C.name, C.population SET numDone = numDone + 1;
FROM country C END WHILE;
WHERE region = rgn;
CLOSE regionOnly;
OPEN regionOnly;
SELECT FOUND_ROWS() INTO numRows; SELECT minC as smallest,
minP as smallestPop,
FETCH regionOnly INTO cname, cpop; maxC as largest,
SET minP = cpop; maxP as largestPop;
SET maxP = cpop; END++
SET minC = cname; DELIMITER ;
SET maxC = cname;

Jianxin Li (UWA) Stored routines 19 / 31


Programming Routines

Cursors

A cursor is essentially a mechanism to store the results of a query, and then


process the results row-by-row.
Cursors essentially support only four statements
DECLARE...CURSOR FOR declares a cursor
OPEN... opens the cursor
FETCH...INTO fetches the current row for processing
CLOSE... closes the cursor

Cursors are also the primary mechanism by which client programs interact
with the database.

Jianxin Li (UWA) Stored routines 20 / 31


Programming Routines

Lifecycle of a cursor conception

Think of a cursor as a machine that runs a SQL query and returns the results
of this query to you one row at a time as you ask for them.
A cursor springs into existence when execution of the stored procedure
reaches a DECLARE...CURSOR statement it does not run the statement at
this point, but just remembers it.
DECLARE myCursor CURSOR FOR
SELECT year, rate
FROM Investments;

myCursor

Jianxin Li (UWA) Stored routines 21 / 31


Programming Routines

Lifecycle of a cursor birth

At some later stage, when the OPEN statement is executed, the cursor actually
runs the query.
OPEN myCursor;

year rate
myCursor 2007 10.183
2008 -8.954
2009 -11.239
2010 2.110
2011 4.102
2012 5.419
2014 7.451

It does not return the result of the query, but just remembers it.
Jianxin Li (UWA) Stored routines 22 / 31
Programming Routines

Lifecycle of a cursor working life

The data is extracted from the cursor one row at a time using FETCH.
Each FETCH call causes it to return whichever row it is pointing to
FETCH myCursor INTO a, b;

year rate
2007, 10.183
myCursor 2007 10.183
2008 -8.954
2009 -11.239
2010 2.110
2011 4.102
2012 5.419
2014 7.451

Jianxin Li (UWA) Stored routines 23 / 31


Programming Routines

Lifecycle of a cursor working life

The data is extracted from the cursor one row at a time using FETCH.
Each FETCH call causes it to return whichever row it is pointing to and then
shift the pointer to the next row.
FETCH myCursor INTO a, b;

year rate
myCursor 2007 10.183
2008 -8.954
2009 -11.239
2010 2.110
2011 4.102
2012 5.419
2014 7.451

Jianxin Li (UWA) Stored routines 23 / 31


Programming Routines

Lifecycle of a cursor working life

The data is extracted from the cursor one row at a time using FETCH.
Each FETCH call causes it to return whichever row it is pointing to and then
shift the pointer to the next row.
FETCH myCursor INTO a, b;

year rate
myCursor 2007 10.183
2008 -8.954
2009 -11.239
2010 2.110
2011 4.102
2012 5.419
2014 7.451

Jianxin Li (UWA) Stored routines 23 / 31


Programming Routines

Lifecycle of a cursor death


Eventually, after multiple FETCH statements, the cursor will have gone
through all of the rows and have no more data left to return.

year rate
myCursor 2007 10.183
2008 -8.954
2009 -11.239
2010 2.110
2011 4.102
2012 5.419
2014 7.451

CLOSE myCursor; closes the cursor and reclaims the memory and/or other
resources it is using.
Jianxin Li (UWA) Stored routines 24 / 31
Programming Routines

Cursor control

CREATE PROCEDURE regionLimits(rgn TEXT)


BEGIN

DECLARE regionOnly CURSOR FOR


SELECT C.name, C.population
FROM country C
WHERE region = rgn;

OPEN regionOnly;

/* process the rows */

CLOSE regionOnly;
END

Jianxin Li (UWA) Stored routines 25 / 31


Programming Routines

How many rows?

We will use a loop to process each row, and so we need to know how many
rows the cursor contains; this can be found from the MySQL function
FOUND_ROWS() which returns the number of rows that the last query found.

DECLARE numRows INT;


DECLARE numDone INT;

/* Declare and open cursor */

SELECT FOUND_ROWS() INTO numRows;


WHILE numDone < numRows DO

/* Process a row */

SET numDone = numDone + 1;


END WHILE;

Jianxin Li (UWA) Stored routines 26 / 31


Programming Routines

Storing max and min

In order to use the cursor to process each row, we need to have variables to
store the name and population of the most populous found so far and least
populous found so far, along with variables for the values extracted from
each row as it is processed.

So the declaration section will need to have the following added to it:
DECLARE minP INT;
DECLARE maxP INT;
DECLARE minC VARCHAR(50);
DECLARE maxC VARCHAR(50);

DECLARE cname VARCHAR(50);


DECLARE cpop INT;

Jianxin Li (UWA) Stored routines 27 / 31


Programming Routines

Initializing

These variables are initialized with the values from the first row (after we have
read just one row, then the name and population are the best-so-far for both
maximum and minimum population.)

So immediately after the SELECT FOUND_ROWS() INTO numRows we put


FETCH regionOnly INTO cname, cpop;

SET minP = cpop;


SET maxP = cpop;

SET minC = cname;


SET maxC = cname;

SET numDone = 1;

Jianxin Li (UWA) Stored routines 28 / 31


Programming Routines

Inside the loop

In the loop, we fetch the contents of the next row and compare them to the
existing minimum/maximum values:
WHILE numDone < numRows DO
FETCH regionOnly INTO cname, cpop;
IF (cpop < minP) THEN
SET minP = cpop;
SET minC = cname;
END IF;
IF (cpop > maxP) THEN
SET maxP = cpop;
SET maxC = cname;
END IF;
SET numDone = numDone + 1;
END WHILE;

Jianxin Li (UWA) Stored routines 29 / 31


Programming Routines

Finally

And finally after the loop we print the output.


SELECT minC as smallest,
minP as smallestPop,
maxC as largest,
maxP as largestPop;

The output from the whole procedure is then something like


CALL regionLimits("Caribbean");
+----------+-------------+---------+------------+
| smallest | smallestPop | largest | largestPop |
+----------+-------------+---------+------------+
| Anguilla | 8000 | Cuba | 11201000 |
+----------+-------------+---------+------------+

Jianxin Li (UWA) Stored routines 30 / 31


Programming Routines

Conclusion

Although MySQL supports stored procedures and functions, the


programming tools available are very rudimentary and awkward compared to
a general-purpose programming language.
Therefore while stored routines are extremely useful when they consist of
things that can be expressed easily in SQL, they become very awkward when
performing general processing.
Therefore in the absence of a compelling reason (e.g. security) to use stored
routines, most non-SQL processing should be performed at the client, and not
on the server.

Jianxin Li (UWA) Stored routines 31 / 31

You might also like