Mysql
Mysql
1/63
Contents at a Glance
1. SQL with MySQL ..................................................................................................................4
2. MySQL Functions ...............................................................................................................20
3. MySQL Stored Routines .................................................................................................... 48
Tables and Figures .................................................................................................................63
2/63
Table of Contents
1. SQL with MySQL ..................................................................................................................4
1.1. Standard SQL ................................................................................................................ 4
1.1.1. SQL Keywords ........................................................................................................ 4
1.2. MySQL Dialects ............................................................................................................. 5
1.2.1. Database Management .......................................................................................... 7
1.2.2. Data Types ..............................................................................................................9
1.2.3. SELECT Query ..................................................................................................... 10
1.2.4. Data Manipulation Language (DML) .................................................................... 15
1.2.5. Data Definition Language (DDL) .......................................................................... 17
2. MySQL Functions ...............................................................................................................20
2.1. Mathematic/Arithmetic Functions ................................................................................20
2.2. String Functions ...........................................................................................................30
2.3. Date/Time Functions ................................................................................................... 34
2.4. Control Functions ........................................................................................................ 41
2.5. Cast Functions .............................................................................................................45
2.6. Other Functions ........................................................................................................... 46
3. MySQL Stored Routines .................................................................................................... 48
3.1. Stored Procedure ........................................................................................................ 48
3.1.1. Benefits of using Stored Procedure ..................................................................... 48
3.1.2. Create and Drop Stored Procedure ..................................................................... 49
3.1.3. Variables ............................................................................................................... 51
3.1.4. Cursors ..................................................................................................................53
3.1.5. Condition and Exception Handlers .......................................................................55
3.1.6. Flow Controls ........................................................................................................ 55
3.2. Stored Function ........................................................................................................... 59
3.3. Database Trigger .........................................................................................................60
Tables and Figures .................................................................................................................63
Figures ................................................................................................................................ 63
Tables ................................................................................................................................. 63
3/63
1. SQL with MySQL
4/63
Transaction control group
START TRANSACTION is to declare stating database transaction
SET TRANSACTION ISOLATION LEVEL is to specify four levels of isolation level in
order to avoid undesirable phenomena during database transaction.
COMMIT is to confirm all data changes in a transaction to be made permanent.
ROLLBAK is to cancel database transaction to rolls back status before it begins.
Standard SQL
Preparation: Please execute following SQL statements to create sample tables and user,
and insert sample data:
-- Create database
CREATE DATABASE test;
-- Create tables
USE test;
CREATE TABLE DEPT
(
DEPTNO NUMERIC(2) PRIMARY KEY,
DNAME VARCHAR(14) ,
LOC VARCHAR(13)
) ENGINE=InnoDB;
5/63
EMPNO NUMERIC(4) PRIMARY KEY,
ENAME VARCHAR(10),
JOB VARCHAR(9),
MGR NUMERIC(4),
HIREDATE DATE,
SAL NUMERIC(7,2),
COMM NUMERIC(7,2),
DEPTNO NUMERIC(2),
FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO)
)ENGINE=InnoDB;
-- Insert records
INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');
6/63
,1250,1400,30);
INSERT INTO EMP VALUES
(7698,'BLAKE','MANAGER',7839,str_to_date('1-5-1981','%d-%m-%Y'),2
850,NULL,30);
INSERT INTO EMP VALUES
(7782,'CLARK','MANAGER',7839,str_to_date('9-6-1981','%d-%m-%Y'),2
450,NULL,10);
INSERT INTO EMP VALUES
(7788,'SCOTT','ANALYST',7566,str_to_date('13-7-1987','%d-%m-%Y'),
3000,NULL,20);
INSERT INTO EMP VALUES
(7839,'KING','PRESIDENT',NULL,str_to_date('17-11-1981','%d-%m-%Y')
,5000,NULL,10);
INSERT INTO EMP VALUES
(7844,'TURNER','SALESMAN',7698,str_to_date('8-9-1981','%d-%m-%Y'),
1500,0,30);
INSERT INTO EMP VALUES
(7876,'ADAMS','CLERK',7788,str_to_date('13-7-1987',
'%d-%m-%Y'),1100,NULL,20);
INSERT INTO EMP VALUES
(7900,'JAMES','CLERK',7698,str_to_date('3-12-1981','%d-%m-%Y'),95
0,NULL,30);
INSERT INTO EMP VALUES
(7902,'FORD','ANALYST',7566,str_to_date('3-12-1981','%d-%m-%Y'),3
000,NULL,20);
INSERT INTO EMP VALUES
(7934,'MILLER','CLERK',7782,str_to_date('23-1-1982','%d-%m-%Y'),1
300,NULL,10);
7/63
SHOW CREATE DATABASE database Shows create database schema
SHOW CREATE TABLE table Shows create table schema
SHOW CREATE VIEW view Shows create view schema
SHOW CREATE PROCEDURE sp Shows create stored procedure schema
SHOW CREATE FUNCTION sf Shows create stored function schema
SHOW STATUS Shows status
SHOW TALBE STATUS Shows table status
SHOW ERRORS Shows errors
SHOW WARNINGS Shows warnings
SHOW GRANTS Shows grants
SHOW ENGINES Shows database engines
SHOW VARIABLES Shows variables
SHOW CHARACTER SET Shows character set
SHOW COLLATION Shows collation
SHOW PRIVILEGES Shows privileges
SHOW PROCESSLIST Shows list of MySQL processes and threads
8/63
USE database
It used to connect or change to specified database:
mysql> USE information_schema;
Database changed
Number
Table 2 - MySQL Number Type
Type Description
TINYINT(length, decimal) 1 byte
SMALLINT(length) 2 byte
MEDIUMINT(length) 3 byte
INT(length) 4 byte
INTEGER(length) Synonym for INT
BIGINT(length) 8 byte
FLOAT(length) Single precision floating-point number
DOUBLE(length, decimal) Double precision floating-point number
REAL(length, decimal) Synonym for DOUBLE
DECIMAL(length, decimal) Fixed-point number
DEC(length, decimal) Synonym for DECIMAL
NUMERIC(length, decimal) Synonym for DECIMAL
FIXED(length, decimal) Synonym for DECIMAL
BOOL | BOOLEAN Synonym for TINYINT
String
Table 3 - MySQL String Types
Type Description
CHAR(length) Fixed-length string, 0 to 255 character
VARCHAR(length) Variable-length string, 0 to 65525 byte
TINYTEXT 255 byte
TEXT 64 KB
MEDIUM TEXT 16 MB
LONG TEXT 4 GB
9/63
Date/Time
Table 4 - MySQL Date/Time Type
Type Description
DATETIME YYYY-MM-DD HH:MM:SS
DATE YYYY-MM-DD
TIME HH:MM:SS
TIMESTAMP YYYY-MM-DD HH:MM:SS
YEAR YYYY
10/63
| 7839 | KING | PRESIDENT |
| 7844 | TURNER | SALESMAN |
| 7876 | ADAMS | CLERK |
| 7900 | JAMES | CLERK |
| 7902 | FORD | ANALYST |
| 7934 | MILLER | CLERK |
+-------+--------+-----------+
14 rows in set (0.00 sec)
Note: As can be seen above two SQL with LIMIT, LIMIT 0, 3 and LIMIT
3 returns the same result. That means omitting the first argument is
same as 0.
11/63
| 7499 | ALLEN | SALESMAN |
| 7521 | WARD | SALESMAN |
| 7566 | JONES | MANAGER |
+-------+-------+----------+
3 rows in set (0.00 sec)
Note: LIMIT, OFFSET can be used for Web page search result navigation
like go to next or previous pages.
mysql> SELECT ename FROM EMP WHERE NOT EXISTS(SELECT * FROM emp WHERE
ename='KING');
Empty set (0.00 sec)
12/63
SELECT ,,, FROM ,,, WHERE ,,, ANY / ALL
ANY / ALL can be used with sub-query and either =,!=,>,<,<= or >=. Sub-query of
first example using ANY returns list of deptno (multiple rows) 10, 20, 40 and 50
hence the result of query returns list of employees except deptno 30. Sub-query of
second example using ALL also returns list of deptno (multiple rows) 10, 20, 40
and 50 hence the result of the query returns
mysql> SELECT * FROM emp WHERE deptno = ANY(SELECT deptno FROM dept
WHERE loc <> 'CHICAGO');
+-------+--------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+-----
-+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-07-13 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7876 | ADAMS | CLERK | 7788 | 1987-07-13 | 1100.00 | NULL | 20 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+-----
-+--------+
8 rows in set (0.00 sec)
mysql> SELECT * FROM emp WHERE deptno <> ALL(SELECT deptno FROM dept
WHERE loc <> 'CHICAGO');
+-------+--------+----------+------+------------+---------+------
---+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM |
13/63
DEPTNO |
+-------+--------+----------+------+------------+---------+------
---+--------+
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
+-------+--------+----------+------+------------+---------+------
---+--------+
6 rows in set (0.00 sec)
Self-Join statement
We have discussed join statements such as inter join and outer joins (left, right and
full outer) in the Fundamental Database, however there is another join statement
can be used and it is called as self-join. The Self-join statement can join same table
as recursive relationship. The example self-join statement for EMP table joins
empno and mgr columns. This self-join statement returns the result set of
employee and each one of their manager as can be seen below:
Emp
14/63
| 7934 | MILLER | 7782 | CLARK |
| 7369 | SMITH | 7902 | FORD |
| 7788 | SCOTT | 7566 | JONES |
| 7902 | FORD | 7566 | JONES |
| 7566 | JONES | 7839 | KING |
| 7698 | BLAKE | 7839 | KING |
| 7782 | CLARK | 7839 | KING |
| 7876 | ADAMS | 7788 | SCOTT |
+-------+---------------+-------+--------------+
13 rows in set (0.00 sec)
REPLACE
REPLACE is mixture of INSERT with UPDATE when primary key exists:
mysql> SELECT * FROM dept;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
4 rows in set (0.19 sec)
15/63
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
| 50 | IT | Yangon |
+--------+------------+----------+
5 rows in set (0.00 sec)
Note: The row of DEPTNO=50 will be updated because DEPTNO=50 has already
been existed.
TRUNCATE
TRUNCATE drops table and re-create. It is not transaction safe:
mysql> SELECT COUNT(*) FROM t2;
+----------+
| COUNT(*) |
+----------+
| 3000 |
+----------+
1 row in set (0.00 sec)
16/63
| COUNT(*) |
+----------+
| 0 |
+----------+
1 row in set (0.01 sec)
Note:
TRUNCATE is usually much faster than using DELETE however there is
no way to rollback truncated data is because TRUNCATE is not transaction
safe.
IF NOT EXISTS
IF NOT EXISTS is a keyword to check existence of same name when MySQL
database objects are created:
mysql> CREATE DATABASE IF NOT EXISTS msis;
Query OK, 0 rows affected, 1 warning (0.00 sec)
AUTO_INCREMENT
AUTO_INCREMENT is a keyword to define auto number:
mysql> CREATE TABLE mytable(id INT AUTO_INCREMENT, name TINYTEXT,
PRIMARY KEY(id));
Query OK, 0 rows affected (0.14 sec)
17/63
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | tinytext | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.05 sec)
18/63
Records: 3 Duplicates: 0 Warnings: 0
Note: mytable2 was created by mytable with the data however PRI (Primary
Key) and auto_increment were not copied from mytable.
19/63
2. MySQL Functions
MAX(exp), MIN(exp)
It returns maximum and minimum value of exp. Following example returns
maximum and minimum salary from emp table:
mysql> SELECT MAX(sal), MIN(sal) FROM emp;
+----------+----------+
| MAX(sal) | MIN(sal) |
+----------+----------+
| 5000.00 | 800.00 |
+----------+----------+
COUNT([DISTINCT] exp)
It returns a count of number of rows retrieved exclude NULL. Following example
returns count without DISTINCT and with DISTINCT:
mysql> SELECT COUNT(*) FROM emp;
+----------+
| COUNT(*) |
+----------+
| 14 |
+----------+
20/63
+------------------------+
| 3 |
+------------------------+
STD(exp), VARIANCE(exp)
It returns standard deviation and standard variance of exp:
mysql> SELECT deptno, STD(sal), VARIANCE(sal) FROM emp
GROUP BY deptno;
+--------+-------------+----------------+
| deptno | STD(sal) | VARIANCE(sal) |
+--------+-------------+----------------+
| 10 | 1546.142152 | 2390555.555556 |
| 20 | 1004.738772 | 1009500.000000 |
| 30 | 610.100174 | 372222.222222 |
+--------+-------------+----------------+
GROUP_CONCAT(exp)
It returns a concatenated string from selected values. Following example displays
list of employee name by department:
mysql> SELECT deptno, GROUP_CONCAT(ename) FROM emp GROUP BY deptno;
+--------+--------------------------------------+
| deptno | GROUP_CONCAT(ename) |
+--------+--------------------------------------+
| 10 | CLARK,KING,MILLER |
| 20 | SMITH,JONES,SCOTT,ADAMS,FORD |
| 30 | ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES |
+--------+--------------------------------------+
21/63
+----------------+
ABS(num)
It returns absolute value of num:
mysql> SELECT ABS(10);
+---------+
| ABS(10) |
+---------+
| 10 |
+---------+
SQRT(num)
It returns square root of num:
mysql> SELECT SQRT(100);
+-----------+
| SQRT(100) |
22/63
+-----------+
| 10 |
+-----------+
23/63
| ROUND(4.56, 2) |
+----------------+
| 4.56 |
+----------------+
24/63
+-----------------+
| 1.5574077246549 |
+-----------------+
RAND([seed])
It returns random number in between 0 to 1:
mysql> SELECT RAND();
+------------------+
| RAND() |
+------------------+
| 0.64443232365365 |
+------------------+
25/63
+--------------------------+
| GREATEST(10, 20, 30, 40) |
+--------------------------+
| 40 |
+--------------------------+
PI()
It returns the ratio of the circumference of a circle:
mysql> SELECT PI();
+----------+
| PI() |
+----------+
| 3.141593 |
+----------+
CRC32(exp)
It returns computed cyclic redundancy check with a 32-bit unsigned exp:
mysql> SELECT CRC32('MySQL');
+----------------+
| CRC32('MySQL') |
+----------------+
| 3259397556 |
+----------------+
SIGN(num)
It returns the sign of the argument as -1, 0, or 1 that depend on whether num is
negative, zero, or positive:
mysql> SELECT SIGN(-5);
26/63
+----------+
| SIGN(-5) |
+----------+
| -1 |
+----------+
MOD(x, y)
It returns surplus of x divided by y:
mysql> SELECT MOD(9,3);
+----------+
| MOD(9,3) |
+----------+
27/63
| 0 |
+----------+
FORMAT(num, dec)
It formats num to a format like '#,###,###.##' with round off of dec and returns the
result as a string.
mysql> SELECT FORMAT(12345.6789, 4);
+-----------------------+
| FORMAT(12345.6789, 4) |
+-----------------------+
| 12,345.6789 |
+-----------------------+
28/63
mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
+--------------------------------+
| INTERVAL(10, 1, 10, 100, 1000) |
+--------------------------------+
| 2 |
+--------------------------------+
29/63
2.2. String Functions
ASCII(srt), CHAR(num, …), ORD(str)
Those functions are converting character and ASCII code:
mysql> SELECT ASCII('A');
+------------+
| ASCII('A') |
+------------+
| 65 |
+------------+
Note:
ORD returns the code for that character in case if the leftmost
character of the string is a multi-byte character.
If the leftmost character is NOT a multi-byte character, ORD() then
it returns the same value as what ASCII() function returns.
30/63
+----------------------+
| 4 |
+----------------------+
Note:
If the database uses multi-byte character set, then CHAR_LENGTH and
LENGTH may returns the different numbers.
STRCOMP(str1, str2)
It returns 0 if str1=str2, -1 if str1 < str2 or 1 if str1>str2:
mysql> SELECT STRCMP('ABC', 'ABC');
+----------------------+
| STRCMP('ABC', 'ABC') |
+----------------------+
| 0 |
+----------------------+
31/63
| ABCDEFGHI |
+-----------------------------+
LOWER(str), UPPER(str)
32/63
It returns lower case str, upper case str:
mysql> SELECT LOWER('MSIS');
+----------------+
| LOWER('MSIS') |
+----------------+
| msis |
+----------------+
33/63
+----------------------+
| MSIS |
+----------------------+
34/63
MICROSECOND ‘Microsecond’
35/63
+------------+
| 2007-05-20 |
+------------+
36/63
| DATE(NOW()) |
+-------------+
| 2007-05-20 |
+-------------+
37/63
+-------------+
| YEAR(NOW()) |
+-------------+
| 2007 |
+-------------+
38/63
+-------------------+
39/63
Table 7 - Format type for Date/Time Functions
Format type Description
%a Day (Sun - Sat)
%b Month (Jan - Dec)
%c Month (0 - 12)
%D Day (1sr, 2nd, 3rd ,,,)
%d Day (00 -31)
%e Day (0 - 31)
%f Microsecond
%H Time (00 - 23)
%h Time (01 - 12)
%l Time (01 - 12)
%i Minute (00 - 59)
%j Days of Year (001 - 336)
%k Time (0 - 23)
%l Time (1 - 12)
%M Month (January - December)
%m Month (00 - 12)
%p AM | PM
%r hh:mm:ss AM/PM
%S Second (00 - 59)
%s Second (00 - 59)
%T hh:mm:ss
%U Week of Year (00 – 53, Start at Sunday)
%u Week of Year (00 - 53, Start at Monday)
%V Together with %X
%v Together with %X
%W Day (Sunday - Saturday)
%w Day (0 - 6)
%X Together with %V
%x Together with %V
%Y Year (4digits)
%y Year (2 digits)
%% ‘%’ Literal
STR_TO_DATE(str, format)
It is inverse of DATE_FORMAT function:
mysql> SELECT STR_TO_DATE('07 May 20th', '%y %M %D');
40/63
+----------------------------------------+
| STR_TO_DATE('07 May 20th', '%y %M %D') |
+----------------------------------------+
| 2007-05-20 |
+----------------------------------------+
41/63
+-----------------------------+
| Wrong |
+-----------------------------+
CASE
CASE function execute statements that matches with specified value or condition
after WHEN. There are two types of CASE conditional function such as Value type
and Condition type as stated in following table:
42/63
WHEN condition2 THEN result2
ELSE resultElse
END
43/63
| 7876 | ADAMS | CLERK | LEVEL 1 |
| 7900 | JAMES | CLERK | LEVEL 1 |
| 7902 | FORD | ANALYST | LEVEL 2 |
| 7934 | MILLER | CLERK | LEVEL 1 |
+-------+--------+-----------+---------+
mysql> SELECT
SUM(CASE WHEN deptno = 10 THEN 1 ELSE 0 END) AS DEPT10,
SUM(CASE WHEN deptno = 20 THEN 1 ELSE 0 END) AS DEPT20,
SUM(CASE WHEN deptno = 30 THEN 1 ELSE 0 END) AS DEPT30,
SUM(CASE WHEN deptno = 40 THEN 1 ELSE 0 END) AS DEPT40
FROM emp;
+--------+--------+--------+--------+
| DEPT10 | DEPT20 | DEPT30 | DEPT40 |
+--------+--------+--------+--------+
| 3 | 5 | 6 | 0 |
+--------+--------+--------+--------+
44/63
1 row in set (0.00 sec)
BINARY(str)
It converts and returns binary byte string from non-binary string:
mysql> SELECT ename FROM emp WHERE ename = 'scott';
+-------+
| ename |
+-------+
45/63
| SCOTT |
+-------+
1 row in set (0.00 sec)
COALESCE(value1, value2, …)
COALESCE returns first non-NUL value from value list or returns NULL if there are
no non-NULL values:
mysql> SELECT COALESCE(NULL, NULL, 2, NULL);
+-------------------------------+
| COALESCE(NULL, NULL, 2, NULL) |
+-------------------------------+
| 2 |
+-------------------------------+
46/63
| JAMES | 950.00 | NULL | 950.00 |
| FORD | 3000.00 | NULL | 3000.00 |
| MILLER | 1300.00 | NULL | 1300.00 |
+--------+---------+---------+---------+
14 rows in set (0.00 sec)
MD5(string), SHA1(string)
Those functions compute hash value and return. MD5 (Message Digest Algorithm)
returns 128-bit checksum in 32-bit hexadecimal notation and SHA1 (Secure Hash
Algorithm) returns 160-bit checksum in 40-bit hexadecimal notation:
47/63
3. MySQL Stored Routines
INSERT
UPDATE
DELETE
48/63
3.1.2. Create and Drop Stored Procedure
CREATE PROCEDURE statement creates a stored procedure and body of the stored
procedure starts with BEGIN and end with END. The stored procedure can be deleted by
DROP PROCEDURE statement. The stored procedure takes parameters and each
parameter has own direction such as stated in table below:
Following access privileges are required for MySQL user who need to create, amend and
execute stored procedures:
Syntax of drop the stored procedure is as follows. [IF EXISTS] is an option to drop when
stored procedure is already existed:
DROP PROCEDURE [IF EXISTS] name;
The stored procedure will be invoked by CALL statement with name of the stored procedure
and parameters according to definition as following syntax:
CALL name(parameter[, ...])
49/63
The following is an example of a simple stored procedure with IN parameter. The example
takes price as for WHERE condition and execute SELECT statement. The example uses the
mysql client DELIMITER command to change the statement delimiter from ; to // while the
procedure is being defined. This allows the ; delimiter used in the procedure body to be
passed through to the server rather than being interpreted by mysql itself. The // changes
back to ; after creation of the stored procedure with DELIMTER ; command.
Following SQL is for preparation to create sample tables during this chapter:
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
`id` int(11) NOT NULL,
`title` varchar(50) default NULL,
`isbn` varchar(50) default NULL,
`price` int(11) default '0',
`author_id` varchar(50) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> DELIMITER //
mysql> CREATE PROCEDURE sp01 (IN p INT)
BEGIN
SELECT id, title, price FROM BOOK WHERE price > p;
END
//
Query OK, 0 rows affected (0.09 sec)
50/63
Note: DELIMITER ; is to set back the delimiter as ;. You can not execute
subsequence SQL commands if you have forgotten this command.
mysql> DELIMITER ;
mysql> CALL sp01(400);
+----+--------------------------+-------+
| id | title | price |
+----+--------------------------+-------+
| 3 | Introduction to Database | 500 |
| 4 | Introduction to Java | 750 |
+----+--------------------------+-------+
2 rows in set (0.11 sec)
Note: Stored Procedure sp01 selects books from book table with the
price more than 400.
3.1.3. Variables
Local variables can be used in Stored Procedure with following expressions:
SELECT column[,...] INTO variable[,...] FROM table WHERE conditions
Variable Variable
Example of local variables which takes IN and OUT parameter is as follows. The example
takes price as input parameter and set output parameter as number of books that price is
higher than input parameter using SELECT INTO statement:
mysql> DELIMITER //
mysql> CREATE PROCEDURE sp02(IN p INT, OUT count INT)
BEGIN
SELECT COUNT(*) INTO count FROM book WHERE price >= p;
END
//
Query OK, 0 rows affected (0.11 sec)
mysql> DELIMITER ;
mysql> CALL sp02(300, @count);
Query OK, 0 rows affected (0.00 sec)
51/63
mysql> SELECT @count;
+--------+
| @count |
+--------+
| 3 |
+--------+
1 row in set (0.00 sec)
@count is local variable of MySQL session that is available within the session established
by mysql client. As can be seen, SELECT @count returns value of the local variables as 2
that is number of books price more than input parameter.
Another example of following stored procedure using SELECT ,,, INTO displays list of books
with price more than average. The local variable average sets average price and copy to
avg OUT parameter:
mysql> DELIMITER //
mysql> CREATE PROCEDURE sp03(OUT avg INT)
BEGIN
DECLARE average INT;
SELECT AVG(price) INTO average FROM book;
SELECT id, title, price FROM book WHERE price > average;
SET avg = average;
END
//
Query OK, 0 rows affected (0.03 sec)
mysql> DELIMITER ;
mysql> call sp03(@avg);
+----+--------------------------+-------+
| id | title | price |
+----+--------------------------+-------+
| 3 | Introduction to Database | 500 |
| 4 | Introduction to Java | 750 |
+----+--------------------------+-------+
2 rows in set (0.02 sec)
52/63
Query OK, 0 rows affected (0.02 sec)
3.1.4. Cursors
Cursor is a control structure used for processing individual rows returned by a query. The
cursor enable to fetch a record from record set in stored procedure one by one to process.
1 MySQL 750
Figure below shows how to use cursor in stored procedure. The cursor can be opened after
the declaration and cursor can fetch variable by row until the loop condition ends. The cursor
must be closed after processing that is usually just before the stored procedure ends.
53/63
Figure 6 – Sample (sp04) Flowchart
Example using cursor below sets total price from book table that is same value as what
SUM function returns:
CREATE PROCEDURE sp04(OUT total INT)
BEGIN
DECLARE flag BIT DEFAULT 0;
DECLARE p INT DEFAULT 0;
DECLARE cur CURSOR FOR SELECT price FROM book;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag=1;
SET total =0;
OPEN cur;
WHILE flag != 1 DO
FETCH cur INTO p;
54/63
IF flag=0 THEN
SET total = total + p;
END IF;
END WHILE;
CLOSE cur;
END
Example below is an exception handler that occurs when cursor crosses last row of the table.
(No more rows can be found). Then statement of SET done = 1 execute to set done
valuable as 1. done as a flag to be used for such as WHILE loop condition to be continued:
WHILE done != 1 DO
END WHILE;
CASE implements a complex conditional construct as syntax stated below (Two types):
CASE variable
WHEN value THEN statement [...]
[ELSE] statement [...]
END CASE
Or
CASE
55/63
WHEN condition THEN statement [...]
[ELSE] statement [...]
END CASE
Example of CASE in stored procedure to display EMP table with Job Level depends on the
job title as follows:
Note : SET GLOBAL log_bin_trust_function_creators = 1;
mysql> DELIMITER //
mysql> CREATE FUNCTION sf_case(job VARCHAR(10)) RETURNS VARCHAR(10)
BEGIN
DECLARE level VARCHAR(10);
CASE job
WHEN 'CLERK' THEN SET level = 'Level 1';
WHEN 'SALESMAN' THEN SET level = 'Level 1';
WHEN 'MANAGER' THEN SET level = 'Level 2';
WHEN 'ANALYST' THEN SET level = 'Level 2';
WHEN 'PRESIDENT' THEN SET level = 'Level 3';
ELSE SET level = 'N/A';
END CASE;
RETURN level;
END
//
Query OK, 0 rows affected (0.02 sec)
mysql> DELIMITER ;
mysql> SELECT ename, job, sf_case(job) FROM emp;
+--------+-----------+--------------+
| ename | job | sf_case(job) |
+--------+-----------+--------------+
| SMITH | CLERK | Level 1 |
| ALLEN | SALESMAN | Level 1 |
| WARD | SALESMAN | Level 1 |
| JONES | MANAGER | Level 2 |
| MARTIN | SALESMAN | Level 1 |
| BLAKE | MANAGER | Level 2 |
| CLARK | MANAGER | Level 2 |
| SCOTT | ANALYST | Level 2 |
| KING | PRESIDENT | Level 3 |
| TURNER | SALESMAN | Level 1 |
| ADAMS | CLERK | Level 1 |
| JAMES | CLERK | Level 1 |
| FORD | ANALYST | Level 2 |
| MILLER | CLERK | Level 1 |
56/63
+--------+-----------+--------------+
14 rows in set (0.19 sec)
LOOP implements a simple loop construct that enables repeated execution of the
statements as syntax stated below:
[label:]LOOP
Statement
END LOOP[label]
LEAVE is used to exit any labeled flow control construct and it can be used within BEGIN ...
END or loop constructs such as LOOP, REPEAT and WHILE as syntax stated below:
LEAVE[label]
Example of LOOP and LEAVE in stored function is as follows. The stored function takes
seed and repeat max times to concatenate seed to be returned:
mysql> DELIMITER //
CREATE FUNCTION sf_loop(seed VARCHAR(5), max INT) RETURNS
VARCHAR(255)
BEGIN
DECLARE cnt INT DEFAULT 0;
DECLARE result VARCHAR(255) DEFAULT seed;
label1 : LOOP
SET cnt = cnt + 1;
IF cnt >= max THEN
LEAVE label1;
ELSE
SET result = CONCAT_WS('', result, seed);
END IF;
END LOOP label1;
RETURN result;
END
//
mysql> select sf_loop('Msis', 10);
+--------------------------------+
| sf_loop('Msis', 10) |
+--------------------------------+
| MsisMsisMsisMsisMsisMsisMsisMsisMsisMsis |
+--------------------------------+
ITERATE repeats loop goes back to the place stated in label and can be used for LOOP,
REPEAT, and WHILE statements as syntax stated below:
57/63
ITERATE label
The statement inside REPEAT is repeated until the condition becomes true as syntax stated
below. REPEAT always enters the loop at least one time:
[label:]REPEAT
Statement
UNTIL condition END REPEAT[label]
The statement inside WHILE is repeated as long as the condition is true as syntax stated
below:
[label:]WHILE condition DO
Statement
END WHILE[label]
//
Query OK, 0 rows affected (0.23 sec)
mysql> delimiter ;
mysql> SELECT sf_while(10);
+--------------+
| sf_while(10) |
+--------------+
| 55 |
+--------------+
1 row in set (0.00 sec)
58/63
3.2. Stored Function
Stored Function is also one of the stored routines and it has similar syntax as what stored
procedure has. The stored function returns value to where it was called. The stored function
can be called from DML statements such as SELECT, INSERT, UPDATE and DELETE
directly without using CALL. However the stored function does not support transaction such
as START TRANSACTION, SET AUTOCOMMIT, COMMIT and ROLLBACK statements
and the stored function locks tables that have been accessed by the function while function
is executed. Following table highlights the differences in between stored procedure and
stored function:
Syntax of drop the stored function is as follows. [IF EXISTS] is an option to drop when stored
function is already existed:
DROP FUNCTION [IF EXISTS] name;
Example of stored function that returns area of triangle based on weight and height input
parameters as follows:
mysql> DELIMITER //
mysql> CREATE FUNCTION my_triangle(width INT, height INT) RETURNS INT
BEGIN
DECLARE result INT;
SET result = width * height / 2;
RETURN result;
END
//
Query OK, 0 rows affected (0.02 sec)
mysql> DELIMITER ;
mysql> SELECT sf01(10, 20);
+--------------+
59/63
| sf01(10, 20) |
+--------------+
| 100 |
+--------------+
1 row in set (0.03 sec)
Another example of stored function is with simple SQL statement. The function takes Author
ID (VARCHAR type) as input parameter and returns number of books belongs to the author:
mysql> DELIMITER //
mysql> CREATE FUNCTION sf02(author VARCHAR(10)) RETURNS INT
BEGIN
DECLARE result INT DEFAULT 0;
SELECT COUNT(*) INTO result FROM book WHERE author_id =
author;
RETURN result;
END
//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> SELECT sf02('01');
+------------+
| sf02('01') |
+------------+
| 3 |
+------------+
1 row in set (0.00 sec)
60/63
1. Client execute DML to book table
INSERT
UPDATE
DELETE
3. Trigger inserts a record with OLD and New values before or after DML is executed
Syntax of create a trigger is as follows. Trigger event as DML statements such as INSERT,
UPDATE and DELETE and timing of the event such as BEFORE and AFTER.
CREATE TRIGGER name event ON table FOR EACH ROW
Keywords NEW and OLD can be used in the body of trigger with column name such as
NEW.price and OLD.price. OLD.price refers to the value of price field before event occurs
and NEW.price refers to the same field after event occurs. Events that can use those
keywords are stated in two tables below:
61/63
Table 14 - Trigger timing with event matrix
Timing INSERT UPDATE DELETE
BEFORE NEW (Editable) NEW (Editable), OLD OLD
AFTER NEW NEW, OLD OLD
Example below is the trigger to insert a row into book_history table before updating of book
table. Upon update on book table (Just before update exactly), trigger tr01 invokes to insert
a row into book_history table with OLD (price_before) and NEW (price_after).
Example of creating a trigger and update book table to invoke the trigger
mysql> delimiter //
mysql> CREATE TRIGGER tr_update
BEFORE UPDATE ON book FOR EACH ROW
BEGIN
INSERT INTO book_history(book_id, title, price_before, price_after,
updated, event) VALUES(OLD.id, OLD.title, OLD.price, NEW.price,
CURRENT_TIMESTAMP(), 'UPDATE');
END
//
62/63
Tables and Figures
Figures
Tables
63/63