Sie sind auf Seite 1von 158

LAB MANUAL

FOR

DATABASE MANAGEMENT SYSTEM

Prepared By: ooooooXXXXXooooooo

1|Page

MYSQL

Introduction: The following table shows each of the prompts you may summarizes what they mean about the state that mysql is in: What is MySQL? MySQL, the most popular Open Source SQL database management system, is developed, distributed, and supported by MySQL AB. MySQL AB is a commercial company, founded by the MySQL developers. It is a second generation Open Source company that unites Open Source values and methodology with a successful business model. History of MySQL We started out with the intention of using the mySQL database system to connect to our tables using our own fast low-level (ISAM) routines. However, after some testing, we came to the conclusion that mySQL was not fast enough or flexible enough for our needs. This resulted in a new SQL interface to our database but with almost the same API interface as mySQL. This API was designed to allow third-party code that was written for use with mSQL to be ported easily for use with MySQL. MySQL is named after co-founder Monty Widenius's daughter My. The name of the MySQL Dolphin (our logo) is Sakila, which was chosen by the founders of MySQL AB from a huge list of names suggested by users in our Name the Dolphin contest. The winning name was submitted by Ambrose Twebaze, an Open Source software developer from Swaziland, Africa. According to Ambrose, the feminine name Sakila has its roots in SiSwati, the local language of Swaziland. Sakila is also the name of a town in Arusha, Tanzania, near Ambrose's country of origin, Uganda. The Main Features of MySQL see and

Uses GNU Automake, Autoconf, and Libtool for portability. The MySQL Server design is multi-layered with independent modules. Fully multi-threaded using kernel threads. It can easily use multiple
CPUs if they are available.

Provides transactional and non-transactional storage engines. Uses very fast B-tree disky tables (MyISAM) with index compression.

2|Page

Relatively easy to add other storage engines. This is useful if you


want to provide an SQL interface for an in-house database.

A very fast thread-based memory allocation system. Very fast joins using an optimized one-sweep multi-join. In-memory hash tables, which are used as temporary tables. SQL functions are implemented using a highly optimized class library
and should be as fast as possible. Usually allocation at all after query initialization. detector) as well as with Valgrind, a GPL tool . there is no memory

The MySQL code is tested with Purify (a commercial memory leakage

How to Write and execute mysql, commands/programs:

1). Open your run oracle application by the following navigation Start->run ->telnet 192.168.1.2 And then press ok button.

2). You will be asked for user name, password. You have to enter user name, pass word. As user name: student rollno(10G01A0501) Password: *******(specified password from system admin)

3). Upon successful login you will get login prompt. In that you enter following command mysql u studentrollno

4). And then successful connect from user client to server then u get mysql prompt.

3|Page

If you type your programs at mysql prompt then screen will look like follow: Mysql>show databases; Displays available database on user login. Mysql>use databasename; Select required database. Mysql>show tables; Displays existing tables on user name.

Prompt mysql> -> > > `> /*>

Meaning Ready for new command. Waiting for next line of multiple-line command. Waiting for next line, waiting for completion of string that began with a single quote(). Waiting for next line, waiting for completion of string that began with a single quote(). Waiting for next line, waiting for completion of string that began with a single quote(`). Waiting for next line, waiting for completion of string that began with a single quote().

a a a a

Overview of MYSQL DDL, DML and DCL Commands.

DDL is Data Definition Language statements. Some examples: CREATE - to create objects in the database ALTER - alters the structure of the database DROP - delete objects from the database TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed 4|Page

COMMENT - add comments to the data dictionary GRANT - gives user's access privileges to database REVOKE - withdraw access privileges given with the GRANT command DML is Data Manipulation Language statements. Some examples: SELECT - retrieve data from the a database INSERT - insert data into a table UPDATE - updates existing data within a table DELETE - deletes all records from a table, the space for the records remain CALL - call a PL/MYSQL or Java subprogram EXPLAIN PLAN - explain access path to data LOCK TABLE - control concurrency DCL is Data Control Language statements. Some examples: COMMIT - save work done SAVEPOINT - identify a point in a transaction to which you can later roll back ROLLBACK - restore database to original since the last COMMIT SET TRANSACTION - Change transaction options like what rollback segment to use

5|Page

Data types: Definition: Data type is the characteristic of columns and variables that defines what types of data values them values they can store. The characterstic indicating whether a data item represents a number, date,character string,etc.

Mysql is structure query language.Mysql contains different data types those are: 1.Numeric types; 1.BIT 2.TINYINT 3.BOOLEAN 4.SMALLINT 5.MEDIUMINT 6.INT 7.INTEGER 8.BIGINT 9.FLOAT 10.DOUBLE 11.DECIMAL 2.Date and Time types: 1.DATE 2.TIME 3.DATETIME 4.TIMESTAMP 5.YEAR

6|Page

3.String Data types: 1.CHAR 2.VARCHAR 3.TEXT 4.BLOB 5.MEDIUMITEX 6.BINARY 7.VARBINARY 8.ENUM 9.SET 10.LONGTEXT Data Type Storage Requirements Storage Requirements for Numeric Types Data Type TINYINT SMALLINT MEDIUMINT INT, INTEGER BIGINT FLOAT(p) FLOAT DOUBLE [PRECISION], REAL DECIMAL(M,D), NUMERIC(M,D) BIT(M) Storage Required 1 byte 2 bytes 3 bytes 4 bytes 8 bytes 4 bytes if 0 <= p <= 24, 8 bytes if 25 <= p <= 53 4 bytes 8 bytes Varies; see following discussion approximately (M+7)/8 bytes

Storage Requirements for Date and Time Types Data Type DATE TIME DATETIME TIMESTAMP YEAR Storage Required 3 bytes 3 bytes 8 bytes 4 bytes 1 byte

7|Page

Storage Requirements for String Types In the following table, M represents the declared column length in characters for non-binary string types and bytes for binary string types. L represents the actual length in bytes of a given string value. Data Type CHAR(M) Storage Required M w bytes, 0 <= M <= 255, where w is the number of bytes required for the maximum-length character in the character set M bytes, 0 <= M <= 255 L + 1 bytes if columnvalues require 0 255 bytes, L + 2 bytes if values may require more than 255 bytes L + 1 bytes, where L < 28 L + 2 bytes, where L < 216 L + 3 bytes, where L < 224 L + 4 bytes, where L < 232 1 or 2 bytes, depending on the number of enumeration values (65,535 values maximum) 1, 2, 3, 4, or 8 bytes, depending on the number of set members (64 members maximum)

BINARY(M) VARCHAR(M), VARBINARY(M)

TINYBLOB, TINYTEXT BLOB, TEXT MEDIUMBLOB, MEDIUMTEXT LONGBLOB, LONGTEXT ENUM('value1','value2',...) SET('value1','value2',...)

mysql> show tables; +----------------------+ | Tables_in_cse550 | +----------------------+ | emp | | employee | | product | | staff | | student | +----------------------+ 6 rows in set (0.00 sec) 8|Page

mysql> describe emp; +--------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+---------+-------+ | ename | char(20) | YES | | NULL | | | doj | date | YES | | NULL | | | dob | date | YES | | NULL | | | sub | char(10) | YES | | NULL | | | salary | int(5) | YES | | NULL | | | deptno | int(5) | YES | | NULL | | | mgr | mediumint(5) |YES | | NULL | | | empid | int(5) | NO | PRI | NULL | | +--------+--------------+------+-----+---------+-------+ 8 rows in set (0.00 sec) mysql> drop table product; Query OK, 0 rows affected (0.00 sec) mysql> show tables; +-------------------------+ | Tables_in_cse550 | +-------------------------+ | emp | | employee | | staff | | student | +-------------------------+ 9|Page

4 rows in set (0.00 sec)

mysql> select *from emp; +------+-------+------+------+-------+--------+------+-------+ | ename | doj | dob | sub |salary | deptno | mgr | empid | +-------+-----+------+------+--------+--------+------+-------+ | xyz | 0000-00-00 | 0000-00-00 | dbms |2000 |NULL | NULL|0| +-------+-------+------+------+--------+-------+-----+-------+ 1 row in set (0.01 sec)

Mysql COMMANDS Mysql Consisting of DDL,DML,DCL,TCL COMMANDS. 1.DDL: Data Definition Language (DDL) statements are used to define the database structure or schema. DDL Commands: Create, Alter, Drop, Rename, Truncate

CREATE - to create objects in the database ALTER - alters the structure of the database DROP - delete objects from the database TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed RENAME - rename an object

2. DML: Data Manipulation Language (DML) statements are used for managing data within schema objects and to manipulate data of a database objects. DML Commands: Insert, Update, Delete, Select

INSERT - insert data into a table 10 | P a g e

UPDATE - updates existing data within a table DELETE - deletes all records from a table, the space for the records remain SELECT - retrieve data from the a database 3.DCL: Data Control Language (DCL) statements is used to create roles, permissions, and referential integrity as well it is used to control access to database by securing it. To control the data of a database. DCL Commands: Grant, Revoke

GRANT - gives user's access privileges to database REVOKE -withdraw access privileges given with the GRANT command

4. TCL: Transaction Control (TCL) statements are used to manage the changes made by DML statements. It allows statements to be grouped together into logical transactions. TCL Commands: COMMIT - save work done SAVEPOINT - identify a point in a transaction to which you can later roll back ROLLBACK - restore database to original since the last COMMIT Commit, Rollback, Save point

Description:

1. DDL(Data Definition Language) Commands: CREATE, ALTER and


DROP.

11 | P a g e

CREATE: This command useful for creating creating table.


Syntax: create table [table name] (column1 datatype[size], column 2 datatype[size], column n datatype[size] ); Ex: mysql>create table student (s_rollno int(10) primary key,s_name varchar(10), gender varchar(5),dob date,addr1 varchar(10),addr2 varchar(10),city varchar(10), percentage float(4)); mysql> desc student; +------------+-------------+-------+------+---------+------+ | Field | Type | Null | Key | Default |Extra | +------------+-------------+-------+------+---------+------+ | s_rollno | int(10) | YES | | NULL | | | s_name | varchar(10) | YES | | NULL | | | gender | varchar(5) | YES | | NULL | | | dob | date | YES | | NULL | | | addr1 | varchar(10) | YES | | NULL | | | addr2 | varchar(10) | YES | | NULL | | | city | varchar(10) | YES | | NULL | | | percentage | float | YES | | NULL | | +------------+-------------+------+-----+---------+--------+ 8 rows in set (0.05 sec)

mysql> select s_rollno,s_name from student; 12 | P a g e

Empty set (0.04 sec) mysql> select *from student; Empty set (0.00 sec)

Create table by using Constraints: Constraints are two types:

1. Table Level Constraints. 2. Column Level Constraints.

1.NOT NULL: a) Not null constraint at column level. Syntax: <col><datatype>(size)not null mysql> create table emp(e_id varchar(5) NOT NULL,e_name varchar(10), e_design varchar(10),dept varchar(10),mgr varchar(10),salary int(10)); Query OK, 0 rows affected (0.05 sec)

2.UNIQUE : Unique constraint at column level. Syntax: <col><datatype>(size)unique; Ex: mysql> create table depositor(customer_name varchar(10),acc_no int(15) UNIQUE, brach_name varchar(10));

13 | P a g e

Query OK, 0 rows affected (0.10 sec)

Unique constraint at table level: Syntax: Create table tablename(col=format,col=format,unique(<col1>,<col2>); Ex: mysql> create table depositor1(customer_name varchar(10),acc_no int(15), brach_name varchar(10),UNIQUE(acc_no)); Query OK, 0 rows affected (0.10 sec)

3.PRIMARY KEY: Primary key constraint at column level Syntax: <col><datatype>(size)primary key; Ex: mysql> create table customer(customer_id int(5) PRIMARY KEY, customer_name varchar(10),customer_street varchar(10), brach_name varchar(10)); Query OK, 0 rows affected (0.32 sec)

Primary key constraint at table level. Syntax: Create table tablename(col=format,col=format primary key(col1>,<col2>);

Ex: 14 | P a g e

mysql> create table customer1(customer_id int(5),customer_name varchar(10),customer_street varchar(10), brach_name varchar(10),PRIMARY KEY(customer_id)); Query OK, 0 rows affected (0.32 sec)

4. CHECK: Check constraint constraint at column level. Syntax: <col><datatype>(size) check(<logical expression>)

Ex: mysql> create table loan(loan_no varchar(10),customer_name varchar(10), balance int(10) CHECK(balance>1000)); Query OK, 0 rows affected (0.04 sec)

Check constraint constraint at table level.

Syntax: check(<logical expression>) Ex: mysql> create table loan1(loan_no varchar(10),customer_name varchar(10), balance int(10), CHECK(balance>1000)); Query OK, 0 rows affected (0.04 sec) 5.FOREIGN KEY: Foreign key constraint at column level.

Syntax: 15 | P a g e

<col><datatype>(size>) references <tablename>[<col>];

InnoDB supports foreign key constraints. The syntax for a foreign key constraint definition in InnoDB looks like this:

[CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,) REFERENCES tbl_name (index_col_name,) [ON DELETE reference_option] [ON UPDATE reference_option]

mysql> desc student; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | s_rollno | int(10) | NO | PRI | NULL | | | s_name | varchar(10) | YES | | NULL | | | gender | varchar(5) | YES | | NULL | | | dob | date | YES | | NULL | | | addr1 | varchar(10) | YES | | NULL | | | addr2 | varchar(10) | YES | | NULL | | | city | varchar(10) | YES | | NULL | | | percentage | float | YES | | NULL | | +------------+-------------+------+-----+---------+-------+ 8 rows in set (0.00 sec)

16 | P a g e

Foreign key constraint at table level

Syntax: foreign key(<col>[,<col>]) references <tablename>[(<col>,<col>)

Ex: Mysql>create table customer(cno int primary key,cname varchar(10) not null,city varchar(15) not null); Query OK, 0 rows affected (0.10 sec)

Mysql>create table order1(ono int primary key,odate date not null,cno int not null,oamt int not null,foreign key(cno) references customer(cno) on delete cascade); Query OK, 0 rows affected (0.10 sec)

Mysql>create table item(ino int primary key,uprice int not null); Query OK, 0 rows affected (0.10 sec)

Mysql>create table oitem(ono int,ino int,qty int check(qty>0),primary key(ono,ino),foreign key(ono) references order1(ono) on delete cascade, foreign key(ino) references item(ino) on delete set null); Query OK, 0 rows affected (0.10 sec)

Mysql>create table warehouse(wno int primary key,city varchar(15) not null); Query OK, 0 rows affected (0.10 sec)

17 | P a g e

Mysql>create table shipment(ono int,wno int,sdate date not null,primary key(ono,wno),foreign key(ono) references order1(ono) on delete cascade, foreign key(wno) references warehouse(wno) on delete cascade); Query OK, 0 rows affected (0.10 sec)

customer Mysql>insert into customer values(1,'abc','bangalore'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into customer values(2,'cde','mysore'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into customer values(3,'def','chennai'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into customer values(4,'efg','mumbai'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into customer values(5,'adf','kolkata'); Query OK, 1 row affected (0.00 sec)

order1 Mysql>insert into order1 values(1,'1-jan-2006',1,20000); Query OK, 1 row affected (0.00 sec)

18 | P a g e

Mysql>insert into order1 values(2,'26-mar-2006',2,10000); Query OK, 1 row affected (0.00 sec)

Mysql>insert into order1 values(3,'12-jun-2006',1,5000); Query OK, 1 row affected (0.00 sec)

Mysql>insert into order1 values(4,'15-sep-2006',3,9000); Query OK, 1 row affected (0.00 sec)

Mysql>insert into order1 values(5,'5-jan-2007',4,2500); Query OK, 1 row affected (0.00 sec)

Mysql>insert into order1 values(6,'10-jan-2007',4,2400); Query OK, 1 row affected (0.00 sec)

Mysql>insert into order1 values(7,'3-mar-2007',5,3500); Query OK, 1 row affected (0.00 sec)

item Mysql>insert into item values(1,500); Query OK, 1 row affected (0.00 sec)

Mysql>insert into item values(2,300);

19 | P a g e

Query OK, 1 row affected (0.00 sec)

Mysql>insert into item values(3,2500); Query OK, 1 row affected (0.00 sec)

Mysql>insert into item values(4,800); Query OK, 1 row affected (0.00 sec)

Mysql>insert into item values(5,700); Query OK, 1 row affected (0.00 sec)

oitem Mysql>insert into oitem values(1,1,40); Query OK, 1 row affected (0.00 sec)

Mysql>insert into oitem values(2,1,20); Query OK, 1 row affected (0.00 sec)

Mysql>insert into oitem values(3,3,2); Query OK, 1 row affected (0.00 sec)

Mysql>insert into oitem values(5,3,1); Query OK, 1 row affected (0.00 sec)

20 | P a g e

Mysql>insert into oitem values(4,2,30); Query OK, 1 row affected (0.00 sec)

Mysql>insert into oitem values(6,4,3); Query OK, 1 row affected (0.00 sec)

Mysql>insert into oitem values(7,5,5); Query OK, 1 row affected (0.00 sec)

warehouse Mysql>insert into warehouse values(100,'bangalore'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into warehouse values(101,'chennai'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into warehouse values(102,'mumbai'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into warehouse values(103,'kolkata'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into warehouse values(104,'mysore'); Query OK, 1 row affected (0.00 sec)

21 | P a g e

shipment Mysql>insert into shipment values(1,100,'3-jan-2006'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into shipment values(2,100,'28-mar-2006'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into shipment values(3,101,'13-jun-2006'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into shipment values(4,102,'18-sep-2006'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into shipment values(5,103,'11-jan-2007'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into shipment values(6,104,'13-jan-2007'); Query OK, 1 row affected (0.00 sec)

Mysql>insert into shipment values(7,103,'3-mar-2007'); Query OK, 1 row affected (0.00 sec)

22 | P a g e

Mysql>select cname as custname,count(ono) as no_of_orders,avg(oamt) as avg_ord_amt from customer c,order1 o where c.ono=o.ono group by c.cno,cname;

Mysql>select ono from order1 o where not exist ((select wno from warehouse where city='bangalore') minus (select wno from shipment s where s.ono=o.ono)) and exists (select wno from warehouse where city='bangalore');

Mysql>delete from item where ino=5;

2. Modifying the structure of tables. a)add new columns Syntax:: Alter table <tablename> add (<new col><datatype(size),<new col>datatype(size)); Ex:: mysql> alter table student add column s_email varchar(20); Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table emp add dob date; Query OK, 6 rows affected (0.12 sec) Records: 6 Duplicates: 0 Warnings: 0

23 | P a g e

mysql> select *from emp; +------+---------+---------+------+---------+--------+-------+ | e_id | e_name | e_design | dept | mgr | salary | dob | +-------+---------+--------+------+---------+-------+--------+ | E1000 | Balaram | asst.prof | ECE | 1010 | 15000 | NULL | | E1001 | Sri Hari | asst.prof | ECE | 1020 | 13000 | NULL | | E1002 | Sitaram | asst.prof | EEE | 1025 | 12500 | NULL | | E1002 | Nagaraja | asst.prof | EEE | 1035 | 10500 | NULL | | E1002 | Nagarjuna| asso.prof | CSE | 1050 | 25000 | NULL | | | Nagababu | asso.prof | CSE | 1065 | 28000 | NULL | +-------+----------+-----------+------+------+--------+------+ 6 rows in set (0.00 sec) mysql> alter table emp add dob date after mgr; Query OK, 6 rows affected (0.04 sec) Records: 6 Duplicates: 0 Warnings: 0

mysql> select *from emp; +-------+----------+-----------+------+-------+------+--------+ | e_id |e_name | e_design | dept | mgr | dob | salary | +-------+----------+-----------+------+-------+--------+------+ | E1000 |Balaram | asst.prof | ECE | 1010 | NULL | 15000 | | E1001 |Sri Hari | asst.prof | ECE | 1020 | NULL | 13000 | | E1002 |Sitaram | asst.prof | EEE | 1025 | NULL | 12500 | | E1002 |Nagaraja | asst.prof | EEE | 1035 | NULL | 10500 |

24 | P a g e

| E1002 | Nagarjuna| asso.prof | CSE | 1050 | NULL | 25000 | | | Nagababu | asso.prof | CSE | 1065 | NULL | 28000 | +-------+----------+-----------+------+------+-------+--------+ 6 rows in set (0.00 sec)

3. Dropping a column from a table.

Syntax: Alter table <tablename> drop column <col>;

Ex: mysql> alter table student drop column addr2; Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0

mysql> desc student; +---------+-------------+-----+------+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+-----+------+---------+-------+ | s_rollno| int(10) | NO | PRI | NULL | | | s_name | varchar(10) | YES | | NULL | | | gender | varchar(5) | YES | | NULL | |

25 | P a g e

| dob | date | YES | | NULL | | | addr1 | varchar(10) | YES | | NULL | | | city | varchar(10) | YES | | NULL | | | percentage | float | YES | | NULL | | +--------+--------------+-----+------+---------+-------+ 7 rows in set (0.00 sec)

mysql> alter table emp drop dob; Query OK, 6 rows affected (0.07 sec) Records: 6 Duplicates: 0 Warnings: 0

mysql> select *from emp; +-------+----------+----------+------+----+------+ | e_id |e_name |e_design | dept | mgr |salary| +-------+----------+----------+------+----+------+ | E1000 | Balaram |asst.prof | ECE |1010 |15000 | | E1001 | Sri Hari |asst.prof | ECE |1020 |13000 | | E1002 | Sitaram |asst.prof | EEE |1025 |12500 | | E1002 | Nagaraja |asst.prof | EEE |1035 |10500 | | E1002 | Nagarjuna|asso.prof | CSE |1050 |25000 | | | Nagababu |asso.prof | CSE |1065 |28000 | +-------+----------+-------------+-------+-------+ 6 rows in set (0.00 sec)

26 | P a g e

4. Modifying existing columns.

Syntax: Alter table <tablename> modify(<col><newdatatype>(<newsize>));

Ex: alter table emp modify(ename varchar2(15)); 5. Renaming the tables

Syntax: Rename <oldtable> to <new table>;

Ex: rename emp to emp1;

6. truncating the tables.

Syntax: Truncate table <tablename>;

Ex:: trunc table emp1;

27 | P a g e

7. Destroying tables.

Syntax: Drop table <tablename>;

Ex: drop table emp;

2.DML: Data Manipulation Language (DML) DML Commands: 1. Insert: Inserting Data into Tables: - once a table is created the most natural thing to do is load this table with data to be manipulated later. Insert, Update, Delete, Select

Syntax 1: insert into <tablename> values(<val 1>,<val 2>.,<val n>);

mysql> insert into emp values('E1000','Balaram','asst.prof','ECE',1010,15000); Query OK, 1 row affected (0.00 sec)

mysql> insert into emp values('E1001','Sri Hari','asst.prof','ECE',1020,13000); Query OK, 1 row affected (0.00 sec)

28 | P a g e

mysql> insert into emp values('E1002','Sitaram','asst.prof','EEE',1025,12500); Query OK, 1 row affected (0.00 sec)

mysql> insert into emp values('E1002','Nagaraja','asst.prof','EEE',1035,10500); Query OK, 1 row affected (0.00 sec)

mysql> insert into emp values('Nagababu','asso.prof','CSE',1065,28000); ERROR 1136 (21S01): Column count doesn't match value count at row 1 mysql> insert into emp values(,'Nagababu','asso.prof','CSE', 1065,28000); ERROR 1064 (42000): You have an error in your MYSQL syntax; check the manual that corresponds to your Mysql server version for the right syntax to use near ''Nagababu','asso.prof', 'CSE',1065, 28000)' atline 1

mysql> insert into emp values('E1002','Nagarjuna','asso.prof','CSE',1050,25000); Query OK, 1 row affected (0.00 sec)

mysql> select *from emp; +------+-----------+--------+-------+-----+--------+ | e_id | e_name | e_design | dept| mgr |salary | +------+-----------+-----------+-----+------+------+ | E1000 | Balaram | asst.prof | ECE |1010 | 15000 | | E1001 | Sri Hari | asst.prof | ECE |1020 | 13000 | | E1002 | Sitaram | asst.prof | EEE |1025 | 12500 | 29 | P a g e

| E1002 | Nagaraja | asst.prof | EEE |1035 | 10500 | | E1002 | Nagarjuna| asso.prof | CSE |1050 | 25000 | +-------+----------+-----------+-----+-----+-------+ 5 rows in set (0.02 sec) mysql> desc emp; +---------+------------+-----+----+-------+-----+ | Field | Type | Null| Key|Default|Extra| +---------+------------+-----+----+-------+-----+ | e_id | varchar(5) | NO | | NULL | | | e_name | varchar(10)| YES | | NULL | | | e_design| varchar(10)| YES | | NULL | | | dept | varchar(10)| YES | | NULL | | | mgr | varchar(10)| YES | | NULL | | | salary | int(10) | YES | | NULL | | +---------+------------+-----+----+------+------+ 6 rows in set (0.00 sec)

mysql> select *from emp; +------+-----------+-----------+-----+------+-------+ | e_id | e_name | e_design | dept| mgr |salary | +------+-----------+-----------+-----+------+-------+ | E1000 | Balaram | asst.prof | ECE | 1010 | 15000 | | E1001 | Sri Hari | asst.prof | ECE | 1020 | 13000 | | E1002 | Sitaram | asst.prof | EEE | 1025 | 12500 |

30 | P a g e

| E1002 | Nagaraja | asst.prof | EEE | 1035 | 10500 | | E1002 | Nagarjuna| asso.prof | CSE | 1050 | 25000 | | | Nagababu | asso.prof | CSE | 1065 | 28000 | +-------+----------+-----------+-----+------+-------+ 6 rows in set (0.02 sec)

Syntax 2: insert into <tablename> (<col1>,<col2>..<col n>) values(<val 1>,<val 2>.<val n>);

2.Update: Updating the contents of a table. a) Updating all rows Syntax: Update <tablename> set <col>=<exp>,<col>=<exp>;

Ex:

b) Updating seleted records. Syntax: Update <tablename> set <col>=<exp>,<col>=<exp> where <condition>;

Ex: Delete operations. a) Remove all rows Syntax: 31 | P a g e

delete from <tablename>; Ex: b) Removal of a specified row/s Syntax: delete from <tablename> where <condition>; Ex: Using AUTO_INCREMENT The AUTO_INCREMENT attribute can be used to generate a unique identity for new rows: MYSQL>CREATE TABLE animals (id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL,PRIMARY KEY (id) );

MYSQL>INSERT INTO animals (name) VALUES ('dog'),('cat'),('penguin'), ('lax'),('whale'),('ostrich');

MYSQL>SELECT * FROM animals; +----+---------+ | id | name | +----+---------+ | 1 | dog | | 2 | cat | | 3 | penguin | | 4 | lax | | 5 | whale | | 6 | ostrich | +----+---------+ 32 | P a g e

6 rows in set (0.02 sec) You can retrieve the most recent AUTO_INCREMENT value with the LAST_INSERT_ID() SQL function or the mysql_insert_id() C API function. These functions are connection-specific, so their return values are not affected by another connection which is also performing inserts. Note For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually return the AUTO_INCREMENT key from the first of the inserted rows. This allows multiple-row inserts to be reproduced correctly on other servers in a replication setup. For MyISAM and BDB tables you can specify AUTO_INCREMENT on a secondary column in a multiple-column index. In this case, the generated value for the AUTO_INCREMENT column is calculated as MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. This is useful when you want to put data into ordered groups. MYSQL>CREATE TABLE animals (grp ENUM('fish','mammal','bird') NOT NULL,id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (grp,id));

MYSQL>INSERT INTO animals (grp,name) VALUES ('mammal', 'dog'), ('mammal','cat'),('bird','penguin'),('fish','lax'),('mammal','whale'), ('bird','ostrich');

MYSQL>SELECT * FROM animals ORDER BY grp,id; +--------+----+--------+ | grp | id | name | +--------+----+--------+ | fish | 1 | lax | | mammal | 1 | dog | | mammal | 2 | cat | | mammal | 3 | whale | | bird | 1 | penguin|

33 | P a g e

| bird | 2 |ostrich | +-------+----+---------+ 6 rows in set (0.02 sec)

Note that in this case (when the AUTO_INCREMENT column is part of a multiple-column index), AUTO_INCREMENT values are reused if you delete the row with the biggest AUTO_INCREMENT value in any group. This happens even for MyISAM tables, for which AUTO_INCREMENT values normally are not reused. If the AUTO_INCREMENT column is part of multiple indexes, MySQL will generate sequence values using the index that begins with the AUTO_INCREMENT column, if there is one. For example, if the animals table contained indexes PRIMARY KEY (grp, id) and INDEX (id), MySQL would ignore the PRIMARY KEY for generating sequence values. As a result, the table would contain a single sequence, not a sequence per grp value. To start with an AUTO_INCREMENT value other than 1, you can set that value with CREATE TABLE or ALTER TABLE, like this:

mysql> ALTER TABLE tbl AUTO_INCREMENT = 100; More information about AUTO_INCREMENT is available here:

How to assign the AUTO_INCREMENT attribute to a column. How AUTO_INCREMENT behaves depending on the SQL mode. Find the row that contains the most recent AUTO_INCREMENT value. Set the AUTO_INCREMENT value to be used. AUTO_INCREMENT and replication. Server-system variables related to AUTO_INCREMENT (auto_increment_increment and auto_increment_offset) that can be used for replication:.

34 | P a g e

WEEK 2 E-R DIAGRAMS


1. MOVIE THEATER MANAGEMENT:

2. HOSPITAL MANAGEMENT:

35 | P a g e

3. EMPLOYEE:

4. BOOK STOREGE MANAGEMENT:

36 | P a g e

5. VEHICLE REGISTRATION:

6. BANK MANAGEMENT SYSTEM:

37 | P a g e

7. PROJECT DEVELOPMENT SYSTEM:

38 | P a g e

WEEK 3

Sailors (sid: integer, sname: string, rating: integer, age: real) Boats (bid: integer, bname:string, color:string) Reserves (sid: integer, bid: integer, day: date) SAILORS TABLE

BOATS TABLE

RESERVES TABLE

39 | P a g e

QUERIES:

1. Find the names and sids of sailors who have reserved a red or a
Green boat? (UNION) 2. Find the names and sids of sailors who have reserved a red and a green boat? (INTERSECT) 3. Find all sids of sailors who have a rating of 10 or reserved boat 104 ?(UNION) 4. Find the names of sailors who have reserved boat 103 ? (IN) 5. Find the names of sailors who have reserved a red boat? (IN) 6. Find the names of sailors who have not reserved a red boat? (NOT IN) 7. Find sailors whose rating is better than some sailor called Horatio? (ANY) 8. Find the sailors with the highest rating? (ALL) 9. Find the names of sailors who have reserved both a red and a green boat? (IN) 10. Find the names of sailors who have reserved boat no 103? (EXISTS) 11. Find the names of sailors who have reserved all boats? (NOT EXISTS) QUERIE 1: Find the names and sids of sailors who have reserved a red or a green boat?

40 | P a g e

MYSQL> SELECT S.sname, S.sid FROM sailors S, reserves R, boats B WHERE S.sid=R.sid AND R.bid=B.bid AND B.color='red' UNION SELECT S1.sname, S1.sid FROM sailors S1, reserves R1, boats B1 WHERE S1.sid=R1.sid AND R1.bid=B1.bid AND B1.color='green'; SNAME SID -------------------- ---------Dustin 22 Horatio 64 Horatio 74 Lubber 31

QUERIE 2: Find the names and sids of sailors who have reserved a red and a green boat? MYSQL> SELECT S.sname, S.sid FROM sailors S, reserves R, boats B WHERE S.sid=R.sid AND R.bid=B.bid AND B.color='red' INTERSECT SELECT S1.sname, S1.sid FROM sailors S1, reserves R1, boats B1 WHERE S1.sid=R1.sid AND R1.bid=B1.bid AND B1.color='green';

SNAME SID ------------------Dustin 22 Lubber 31

41 | P a g e

QUERIE 3: Find all sids of sailors who have a rating of 10 or reserved boat 104?

MYSQL> SELECT S.sid FROM sailors S WHERE S.rating=10

UNION
SELECT R.sid FROM reserves R WHERE R.bid=104;

SID ---------22 31 58 71

QUERIE 4: Find the names of sailors who have reserved boat 103 ? (IN)

MYSQL> SELECT S.sname FROM sailors S WHERE S.sid IN (SELECT R.sid FROM reserves R WHERE R.bid=103);

SNAME -------------------Dustin Lubber Horatio

42 | P a g e

QUERIE 5: Find the names of sailors who have reserved a red boat? mysql> SELECT S.sname FROM sailors S WHERE S.sid IN (SELECT R.sid FROM reserves R WHERE R.bid IN (SELECT B.bid FROM boats B WHERE B.color='red')); SNAME -------------------Dustin Lubber Horatio

QUERIE 6: Find the names of sailors who have not reserved a red boat?

MYSQL> SELECT S.sname FROM sailors S WHERE S.sid NOT IN (SELECT R.sid FROM reserves R WHERE R.bid IN (SELECT B.bid FROM boats B WHERE B.color='red')); SNAME -------------------Brutus Andy Rusty Zorba Horatio Art BOB 7 rows selected.

43 | P a g e

QUERIE 7: Find sailors whose rating is better than some sailor called Horatio?

MYSQL> SELECT S.sid FROM sailors S WHERE S.rating > ANY (SELECT S1.rating FROM sailors S1 WHERE S1.sname='Horatio'); SID ---------58 71 74 31 32

QUERIE 8: Find the sailors with the highest rating?

mysql> SELECT S.sid FROM sailors S WHERE S.rating >= ALL (SELECT S1.rating FROM sailors S1); SID ---------58 71

QUERIE 9: Find the names of sailors who have reserved both a red and a green boat?

MYSQL> SELECT S.sname FROM sailors S, reserves R, boats B WHERE S.sid=R.sid AND R.bid=B.bid AND B.color='red' AND S.sid IN (SELECT 44 | P a g e

S1.sid FROM sailors S1, reserves R1, boats B1 WHERE S1.sid=R1.sid AND R1.bid=B1.bid AND B1.color='green'); SNAME -------------------Dustin Dustin Lubber Lubber

QUERIE 10: Find the names of sailors who have reserved boat no 103? MYSQL> SELECT S.sname FROM sailors S WHERE EXISTS (SELECT * FROM reserves R DBMS LAB MANUAL COMMON TO BTECH CSE-II AND IT WHERE R.bid=103 AND R.sid=S.sid); SNAME -------------------Dustin Lubber Horatio QUERIE 11: Find the names of sailors who have reserved all boats? MYSQL> SELECT S.sname FROM sailors S WHERE NOT EXISTS (SELECT B.bid FROM boats B WHERE NOT EXISTS (SELECT R.bid FROM reserves R WHERE R.bid=B.bid AND R.sid=S.sid)); SNAME -------------------Dustin 45 | P a g e

1) Queries (along with subqueries) using ANY, ALL, IN, EXISTS, NOT EXISTS, UNIQUE, INTERSECT, Constraints.

Example: select the rollno and name of the student who secured 4th rank in the class

TABLE DEFINITIONS

MYSQL> CREATE TABLE Customer ( cust_no NUMBER(4) PRIMARY KEY, last_name VARCHAR2(20), first_name VARCJHAR2(20) NOT NULL, address1 VARCHAR2(20), address2 VARCHAR2(20), city VARCHAR2(3), state VARCHAR2(20), pin VARCHAR2(6), birth_date DATE, status VARCHAR2(1), CHECH (status IN (V, I, A)) );

Table created.

Insert the following data:

46 | P a g e

1 row created.
CUST NO LAST NAME FIRST NAME ADDRESS1 ADDRESS2CITY STATE BIRTH DATE PIN S T A T U S 1001 1002 UDUPI KUMAR RAJ RAJ RAJ FELIX RAJAN SHILPA RAKSHIT SHANTHI VILLA M-J-56 A1 TRADERS 12/4B BOSCO NEAR MALLIKA UDP ALTOBETIM PJM NEAR RLY STATION KNR POLICE QUARTERS MNG R.K PLAZA BNG KARNATAKA GOA KERALA KARNATAKA KARNATAKA 576101 1-AUG-70 403002 12-FEB-71 67001 9-JUN-71 574154 11-DEC-70 576201 1-JAN-71 UPENDRABAUG NEAR KALPANAUDPP KARNARATA 576101 12-DEC-62 A A V A A I A

1003 BAHADUR 1004 1005 1006 1007 SIMON KUTTY PAI JAIN

QUERIES

1. To list all the fields from the table Customer.


SEELCT * FROM Customer;

2. To list the first name, last name.


SELECT first_name, last_name FROM Customer; 47 | P a g e

3. To list the first name and last name of persons in Karnataka.


SELECT first_name, last_name FROM Customer WHERE state = KARNATAKA;

4. To list all the columns for invalid persons.


SELECT * FROM Customer WHERE status = I;

5. To list the names of active customers.


SELECT first_name, last_name FROM Customer WHERE status = A;

6. To list the name and address using concatenation.


SELECT first_name || || last_name, address1 || , || address2 || , || city || , || state || - || pin FROM Customer;

7. To select records where the pin code has not been entered.
SELECT * FROM Customer

48 | P a g e

WHERE pin IS NULL;

8. To select the single occurrence of any value from the table.


SELECT DISTINCT state FROM Customer;

9. To select rows of valid customers from Karnataka.


SELECT * FROM Customer WHERE state = KARNATAKA AND status = V;

10. To select rows of customers from Karnataka or Kerala.


SELECT * FROM Customer WHERE state = KARNATAKA OR state = KERALA;

11. To sort the customer data in the alphabetic order of state.


SELECT state, first_name, last_name, pin FROM Customer ORDER BY state;

12. To sort in the descending order.


49 | P a g e

SELECT state, first_name, last_name, pin FROM Customer ORDER BY state DESC;

13. To sort the customer data, state wise and within state by the last
name. SELECT state, first_name, last_name, pin FROM Customer ORDER BY state, last_name;

14. To retrieve records of Karnataka customers who are valid.


SELECT * FROM Customer WHERE UPPER(state) = KARNATAKA AND UPPER(status) = V;

15. To retrieve records of Karnataka/Kerala customers.


SELECT * FROM Customer WHERE UPPER(state) = KARNATAKA OR UPPER(state) = KERALA;

16. To retrieve records of Karnataka/Kerala customers who are active.


SELECT * FROM Customer 50 | P a g e

WHERE (UPPER(state) = KARNATAKA OR UPPER(state) = KERALA) AND UPPER(status) = A;

17. To retrieve records of Karnataka customers with pin code 576101.


SELECT * FROM Customer WHERE LOWER(state) = karnataka AND pin = 576101;

18. To retrieve rows where the state name begins with K and followed by
any other character. SELECT first_name, last_name, state FROM Customer WHERE state LIKE K%;

19. To retrieve rows where the first name contains the word RAJ embedded
in it. SELECT first_name, last_name, state FROM Customer WHERE first_name LIKE %RAJ%;

20. To retrieve rows where the address2 contains the word UDUPI or UDIPI
in which the 3rd character may be anything. SELECT first_name, last_name, state FROM Customer 51 | P a g e

WHERE address2 LIKE UD_PI;

21. To retrieve rows where the cust_no has data representing any value
between 1003 and 1005, both numbers included. SELECT * FROM Customer WHERE cust_no BETWEEN 1003 AND 1005;

22. To retrieve rows of persons born after 9-JAN-70 and before 1-AUG-96.
SELECT * FROM Customer WHERE birth_date BETWEEN 10-JAN-70 AND 31-JUL-96;

23. To retrieve rows where the city has data which is equal to UDP or
MNG or BNG or PJM or MAR. SELECT * FROM Customer WHERE city IN (UDP, MNG, BNG, PJM, MAR);

TABLE DEFINITIONS

MYSQL> CREATE TABLE Emp (emp_no NUMBER,emp_name VARCHAR(20), join_date DATE, join_basic NUMBER(7,2),PRIMARY KEY (emp_no));

Table created. 52 | P a g e

Insert the following data:

EMP NO 1001 1002 1003 1004 1005

EMP NAME Subhas bose Nadeem shah Charles babbage Shreyas kumar George boole

JOIN DATE 01-JUN-96 01-JUN-96 01-JUN-96 01-JUL-96 01-JUL-96

JOIN BASIC 3000 2500 3000 2500 2800

MYSQL> CREATE TABLE Salary (emp_no NUMBER,basic NUMBER(7, 2),commission NUMBER(7, 2),deduction NUMBER(7,2), salary_date DATE,FOREIGN KEY (emp_no) REFERENCES Emp); Table created. Insert the following data: EMP NO 1001 1002 1003 1004 1005 1001 1002 1003 1004 1005 BASIC 3000 2500 3000 2500 2800 3000 2500 3000 2500 2800 COMMISSION 200 120 500 200 100 200 120 500 200 100 DEDUCTION 250 200 290 300 250 250 200 290 300 150 SALARY DATE 30-JUN-96 30-JUN-96 30-JUN-96 30-JUN-96 30-JUN-96 31-JUL-96 31-JUL-96 31-JUL-96 31-JUL-96 31-JUL-96

53 | P a g e

QUERIES

1. To sum the salary of each employee.


SELECT emp_no, SUM(basic) FROM salary GROUP BY emp_no;

2. To sum the salary of each employee and sort it on the sum of basic.
SELECT emp_no, SUM(basic) FROM salary GROUP BY emp_no ORDER BY SUM(basic);

3. To sum the salary of each employee and sort it in descending order


on the sum of basic. SELECT emp_no, SUM(basic) FROM salary GROUP BY emp_no ORDER BY SUM(basic) DESC;

4. To sum the salary of each employee and sort it in descending order


on the sum of basic. Display name also SELECT s.emp_no, e.emp_name, SUM(s.basic) FROM salary s, emp e WHERE s.emp_no = e.emp_no GROUP BY s.emp_no, e.emp_no

54 | P a g e

ORDER BY SUM(s.basic) DESC;

5. To group the data by average salary of each employee.


SELECT s.emp_no, INITCAP(e.emp_name), AVG(s.basic) FROM salary s, emp e WHERE s.emp_no = e.emp_no GROUP BY s.emp_no, e.emp_no ORDER BY AVG(s.basic);

6. To group the basic by month.


SELECT TO_CHAR(salary_date, MONTH) MONTH, SUM(basic) TOTAL BASIC FROM salary GROUP BY TO_CHAR(salary_date, MONTH);

7. To group the data by average salary of each employee and display


where average basic is more than 2000.. SELECT s.emp_no, INITCAP(e.emp_name), AVG(s.basic) FROM salary s, emp e WHERE s.emp_no = e.emp_no GROUP BY s.emp_no, e.emp_no HAVING AVG(s.basic) >= 2000 ORDER BY AVG(s.basic);

55 | P a g e

SUBQUERIES

8. To list the employees who earn less than the average salary.
SELECT * FROM salary WHERE basic < (SELECT AVG(basic) FROM salary);

9. To list the employees whose deduction is 150.


SELECT * FROM salary WHERE emp_no IN (SELECT emp_no FROM salary WHERE deduction = 150);

10. To list the names of employees and salary details, whose basic is
less than the average salary. SELECT s.*, e.emp_name FROM salary s, emp e WHERE s.emp_no = e.emp_no AND s.basic < (SELECT AVG(basic) FROM salary);

56 | P a g e

2. Queries (along with subqueries) using ANY, ALL, IN, EXISTS, NOT
EXISTS, UNIQUE, INTERSECT, Constraints.

Example: select the rollno and name of the student who secured 4th rank in the class.

2. Queries using Aggregate functions (COUNT, SUM, AVG, MAX and MIN),
GROUP BY, HAVING and Creation and Dropping of Views.

2. Queries using Conversions, functions (to_char, to_num, and to_date),


string function (Conactenation, lpad, rpad, ltrim, rtrim, lower, upper, initcap, length, substr, and instr), date functions (sysdate, next_day, add_months, last_day, months_between, least, greatest, trunk, round, to_char, to_date).

TABLE DEFINITIONS

MYSQL> CREATE TABLE Emp ( emp_no NUMBER, emp_name VARCHAR(20), join_date DATE, join_basic NUMBER(7, 2), PRIMARY KEY (emp_no) );

Table created.

Insert the following data: 57 | P a g e

EMP NO 1001 1002 1003 1004 1005

EMP NAME Subhas bose Nadeem shah Charles babbage Shreyas kumar George boole

JOIN DATE 01-JUN-96 01-JUN-96 01-JUN-96 01-JUL-96 01-JUL-96

JOIN BASIC 3000 2500 3000 2500 2800

MYSQL> CREATE TABLE Salary (emp_noNUMBER,basicNUMBER(7, 2), commission NUMBER(7,2),deduction NUMBER(7,2),salary_date DATE,FOREIGN KEY (emp_no)REFERENCES Emp); Table created. Insert the following data:

EMP NO 1001 1002 1003 1004 1005 1001 1002 1003 1004 1005

BASIC 3000 2500 3000 2500 2800 3000 2500 3000 2500 2800

COMMISSION 200 120 500 200 100 200 120 500 200 100

DEDUCTION 250 200 290 300 250 250 200 290 300 150

SALARY DATE 30-JUN-96 30-JUN-96 30-JUN-96 30-JUN-96 30-JUN-96 31-JUL-96 31-JUL-96 31-JUL-96 31-JUL-96 31-JUL-96

58 | P a g e

QUERIES

11. To sum the salary of each employee.


SELECT emp_no, SUM(basic) FROM salary GROUP BY emp_no;

12. To sum the salary of each employee and sort it on the sum of basic.
SELECT emp_no, SUM(basic) FROM salary GROUP BY emp_no ORDER BY SUM(basic);

13. To sum the salary of each employee and sort it in descending order
on the sum of basic. SELECT emp_no, SUM(basic) FROM salary GROUP BY emp_no ORDER BY SUM(basic) DESC;

14. To sum the salary of each employee and sort it in descending order
on the sum of basic. SELECT s.emp_no, e.emp_name, SUM(s.basic) FROM salary s, emp e WHERE s.emp_no = e.emp_no 59 | P a g e

GROUP BY s.emp_no, e.emp_name ORDER BY SUM(s.basic) DESC;

15. To group the data by average salary of each employee.


SELECT s.emp_no, INITCAP(e.emp_name), AVG(s.basic) FROM salary s, emp e WHERE s.emp_no = e.emp_no GROUP BY s.emp_no, e.emp_no ORDER BY AVG(s.basic);

16. To group the basic by month.


SELECT TO_CHAR(salary_date, MONTH) MONTH, SUM(basic) TOTAL BASIC FROM salary GROUP BY TO_CHAR(salary_date, MONTH);

17. To group the data by average salary of each employee and display
where average basic is more than 2000.. SELECT s.emp_no, INITCAP(e.emp_name), AVG(s.basic) FROM salary s, emp e WHERE s.emp_no = e.emp_no GROUP BY s.emp_no, e.emp_no HAVING AVG(s.basic) >= 2000 ORDER BY AVG(s.basic);

60 | P a g e

SUBQUERIES

18. To list the employees who earn less than the average salary.
SELECT * FROM salary WHERE basic < (SELECT AVG(basic) FROM salary);

19. To list the employees whose deduction is 150.


SELECT * FROM salary WHERE emp_no IN (SELECT emp_no FROM salary WHERE deduction = 150);

20. To list the names of employees and salary details, whose basic is
less than the average salary. SELECT s.*, e.emp_name FROM salary s, emp e WHERE s.emp_no = e.emp_no AND s.basic < (SELECT AVG(basic) FROM salary);

2. Queries (along with subqueries) using ANY, ALL, IN, EXISTS, NOT
EXISTS, UNIQUE, INTERSECT, Constraints. Example: select the rollno and name of the student who secured 4th rank in the class.

61 | P a g e

2. Queries using Aggregate functions (COUNT, SUM, AVG, MAX and MIN),
GROUP BY, HAVING and Creation and Dropping of Views.

2. Queries using Conversions, functions (to_char, to_num, and


to_date), string function (Conactenation, lpad, rpad, ltrim, rtrim, lower, upper, initcap, length, substr, and instr), date functions (sysdate, next_day, add_months, last_day, months_between, least, greatest, trunk, round, to_char, to_date).

TABLE DEFINITIONS

Branch Schema <branch-name, branch-city, assets> Customer Schema <customer-name, customer-street, customer-city> Loan Schema <loan-number, branch-name, amount> Borrower Schema <customer-name, loan-number> Account Scheme <account-number, branch-name, balance> Depositor Scheme <customer-name, account-number> BRANCH TABLE Branch Name Brighton Downtown Mianus North Town Perryridge Pownal Redwood Round Hill Branch City Brooklyn Brooklyn Horseneck Rye Horseneck Bennington Palo Alto Horseneck Assets 7100000 9000000 400000 3700000 1700000 300000 2100000 800000

62 | P a g e

CUSTOMER TABLE Customer Name Adams Brooks Curry Glenn Green Hayes Johnson Jones Lindsay Smith Turner Williams Customer Street Spring Senator North Sand Hill Walnut Main Alma Main Park North Putnam Nassau Customer City Pittsfield Brooklyn Rye Woodside Stamford Harrison Palo Alto Harrison Pittsfield Rye Stamford Princeton

LOAN TABLE Loan Number L-11 L-14 L-15 L-16 L-17 L-23 L-93 Branch Name Round Hill Downtown Perryridge Perryridge Downtown Redwood Mianus Amount 900 1500 1500 1300 1000 2000 500

63 | P a g e

BORROWER TABLE

Customer Name Adams Curry Hayes Jackson Jones Smith Smith Williams

Loan Number l-16 L-93 L-15 L-14 L-17 L-11 L-23 L-17

ACCOUNT TABLE

Account Number A-101 A-102 A-201 A-215 A-217 A-222 A-305

Branch Name Downtown Perryridge Brighton Mianus Brighton Redwood Round Hill

Balance 500 400 900 700 750 700 350

64 | P a g e

DEPOSITOR TABLE

Customer Name Hayes Johnson Johnson Jones Lindsay Smith Turner

Account Number A102 A-101 A-201 A-217 A-222 A-215 A-305

QUERIES 1) To list all the fields from the table Customer. SELECT branch_name FROM Loan; 2) To list rows after eliminating duplicates. SELECT distinct branch_name FROM Loan; 3) To explicitly list rows, including duplicates. SELECT all branch_name FROM Loan; 4) To list fields after applying arithmetic operations. SELECT loan_number, branch_name, amount *100 FROM Loan;

65 | P a g e

5) Find all loan numbers for loans made at the Perryridge branch with loan amounts greater than Rs1200. SELECT loan_number FROM Loan WHERE branch_name = Perryridge AND amount > 1200; 6) Find all loan numbers for loans with loan amounts between Rs90,000 and Rs100,000. SELECT loan_number FROM Loan WHERE amount BETWEEN 90000 AND 100000; Or SELECT loan_number FROM Loan WHERE amount <= 100000 AND amount >= 90000; 7) Find all loan numbers for loans with loan amounts not between Rs90,000 and Rs100,000. SELECT loan_number FROM Loan WHERE amount NOT BETWEEN 90000 AND 100000; 8) For all customers who have a loan from the bank, find their names, loan numbers and loan amounts. SELECT customer_name, Borrower.loan_number, amount FROM Borrower, Loan WHERE Borrower.loan_number = Loan.loan_number;

66 | P a g e

Or SELECT customer_name, Borrower.loan_number AS loan_id, amount FROM Borrower, Loan WHERE Borrower.loan_number = Loan.loan_number; 9) Find the customer names, loan numbers and loan amounts for all loans at the Perryridge branch. SELECT customer_name, Borrower.loan_number, amount FROM Borrower, Loan WHERE Borrower.loan_number = Loan.loan_number AND branch_name = Perryridge; Or SELECT customer_name, T.loan_number, S.amount FROM Borrower AS T, Loan AS S WHERE T.loan_number = S.loan_number AND branch_name = Perryridge; 10) Find the names of all branches that have assets greater than atleast one branch located in Brooklyn. SELECT DISTINCT T.branch_name FROM Branch as T, Branch as S WHERE T.assets > S.assets AND S.branch_city = Brooklyn; 11) Find the names of all customers whose street address includes the substring Main. SELECT customer_name FROM Customer WHERE customer_street LIKE %Main%;

67 | P a g e

12) To list in alphabetic order all customers who have a loan at the Perryridge branch. SELECT DISTINCT customer_name FROM Borrower B, Loan L WHERE B.loan_number = L.loan_number AND branch_name = Perryridge ORDER BY customer_name;

13) To list the entire loan info in descending order of amont. SELECT * FROM Loan ORDER BY amount DESC, loan_number ASC; 14) To find all customers having a loan, an account or both at the bank, without duplicates. (SELECT customer_name FROM Depositor) UNION (SELECT customer_name FROM Borrower); 15) To find all customers having a loan, an account or both at the bank, with duplicates. (SELECT customer_name FROM Depositor) UNION ALL (SELECT customer_name FROM Borrower); 68 | P a g e

16) To find all customers having both a loan and an account at the bank, without duplicates. (SELECT customer_name FROM Depositor) INTERSECT (SELECT customer_name FROM Borrower); 17) To find all customers having a loan, an account or both at the bank, with duplicates. (SELECT customer_name FROM Depositor) INTERSECT ALL (SELECT customer_name FROM Borrower); 18) To find all customers who have an account but no loan at the bank, without duplicates. (SELECT DISTINCT customer_name FROM Depositor) EXCEPT (SELECT customer_name FROM Borrower); 19) To find all customers who have an account but no loan at the bank, with duplicates. (SELECT DISTINCT customer_name FROM Depositor) EXCEPT ALL (SELECT customer_name FROM Borrower); 69 | P a g e

20) Find the average account balance at the Perryridge branch. SELECT branch_name, AVG(balance) FROM Account WHERE branch_name = Perryridge; 21) Find the average account balance at the each branch. SELECT AVG(balance) FROM Account GROUP BY branch_name; 22) Find the number of depositors for each branch . SELECT branch_name, COUNT(DISTINCT customer_name) FROM Depositor D, Account A WHERE D.account_number = A.account_number GROUP BY branch_name; 23) Find the number of depositors for each branch where average account balance is more than Rs 1200. SELECT branch_name, COUNT(DISTINCT customer_name) FROM Depositor D, Account A WHERE D.account_number = A.account_number GROUP BY branch_name HAVING AVG(balance) > 1200; 24) Find the average balance for all accounts. SELECT AVG(balance) FROM Account;

70 | P a g e

25) Find the number of tuples in the customer relation. SELECT COUNT(*) FROM Customer; 26) Find the average balance for each customer who lives in Harrision and has at least three accounts. SELECT D.customer_name, AVG(balance) FROM Depositor D, Account A, Customer C WHERE D.account_number = A.account_number AND D.customer_name = C.customer_name AND C.customer_city = Harrison GROUP BY D.customer_name HAVING COUNT(DISTINCT D.account_number) >= 3;

27) Find all the loan number that appear in loan relation with null amount values. SELECT loan_number FROM Loan WHERE amount IS NULL;

28) Find all customers who have both a loan and an account at the bank. SELECT customer_name FROM Borrower WHERE customer_street IN (SELECT customer_name FROM Depositor);

71 | P a g e

29) Find all customers who have both an account and a loan at the Perryridge branch. SELECT DISTINCT B.customer_name FROM Borrower B, Loan L WHERE B.loan_number L.loan_number AND branch_name = Perryridge AND (branch_name, customer_name) IN (SELECT branch_name, customer_name FROM Depositor D, Account A WHERE D.account_number = A.account_number); or SELECT customer_name FROM Borrower B WHERE EXISTS (SELECT * FROM Depositor D WHERE D.customer_name = B.customer_name);

30) Find all customers who do not have a loan at the bank, but do not have an account the bank. SELECT DISTINCT customer_name FROM Borrower WHERE customer_name NOT IN (SELECT customer_name FROM Depositor);

72 | P a g e

31) Find the names of customers who do have a loan at the bank, and whose names are neither Smith nor Jones. SELECT DISTINCT customer_name FROM Borrower WHERE customer_name NOT IN (Smith, Jones);

32) Find the names of all branches that have assets greater than those of at least one branch located in Brooklyn. SELECT DISTINCT T.branch_name FROM Branch AS T, Branch AS S WHERE T.assets > S.assets AND S.branch_city = Brooklyn; 33) Find the names of all branches that have assets greater than that of each branch located in Brooklyn. SELECT branch_name FROM Account GROUP BY branch_name HAVING AVG(balance) >= ALL (SELECT AVG(balance) FROM Account GROUP BY branch_name); 34) Find all customers who have an account at all the branches located in Brooklyn. SELECT DISTINCT S.customer_name FROM Depositor AS D WHERE NOT EXISTS ((SELECT branch_name FROM Branch WHERE branch_city = Brroklyn) 73 | P a g e

EXCEPT (SELECT R.branch_name FROM Depositor AS T, Account AS R WHERE T.account_number = R.account_number AND D.customer_name = t.customer_name));

35) Find all customers who have at most one account at the Perryridge branch.

SELECT T.customer_name FROM Depositor AS T WHERE UNIQUE (SELECT R.customer_name FROM Depositor AS R, Account AS A WHERE T.customer_name = R.customer_name AND R.account_number = A.account_number AND A.branch_name = Perryridge);

36) Find all customers who have at least two accounts at the Perryridge branch.

SELECT DISTINCT T.customer_name FROM Depositor AS T WHERE NOT UNIQUE (SELECT R.customer_name FROM Depositor AS R, Account AS A

74 | P a g e

WHERE T.customer_name = R.customer_name AND R.account_number = A.account_number AND A.branch_name = Perryridge);

37) Find the average account balance of those branches where the average account balance is greater than 1200.

SELECT branch_name, avg_balance FROM (SELECT branch_name, AVG(balance) FROM Account GROUP BY branch_name) AS Branch_avg(branch_name, avg_balance) WHERE avg_balance > 1200;

38) Find the maximum across all branches of the total balance at each branch.

SELECT MAX(tot_balance) FROM (SELECT branch_name, SUM(balance) FROM Account GROUP BY branch_name) AS Branch_total(branch_name, tot_balance);

75 | P a g e

39) Find the all customers who have an account but no loan at the bank.

SELECT d-CN FROM (Depositor LEFT OUTER JOIN Borrower ON Depositor.customer_name = Borrower.customer_name) AS db1(d-CN, account_number, b-CN, loan_number) WHERE b-CN is null;

40) Find the all customers who have either an account or a loan (but not both) at the bank.

SELECT customer_name FROM (Depositor NATURAL FULL OUTER JOIN Borrower) WHERE account_number IS NULL OR loan_number IS NULL; FUNCTIONS: AGGREGATE, DATE, STRING

AGGREGATE FUNCTIONS:

MYSQL> SELECT * FROM EMP; output:ENO ENAME JOB SAL ----- --------- ---------- ---------1001 STEVE SALESMAN 1500

76 | P a g e

1002 ADAM CLERK 1000 1003 EVE MANAGER 5220 1004 JAMES DIRECTOR 7000

MYSQL> SELECT COUNT(*)FROM EMP; output:COUNT(*) ---------4 MYSQL> SELECT SUM(SAL) FROM EMP; output:SUM(SAL) ---------14720

MYSQL> SELECT AVG(SAL) FROM EMP; output:AVG(SAL) ---------3680

MYSQL> SELECT MAX(SAL) FROM EMP; output:MAX(SAL)

77 | P a g e

---------7000

MYSQL> SELECT MIN(SAL) FROM EMP; output:MIN(SAL) ---------1000

MYSQL>select * from emp;

OUTPUT:EMPNO ENAME JOB SAL DEPTNO ------ -------- --------- ------- -------7369 SMITH CLERK 800 20 7499 ALLEN SALESMAN 1600 30 7521 WARD SALESMAN 1250 30 7566 JONES MANAGER 2975 20 7654 MARTIN SALESMAN 1250 30 78 | P a g e

7698 BLAKE MANAGER 2850 30 7782 CLARK MANAGER 2450 10 7788 SCOTT ANALYST 3000 20 7839 KING PRESIDENT 5000 10 7844 TURNER SALESMAN 1500 30 7876 ADAMS CLERK 1100 20 7900 JAMES CLERK 950 30 7902 FORD ANALYST 3000 20 7934 MILLER CLERK 1300 10

14 rows selected.

MYSQL> select round(12.36), round(14.63) ; OUTPUT:ROUND(12.36) ROUND(14.63) ------------ -----------12 15

MYSQL> select floor(12.87), floor(11.23) ; OUTPUT:FLOOR(12.87) FLOOR(11.23) ------------ -----------12 11 MYSQL> select ceil(16.23), ceil(12.78) ;

79 | P a g e

OUTPUT:CEIL(16.23) CEIL(12.78) ----------- ----------17 13

MYSQL> select trunc(56.63) ; OUTPUT:TRUNC(56.63) -----------56

MYSQL> select mod(11,4) ; OUTPUT:MOD(11,4) ---------3

MYSQL> select power(2,3) ; OUTPUT:POWER(2,3) ---------8

80 | P a g e

MYSQL> select sign(0),sign(34),sign(-56) ; OUTPUT:SIGN(0) SIGN(34) SIGN(-56) -------- --------- ---------0 1 -1

MYSQL> select abs(12),abs(-89) ;

OUTPUT:ABS(12) ABS(-89) ---------- ---------12 89 MYSQL> select sqrt(25) ; OUTPUT:SQRT(25) -------5

STRING FUNCTIONS:

MYSQL>SELECT CONCAT(ORACLE,CORPORATION) ;

81 | P a g e

OUTPUT:-ORACLECORPORATION

MYSQL>SELECT LPAD(ORACLE,15,*) ;

OUTPUT:-*********ORACLE

MYSQL>SELECT RPAD(ORACLE,15,*) ;

OUTPUT:-ORACLE*********

MYSQL>SELECT LTRIM(SSMITHSS,S) ;

OUTPUT:-MITHSS

MYSQL>SELECT RTRIM(SSMITHSS,S) ;

OUTPUT:-SSMITH

MYSQL>SELECT LOWER(DBMS) ;

OUTPUT:-dbms

MYSQL>SELECT UPPER(dbms) ;

82 | P a g e

OUTPUT:-DBMS

MYSQL>SELECT INITCAP(ORACLE,CORPORATION) ;

OUTPUT:-Oracle Corporation

MYSQL>SELECT LENGTH(DATABASE) ;

OUTPUT:-8

MYSQL>SELECT SUBSTR(ABCDEFGHIJ3,4) ;

OUTPUT:-CDEF

MYSQL>SELECT INSTR('CORPORATE FLOOR','OR',3,2) ;

OUTPUT:-14

DATE FUNCTIONS:

MYSQL>SELECT SYSDATE ; OUTPUT:-29-DEC-08 83 | P a g e

MYSQL>SELECT NEXT_DAY(SYSDATE,WED) ; OUTPUT:-05-JAN-09

MYSQL>SELECT ADD_MONTHS(SYSDATE,2) ; OUTPUT:-28-FEB-09

MYSQL>SELECT LAST_DAY(SYSDATE) ; OUTPUT:-31-DEC-08

MYSQL>SELECT LEAST('10-JAN-07','12-OCT-07') ; OUTPUT:-10-JAN-07

MYSQL>SELECT GREATEST('10-JAN-07','12-OCT-07') ;

OUTPUT:-10-JAN-07

MYSQL>SELECT TRUNC(SYSDATE,'DAY') ; OUTPUT:-28-DEC-08

MYSQL>SELECT TRUNC(SYSDATE,'MONTH') ; OUTPUT:-01-DEC-08

MYSQL>SELECT TRUNC(SYSDATE,'YEAR') ; 84 | P a g e

OUTPUT:-01-JAN-08

MYSQL>SELECT ROUND(SYSDATE,'DAY') ; OUTPUT:-28-DEC-08

MYSQL>SELECT ROUND(SYSDATE,'MONTH') ; OUTPUT:-01-JAN-09

MYSQL>SELECT ROUND(SYSDATE,'YEAR') ; OUTPUT:-01-JAN-09

List of date functions

Name ADDDATE() ADDTIME() CONVERT_TZ() CURDATE() CURRENT_DATE(), CURRENT_DATE CURRENT_TIME(), CURRENT_TIME CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP CURTIME() DATE_ADD() DATE_FORMAT() DATE_SUB() DATE() DATEDIFF()
85 | P a g e

Description Add dates Add time Convert from one timezone to another Return the current date Synonyms for CURDATE() Synonyms for CURTIME() Synonyms for NOW() Return the current time Add two dates Format date as specified Subtract two dates Extract the date part of a date or datetime expression Subtract two dates

DAY() DAYNAME() DAYOFMONTH() DAYOFWEEK() DAYOFYEAR() EXTRACT FROM_DAYS() FROM_UNIXTIME() GET_FORMAT() HOUR() LAST_DAY LOCALTIME(), LOCALTIME LOCALTIMESTAMP, LOCALTIMESTAMP() MAKEDATE() MAKETIME MICROSECOND() MINUTE() MONTH() MONTHNAME() NOW() PERIOD_ADD() PERIOD_DIFF() QUARTER() SEC_TO_TIME() SECOND() STR_TO_DATE() SUBDATE() SUBTIME() SYSDATE() TIME_FORMAT() TIME_TO_SEC()
86 | P a g e

Synonym for DAYOFMONTH() Return the name of the weekday Return the day of the month (1-31) Return the weekday index of the argument Return the day of the year (1-366) Extract part of a date Convert a day number to a date Format date as a UNIX timestamp Return a date format string Extract the hour Return the last day of the month for the argument Synonym for NOW() Synonym for NOW() Create a date from the year and day of year returns a time value calculated from the hour, minute, and second arguments Return the microseconds from argument Return the minute from the argument Return the month from the date passed Return the name of the month Return the current date and time Add a period to a year-month Return the number of months between periods Return the quarter from a date argument Converts seconds to 'HH:MM:SS' format Return the second (0-59) Convert a string to a date When invoked with three arguments a synonym for DATE_SUB() Subtract times Return the time at which the function executes Format as time Return the argument converted to

TIME() TIMEDIFF() TIMESTAMP()

TIMESTAMPADD() TIMESTAMPDIFF() TO_DAYS() UNIX_TIMESTAMP() UTC_DATE() UTC_TIME() UTC_TIMESTAMP() WEEK() WEEKDAY() WEEKOFYEAR() YEAR() YEARWEEK()

seconds Extract the time portion of the expression passed Subtract time With a single argument, this function returns the date or datetime expression. With two arguments, the sum of the arguments Add an interval to a datetime expression Subtract an interval from a datetime expression Return the date argument converted to days Return a UNIX timestamp Return the current UTC date Return the current UTC time Return the current UTC date and time Return the week number Return the weekday index Return the calendar week of the date (153) Return the year Return the year and week

APPLYING GROUP BY ---

MYSQL> select deptno,max(sal) from emp group by deptno; OUTPUT:DEPTNO MAX(SAL) ---------- ---------10 5000 20 3000

87 | P a g e

30 2850

MYSQL> select deptno,min(sal) from emp group by deptno; OUTPUT:DEPTNO MIN(SAL) ---------- ---------10 1300 20 800 30 950

MYSQL> select deptno,max(sal) from emp group by deptno having max(sal)<3000; OUTPUT:DEPTNO MAX(SAL) ---------- ---------30 2850

MYSQL>select deptno,min(sal) from emp group by deptno having min(sal)>1000; OUTPUT:DEPTNO MIN(SAL) -------- ---------10 1300

MYSQL> select ename,count(*) from emp group by deptno;

88 | P a g e

OUTPUT:DEPTNO COUNT(*) --------- ------10 3 20 5 30 6 3 rows selected.

CONVERSION FUNCTIONS(TO_CHAR)

MYSQL>select to_char(65,'RN') ; OUTPUT:LXV

MYSQL>select to_char(65,'rn') ; OUTPUT:lxv

MYSQL>select to_char(58,'s9999') ; OUTPUT:+58

MYSQL>select to_char(-100,'s9999') ; OUTPUT:-100

MYSQL> select to_char(41,'XXXX') ; OUTPUT:29

89 | P a g e

MYSQL> select to_char(10,'XXXX') ; OUTPUT:A

MYSQL> select to_char(sysdate,'day') ; OUTPUT:MONDAY

MYSQL> SELECT TO_CHAR(SYSDATE,'MONTH') ; OUTPUT:JANUARY

MYSQL> SELECT TO_CHAR(SYSDATE,'YEAR') ; OUTPUT:TWO THOUSAND NINE

MYSQL> select to_char(123456,'9g99g999') ; OUTPUT:1,23,456

MYSQL> select to_char(1234,'l9999') ; OUTPUT:$1234

MYSQL> select to_char(123456,'9g99g999d999') ; OUTPUT:1,23,456.000

SELECT TO_CHAR(2234,'L9999','NLS_CURRENCY=RS') ; OUTPUT:RS2234

90 | P a g e

2. Queries (along with subqueries) using ANY, ALL, IN, EXISTS, NOT
EXISTS, UNIQUE, INTERSECT, Constraints.

Example: select the rollno and name of the student who secured 4th rank in the class.

2. Queries using Aggregate functions (COUNT, SUM, AVG, MAX and MIN),
GROUP BY, HAVING and Creation and Dropping of Views.

2. Queries using Conversions, functions (to_char, to_num, and to_date),


string function (Conactenation, lpad, rpad, ltrim, rtrim, lower, upper, initcap, length, substr, and instr), date functions (sysdate, next_day, add_months, last_day, months_between, least, greatest, trunk, round, to_char, to_date).

1. To display system date.


select SYSDATE;

2. To display arithmetic calculations.


select 2*2;

3. To display the logged user.


select USER;

4. To display system time.


select TO_CHAR(sysdate, HH:MI:SS) ;

5. To display current month.


select TO_CHAR(sysdate, MONTH) ;

91 | P a g e

6. To display system date in specified format.


select TO_CHAR(sysdate, dd/mm/yy) ;

7. To display system date in specified format.


select TO_CHAR(sysdate, mm) ;

8. To display date arithmetic.


select ADD_MONTHS(SYSDATE, 5) ;

9. To display date arithmetic.


select LAST_DAY(SYSDATE) ;

10. To display date arithmetic.


select MONTHS_BETWEEN(SYSDATE, 01-APR-09) ;

11. To display date arithmetic.


select NEXT_DAY(SYSDATE, MON) ;

GROUP FUNCTIONS:

12. To display average basic salary of the employees.


SELECT SUM(basic) FROM salary;

92 | P a g e

13. To display minimum basic salary of the employees.


SELECT MIN(basic) FROM salary;

14. To display maximum basic salary of the employees.


SELECT MAX(basic) FROM salary;

15. To display sum of basic salaries of all the employees.


SELECT SUM(basic) FROM salary;

16. To display the number of records in salary table.


SELECT COUNT(*) FROM salary;

STRING FUNCTIONS:

17. To display a field value after left padding.


select lpad('page-1', 10, '*') ;

18. To display a field value after left padding.


select Rpad('page-1', 10, '*') ;

19. To display a field value after converting to lower case.


select LOWER(A) ;

20. To display a field value after converting to upper case.


select LOWER(a) ; 93 | P a g e

21. To display a field value after converting to initial capital case.


select INITCAP(HOw are you?) ;

23. To display a substring of a field value.


select substr(cse2a, 4, 2) ;

24. To display the length of a field value.


select length(how long am i?) ;

25. To display a field value after trimming the right side.


select rtrim(cse2a, 2a) ;

26. To display a field value after trimming the left side.


SELEct ltrim(cse2a, cse) ;

94 | P a g e

SUBQUERRIES
Writing Subqueries A subquery can be defined as a query within a query. In other words, any query results that we reuse in another query. Subquery is known as nestee queries or subselects also. Subqueries don?t include any new functionality but the queries are more readable with using subqueries rather than of joins.

We will describe you the subqueries with the help of following tables: mysql> SELECT * FROM Client; +------+---------------+----------+ | C_ID | Name | City | +------+---------------+----------+ | 1 | A K Ltd | Delhi | | 2 | V K Associate | Mumbai | | 3 | R K India | Banglore | | 4 | R S P Ltd | Kolkata | | 5 | A T Ltd | Delhi | | 6 | D T Info | Delhi | +------+---------------+----------+ 6 rows in set (0.08 sec) mysql> SELECT * FROM Products; +---------+-------------+------+----------+ | Prod_ID | Prod_Detail | C_ID | price | 95 | P a g e

+---------+-------------+------+----------+ | 111 | Monitor | 1 | 7000.00 | | 112 | Processor | 2 | 11000.00 | | 113 | Keyboard | 2 | 1200.00 | | 114 | Mouse | 3 | 500.00 | | 115 | CPU | 5 | 15500.00 | +---------+-------------+------+----------+ 5 rows in set (0.00 sec) There are 3 basic types of subqueries in SQL:

Predicate Subqueries - extended logical constructs in the WHERE (and HAVING) clause. Scalar Subqueries - standalone queries that return a single value; they can be used anywhere a scalar value is used. Table Subqueries - queries nested in the FROM clause.

All subqueries must be enclosed in parentheses. Predicate Subqueries Predicate Subqueries can be used in the HAVING and WHERE clause only because both are special logical construct. These subqueries must retrieve one column.

IN Subquery The IN subquery tests if a scalar values match with the single query column value in any subquery result row.

96 | P a g e

The general syntax is : Value_1 [NOT] IN (query_1) In the following example we are getting the list of clients that are available in Products table also. Example : mysql> SELECT * FROM Client WHERE C_ID IN -> (SELECT C_ID FROM Products); +------+---------------+----------+ | C_ID | Name | City | +------+---------------+----------+ | 1 | A K Ltd | Delhi | | 2 | V K Associate | Mumbai | | 3 | R K India | Banglore | | 5 | A T Ltd | Delhi | +------+---------------+----------+ 4 rows in set (0.00 sec) In the following example we are getting the list of clients that are not available in Products table also. Example : mysql> SELECT * FROM Client WHERE C_ID NOT IN -> (SELECT C_ID FROM Products); +------+-----------+---------+ | C_ID | Name | City | +------+-----------+---------+ | 4 | R S P Ltd | Kolkata | | 6 | D T Info | Delhi | +------+-----------+---------+

97 | P a g e

2 rows in set (0.01 sec) Quantified Subqueries A quantified subquery can use the all comparison operators for several types of tests. The general syntax is : Value_1 {=|>|<|>=|<=|<>} {ANY | ALL | SOME} (query_1) The comparison operator is used to compare value_1 to the single query column value from each subquery result row. If we are using ALL clause then must match the all rows in subquery, or subquery must be empty. If we are using ANY or SOME clause then must match at least one row in the subquery.

Example : mysql> SELECT * FROM Client WHERE C_ID= ANY(SELECT C_ID FROM Products); +------+---------------+----------+ | C_ID | Name | City | +------+---------------+----------+ | 1 | A K Ltd | Delhi | | 2 | V K Associate | Mumbai | | 3 | R K India | Banglore | | 5 | A T Ltd | Delhi | +------+---------------+----------+ 4 rows in set (0.00 sec)

Exists Subqueries The EXISTS subquery is used to tests whether a subquery returns at

98 | P a g e

least one row or a qualifying row exists. The general syntax is : Exists (query_1) Any EXISTS subquery should contain an outer reference. It must be a correlated subquery. Example : mysql> SELECT * FROM Client -> WHERE EXISTS -> (SELECT * FROM Products WHERE Client.C_ID=Products.C_ID); +------+---------------+----------+ | C_ID | Name | City | +------+---------------+----------+ | 1 | A K Ltd | Delhi | | 2 | V K Associate | Mumbai | | 3 | R K India | Banglore | | 5 | A T Ltd | Delhi | +------+---------------+----------+ 4 rows in set (0.00 sec) Scalar Subqueries The Scalar Subquery is a subquery which returns a single value. A Scalar subquery can be used almost anywhere a single column value can be used. The subquery have to reference only one column in the select list. It must not retrieve more than one row. When subquery retrieve one row then the value of select list column becomes the value of the Scalar Subquery. Example :
mysql> SELECT (SELECT Name FROM Client WHERE C_ID=1);

99 | P a g e

+----------------------------------------+ | (SELECT Name FROM Client WHERE C_ID=1) | +----------------------------------------+ | A K Ltd | +----------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT (SELECT C_ID FROM Products WHERE C_ID=2) FROM Client; ERROR 1242 (21000): Subquery returns more than 1 row mysql> SELECT (SELECT C_ID FROM Products WHERE C_ID=1) FROM Client; +------------------------------------------+ | (SELECT C_ID FROM Products WHERE C_ID=1) | +------------------------------------------+ | 1 | | 1 | | 1 | | 1 | | 1 | | 1 | +------------------------------------------+ 6 rows in set (0.01 sec)

Table Subqueries Table subqueries are used in the FROM Clause , replace the table name. These subqueries can have correlation name also. Example : mysql> SELECT Client.*,Price -> FROM Client, Products 100 | P a g e

-> WHERE Client.C_ID=Products.C_ID -> AND Price>1000; +------+---------------+--------+----------+ | C_ID | Name | City | Price | +------+---------------+--------+----------+ | 1 | A K Ltd | Delhi | 7000.00 | | 2 | V K Associate | Mumbai | 11000.00 | | 2 | V K Associate | Mumbai | 1200.00 | | 5 | A T Ltd | Delhi | 15500.00 | +------+---------------+--------+----------+ 4 rows in set (0.06 sec) Using Single Value Subqueries Firstly we will start with a simple query : mysql> SELECT MAX(Price) FROM Products; +------------+ | MAX(Price) | +------------+ | 15500.00 | +------------+ 1 row in set (0.60 sec) The above example retrieve only a single value and its representing the maximum Price of the Product. In this example we used a MySQL Function MAX() that finds the greatest values in a specified column.

101 | P a g e

Single ? value subqueries is used to return a single column value and then they are typically used for comparison. For Example :
mysql> SELECT * FROM Client c,Products p WHERE c.C_ID=p.C_ID -> AND p.Price=(SELECT MAX(Price) FROM Products); +------+---------+-------+---------+-------------+------+----------+ | C_ID | Name | City | Prod_ID | Prod_Detail | C_ID | price | +------+---------+-------+---------+-------------+------+----------+ | 5 | A T Ltd | Delhi | 115 | CPU | 5 | 15500.00 | +------+---------+-------+---------+-------------+------+----------+ 1 row in set (0.02 sec)

102 | P a g e

JOINS
If we do a regular JOIN (with none of the keywords INNER, OUTER, LEFT or RIGHT), then you get all records that match in the appropriate way in the two tables, and records in both incoming tables that do not match are not reported: mysql> select name, phone, selling from demo_people join demo_property on demo_people.pid = demo_property.pid;

+-----------+--------------+----------------------+ | name | phone | selling | +-----------+--------------+----------------------+ | Mr Brown | 01225 708225 | Old House Farm | | Mr Pullen | 01380 724040 | The Willows | | Mr Pullen | 01380 724040 | Tall Trees | | Mr Pullen | 01380 724040 | The Melksham Florist | +-----------+--------------+----------------------+ 4 rows in set (0.01 sec) MySQL LEFT, RIGHT JOIN
MySQL joins are hard for beginners. It will try to explain the joins in the simplest possible way. Join in MySQL is a query where you can join one or more tables.

For example we have two tables: products and buyers with the following structures. Table products: mysql> SELECT * FROM products; +----+--------------+--------------+ | id | product_name | manufacturer | +----+--------------+--------------+ | 1 | Shoes | Company1 | | 2 | Laptop | Company2 | | 3 | Monitor | Company3 | | 4 | DVD | Company4 | 103 | P a g e

+----+--------------+--------------+ 4 rows in set (0.00 sec) Table buyers: mysql> SELECT * FROM buyers; +----+------+------------+----------+ | id | pid | buyer_name | quantity | +----+------+------------+----------+ | 1 | 1 | Steve | 2 | | 2 | 2 | John | 1 | | 3 | 3 | Larry | 1 | | 4 | 3 | Michael | 5 | | 5 | NULL | Steven | NULL | +----+------+------------+----------+ 5 rows in set (0.00 sec) Left Join mysql> SELECT buyer_name, quantity, product_name FROM buyers LEFT JOIN products ON buyers.pid=products.id; +------------+----------+--------------+ | buyer_name | quantity | product_name | +------------+----------+--------------+ | Steve | 2 | Shoes | | John | 1 | Laptop | | Larry | 1 | Monitor | | Michael | 5 | Monitor | | Steven | NULL | NULL | +------------+----------+--------------+ 104 | P a g e

5 rows in set (0.00 sec) What happened? Mysql starts with the left table (buyers). For each row from the table buyers mysql scans the table products, finds the id of the product and returns the product name. Then the product name is joined with the matching row from the table buyers. For unmatched rows it returns null. To make it simpler, the above query is same as (except the unmatched rows are not returned): mysql> SELECT buyers.buyer_name, buyers.quantity, products.product_name FROM buyer s,products WHERE buyers.pid=products.id; +------------+----------+--------------+ | buyer_name | quantity | product_name | +------------+----------+--------------+ | Steve | 2 | Shoes | | John | 1 | Laptop | | Larry | 1 | Monitor | | Michael | 5 | Monitor | +------------+----------+--------------+ 4 rows in set (0.00 sec)

If we do a LEFT JOIN, we get all records that match in the same way and IN ADDITION you get an extra record for each unmatched record in the left table of the join - thus ensuring (in my example) that every PERSON gets a mention: mysql> select name, phone, selling from demo_people left join demo_property on demo_people.pid = demo_property.pid; +------------+--------------+----------------------+ | name | phone | selling | +------------+--------------+----------------------+ | Mr Brown | 01225 708225 | Old House Farm | | Miss Smith | 01225 899360 | NULL | | Mr Pullen | 01380 724040 | The Willows | | Mr Pullen | 01380 724040 | Tall Trees | 105 | P a g e

| Mr Pullen | 01380 724040 | The Melksham Florist | +------------+--------------+----------------------+ 5 rows in set (0.00 sec)

MySQL LEFT JOIN: A MySQL left join is different from a simple join. A MySQL LEFT JOIN gives extra consideration to the table that is on the left. If you do a LEFT JOIN, you get all records that match in the same way and IN ADDITION I get an extra record for each unmatched record in the left table of the join - thus ensuring (in my example) that every AUTHOR gets a mention: Example:

Try out following example to understand LEFT JOIN:


root@host# mysql -u root -p password; Enter password:******* mysql> use TUTORIALS; Database changed mysql> SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count -> FROM tutorials_tbl a LEFT JOIN tcount_tbl b -> ON a.tutorial_author = b.tutorial_author; +-------------+-----------------+----------------+ | tutorial_id | tutorial_author | tutorial_count | +-------------+-----------------+----------------+ | 1 | John Poul | 1 | | 2 | Abdul S | NULL | | 3 | Sanjay | 1 | +-------------+-----------------+----------------+ 3 rows in set (0.02 sec) 106 | P a g e

Right Join mysql> SELECT buyer_name, quantity, product_name FROM buyers RIGHT JOIN products ON buyers.pid=products.id; +------------+----------+--------------+ | buyer_name | quantity | product_name | +------------+----------+--------------+ | Steve | 2 | Shoes | | John | 1 | Laptop | | Larry | 1 | Monitor | | Michael | 5 | Monitor | | NULL | NULL | DVD | +------------+----------+--------------+ 5 rows in set (0.00 sec) What happens here is Mysql starts with the Right table (products). For each id from the table products MySQL scans the left table - buyers to find the matching pid. When it finds the matching pid it returns the buyer_name and the quantity. For unmatched rows it returns null. From my example above it returns NULL for DVD because no one bought DVD.

MySQL outer join: First of all, outer joins are for instances where info is being looked up on another table and you want rows returned even though nothing was matched for a particular id, e.g.: create table food (id int unsigned primary key auto_increment,food char(16), yummy char(1),animal char(16)); create table animals (name char(16) primary key,weight int unsigned); insert into food values(NULL, 'apple', 'Y', 'human'),(NULL, 'oranges', 'Y', 'human'), (NULL, 'apple', 'N', 'dog'),(NULL, 'oranges', 'N', 'dog'),(NULL, 107 | P a g e

'apple', 'N', 'cat'), (NULL, 'oranges', 'N', 'cat'); insert into animals values('cat', 12),('dog', 25); table 'food' id food yummy animal --- ---- ----- -----1 apple Y human 2 oranges Y human 3 apple N dog 4 oranges N dog 5 apple N cat 6 oranges N cat table 'animals' name weight ---- -----Cat 12 Dog 25 Let's say you want a list of all the foods and the weight of the animals. If you do: MYSQL>select f.*, a.weight from food f, animals a where f.animal = a.name; In this case the result would be: +---+--------+--------+--------+--------+ | id| food |yummy | animal | weight | +---+--------+--------+--------+--------+ | 5 | apple | N | cat | 12 | | 6 | orange | N | cat | 12 | | 3 | apple | N | dog | 25 | | 4 | oranges| N | dog | 25 | +---+--------+--------+--------+--------+ Notice that humans is missing, but if you want the humans to show up even though there's no human entry in the 'animals' table you have to do an outer join (aka LEFT [OUTER] JOIN in Mysql): select f.*, a.weight from food f LEFT JOIN animals a on (f.animal=a.name); 108 | P a g e

In this case the result would be: +----+---------+-------+--------+--------+ | id | food | yummy | animal | weight | +----+---------+-------+--------+--------+ | 1 | apple | Y | human | NULL | | 2 | oranges | Y | human | NULL | | 3 | apple | N | dog | 25 | | 4 | oranges | N | dog | 25 | | 5 | apple | N | cat | 12 | | 6 | oranges | N | cat | 12 | +----+---------+-------+--------+--------+ Here are some more examples: SELECT T.name, V.value, T.unit, T.id, A.Product_id FROM attribute_type AS T LEFT JOIN attribute AS A ON ( T.id = A.type_id AND A.Product_id = 21 ) LEFT JOIN attribute_value AS V ON ( A.value_id = V.id ); select j.id, j.job_id, d.NAMES, e.DETAILS1, j.file_name, j.job_owner, j.import_date from db.summary_jobs j left join db.EST e on (j.job_id=e.JOB_NUMBER) left join db.DEB d on (e.DEBTOR=d.AC_NO) order by j.job_id desc limit ;

MySQL - LEFT JOIN and RIGHT JOIN, INNER JOIN and OUTER JOIN

In a database such as MySQL, data is divided into a series of tables (the "why" is beyond what I'm writing today) which are then connected together in SELECT commands to generate the output required. I find when I'm running MySQL training, people often get confused between all the join flavours. Let me give you an example to see how it works.

First, some sample data: Mr Brown, Person number 1, has a phone number 01225 708225 Miss Smith, Person number 2, has a phone number 01225 899360 Mr Pullen, Person number 3, has a phone number 01380 724040 and also: Person number 1 is selling property number 1 - Old House Farm Person number 3 is selling property number 2 - The Willows Person number 3 is (also) selling property number 3 - Tall Trees 109 | P a g e

Person number 3 is (also) selling property number 4 - The Melksham Florist Person number 4 is selling property number 5 - Dun Roamin. mysql> select * from demo_people; +------------+--------------+------+ | name | phone | pid | +------------+--------------+------+ | Mr Brown | 01225 708225 | 1 | | Miss Smith | 01225 899360 | 2 | | Mr Pullen | 01380 724040 | 3 | +------------+--------------+------+ 3 rows in set (0.00 sec) mysql> select * from demo_property; +------+------+--------------------+ | pid | spid | selling | +-----+------+---------------------+ | 1 | 1 | Old House Farm | | 3 | 2 | The Willows | | 3 | 3 | Tall Trees | | 3 | 4 | The Melksham Florist | | 4 | 5 | Dun Roamin | +-----+-----+----------------------+ 5 rows in set (0.00 sec)

If I do a RIGHT JOIN, I ADDITION I get an extra right table of the join property gets a mention

get all the records that match and IN record for each unmatched record in the - in my example, that means that each even if we don't have seller details:

mysql> select name, phone, selling from demo_people right join demo_property on demo_people.pid = demo_property.pid; +-----------+--------------+----------------------+ | name | phone | selling | +-----------+--------------+----------------------+ | Mr Brown | 01225 708225 | Old House Farm | | Mr Pullen | 01380 724040 | The Willows | | Mr Pullen | 01380 724040 | Tall Trees | | Mr Pullen | 01380 724040 | The Melksham Florist | | NULL | NULL | Dun Roamin | +-----------+--------------+----------------------+ 5 rows in set (0.00 sec) An INNER JOIN does a full join, just like the first example, and the word OUTER may be added after the word LEFT or RIGHT in the last two 110 | P a g e

examples - it's provided for ODBC compatibility and doesn't add an extra capabilities.

This INNER JOIN example for MySQL shows you how to combine rows of two tables using an INNER JOIN. You can write them with the help of the comma operator or the INNER JOIN keywords. The keywords JOIN and CROSS JOIN are synonymous with "INNER JOIN". What can they do? An INNER JOIN can be used to combine (join) matching rows. This is important, because they can't be used to identify rows without matches, i.e. rows in one table that have no match in another table. To do this, an OUTER JOIN can be used. Sample data We will use the following tables for the purpose of this example: MYSQL>CREATE TABLE IF NOT EXISTS `products`(`productid` int(11) NOT NULL,`name` varchar(128) NOT NULL,PRIMARY KEY (`productid`))ENGINE=InnoDB DEFAULT CHARSET=latin1;

MYSQL>INSERT INTO `products` (`productid`, `name`) VALUES (1, 'keyboard'),(2, 'mouse'),(3, 'monitor'),(4, 'harddisk'), (5, 'printer');

--------------------------------------------------------

MYSQL>CREATE TABLE IF NOT EXISTS `stock`(`productid` int(11) NOT NULL,`inventory` int(11) NOT NULL,PRIMARY KEY `productid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

MYSQL>INSERT INTO `stock` (`productid`,`inventory`)VALUES (1,10),(2,15),(3,4),(4,12),(5,6);

111 | P a g e

Writing the INNER JOIN To illustrate how to "join" tables, we are going to generate a listing of all products which includes the current stock of each product. This is how to do this using the comma operator: SELECT p.productid, p.name, s.inventory FROM products p, stock s WHERE p.productid = s.productid

-- output: +-----------+----------+-----------+ | productid | name | inventory | +-----------+----------+-----------+ | 1 | keyboard | 10 | | 2 | mouse | 15 | | 3 | monitor | 4 | | 4 | harddisk | 12 | | 5 | printer | 6 | +-----------+----------+-----------+ First of all, we have to tell MySQL that the selected data is stored in different tables. To do this, we add all required tables to the FROM clause, separated by a comma. Additionally, we have to tell MySQL how to combine the rows using the WHERE clause. In this example we only need a combinations of rows which belong to the same "productid". If we omit the WHERE clause, MySQL builds a Cartesian product and builds all possible combination of rows: SELECT p.productid, p.name, s.inventory FROM products p, stock s;

+-----------+---------------+-----------+ |productid | name |inventory | +-----------+---------------+-----------+ | 1 | keyboard | 10 | 112 | P a g e

| 2 | mouse | 10 | | 3 | monitor | 10 | | 4 | harddisk | 10 | | 5 | printer | 10 | | 1 | keyboard | 15 | | 2 | mouse | 15 | | 3 | monitor | 15 | | 4 | harddisk | 15 | | 5 | printer | 15 | | 1 | keyboard | 4 | | 2 | mouse | 4 | | 3 | monitor | 4 | | 4 | harddisk | 4 | | 5 | printer | 4 | | 1 | keyboard | 12 | | 2 | mouse | 12 | | 3 | monitor | 12 | | 4 | harddisk | 12 | | 5 | printer | 12 | | 1 | keyboard | 6 | | 2 | mouse | 6 | | 3 | monitor | 6 | | 4 | harddisk | 6 | | 5 | printer | 6 | +-----------+---------------+-----------+ 113 | P a g e

Another way to write an INNER JOIN is to use the INNER JOIN keywords (or a synonym like JOIN / CROSS JOIN). When you use the INNER JOIN keywords, they are used instead of the comma operator to separate the tables in the FROM clause. To tell MySQL how to combine the rows, either ON or USING are used to add a condition for the JOIN: SELECT p.productid, p.name, s.inventory FROM products p INNER JOIN stock s USING ( productid ) The example uses "USING" because the column which we use to join the rows has the name "productid". You can also do this using ON, which is for example required if the columns have different names: SELECT p.productid, p.name, s.inventory FROM products p INNER JOIN stock s ON p.productid = s.productid

Thus far we have only been getting data from one table at a time. This is fine for simple takes, but in most real world MySQL usage you will often need to get data from multiple tables in a single query. You can use multiple tables in your single SQL query. The act of joining in MySQL refers to smashing two or more tables into a single table. You can use JOINS in SELECT, UPDATE and DELETE statements to join MySQL tables. We will see an example of LEFT JOIN also which is different from simple MySQL JOIN. Using Joins at Command Prompt: Suppose we have two tables tcount_tbl and tutorials_tbl in TUTORIALS. A complete listing is given below: Example:

root@host# mysql -u root -p password; Enter password:******* mysql> use TUTORIALS;


114 | P a g e

Database changed mysql> SELECT * FROM tcount_tbl; +-----------------+----------------+ | tutorial_author | tutorial_count | +-----------------+----------------+ | mahran | 20 | | mahnaz | NULL | | Jen | NULL | | Gill | 20 | | John Poul | 1 | | Sanjay | 1 | +-----------------+----------------+ 6 rows in set (0.01 sec) mysql> SELECT * from tutorials_tbl; +-----------+---------------+---------------+---------------+ |tutorial_id|tutorial_title |tutorial_author|submission_date| +-----------+---------------+---------------+---------------+ | 1 | Learn PHP | John Poul | 2007-05-24 | | 2 | Learn MySQL | Abdul S | 2007-05-24 | | 3 | JAVA Tutorial | Sanjay | 2007-05-06 | +-----------+---------------+---------------+---------------+ 3 rows in set (0.00 sec)

115 | P a g e

Now we can write a SQL query to join these two tables. This query will select all the authors from table tutorials_tbl and will pickup corresponding number of tutorials fromtcount_tbl. SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count -> FROM tutorials_tbl a, tcount_tbl b -> WHERE a.tutorial_author = b.tutorial_author; +-------------+-----------------+----------------+ | tutorial_id | tutorial_author | tutorial_count | +-------------+-----------------+----------------+ | 1 | John Poul | 1 | | 3 | Sanjay | 1 | +-------------+-----------------+----------------+ 2 rows in set (0.01 sec)

116 | P a g e

WEEK 5

CREATE PROCEDURE and FUNCTION

1.CREATE PROCEDURE and CREATE FUNCTION Syntax CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ([proc_parameter[,...]]) [characteristic ...] routine_body

CREATE [DEFINER = { user | CURRENT_USER }] FUNCTION sp_name ([func_parameter[,...]]) RETURNS type [characteristic ...] routine_body proc_parameter: [ IN | OUT | INOUT ] param_name type func_parameter: param_name type

type: Any valid MySQL data type

characteristic:

117 | P a g e

LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'

routine_body: Valid SQL procedure statement

mysql> delimiter // mysql> CREATE PROCEDURE simpleproc (OUT param1 INT) -> BEGIN -> SELECT COUNT(*) INTO param1 FROM t; -> END; -> // Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ; mysql> CALL simpleproc(@a); Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @a; +------+ | @a |

118 | P a g e

+------+ | 3 | +------+ 1 row in set (0.00 sec)

ALTER PROCEDURE and ALTER FUNCTION Syntax ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]

characteristic: { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string' This statement can be used to change the characteristics of a stored procedure or function. As of MySQL 5.0.3, you must have the ALTER ROUTINE privilege for the routine. If binary logging is enabled, this statement might also require the SUPER privilege, as described. More than one change may be specified in an ALTER PROCEDURE or ALTER FUNCTION statement. DROP PROCEDURE and DROP FUNCTION Syntax DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name This statement is used to drop a stored procedure or function. That is, the specified routine is removed from the server. As of MySQL 5.0.3, you must have the ALTER ROUTINE privilege for the routine. (That privilege is granted automatically to the routine creator.) The IF EXISTS clause is a MySQL extension. It prevents an error from occurring if the procedure or function does not exist. A warning is produced that can be viewed with SHOW WARNINGS. DROP FUNCTION is also used to drop user-defined functions. CALL Statement Syntax CALL sp_name([parameter[,...]])

119 | P a g e

CALL sp_name[()] The CALL statement invokes a procedure that was defined previously with CREATE PROCEDURE. CALL can pass back values to its caller using parameters that are declared as OUT or INOUT parameters. It also returns the number of rows affected, which a client program can obtain at the SQL level by calling the ROW_COUNT() function and from C by calling the mysql_affected_rows() C API function. As of MySQL 5.0.30, stored procedures that take no arguments can be invoked without parentheses. That is, CALL p() and CALL p are equivalent. To get back a value from a procedure using an OUT or INOUT parameter, pass the parameter by means of a user variable, and then check the value of the variable after the procedure returns. (If you are calling the procedure from within another stored procedure or function, you can also pass a routine parameter or local routine variable as an IN or INOUT parameter.) For an INOUT parameter, initialize its value before passing it to the procedure. The following procedure has an OUT parameter that the procedure sets to the current server version, and an INOUT value that the procedure increments by one from its current value: CREATE PROCEDURE p (OUT ver_param VARCHAR(25), INOUT incr_param INT) BEGIN # Set value of OUT parameter SELECT VERSION() INTO ver_param; # Increment value of INOUT parameter SET incr_param = incr_param + 1; END; Before calling the procedure, initialize the variable to be passed as the INOUT parameter. After calling the procedure, the values of the two variables will have been set or modified: mysql> SET @increment = 10; mysql> CALL p(@version, @increment); mysql> SELECT @version, @increment; +------------+---------------------+ 120 | P a g e

| @version | @increment | +------------+--------------------+ | 5.0.25-log | 11 | ----------------+-----------------+

Variables in Stored Routines 1. DECLARE Local Variables 2. Variable SET Statement 3. SELECT ... INTO Statement You may declare and use variables within a routine. 1. DECLARE Local Variables DECLARE var_name[,...] type [DEFAULT value] This statement is used to declare local variables. To provide a default value for the variable, include a DEFAULT clause. The value can be specified as an expression; it need not be a constant. If the DEFAULT clause is missing, the initial value is NULL. The scope of a local variable is within the BEGIN ... END block where it is declared. 2. Variable SET Statement SET var_name = expr [, var_name = expr] ... The SET statement in stored routines is an extended version of the general SET statement. Referenced variables may be ones declared inside a routine, or global system variables. The SET statement in stored routines is implemented as part of the pre-existing SET syntax. This allows an extended syntax of SET a=x, b=y, ... where different variable types (locally declared variables and global and session server variables) can be mixed. 3. SELECT ... INTO Statement SELECT col_name[,...] INTO var_name[,...] table_expr

121 | P a g e

This SELECT syntax stores selected columns directly into variables. Therefore, only a single row may be retrieved. SELECT id,data INTO x,y FROM test.t1 LIMIT 1; User variable names are not case sensitive. Important SQL variable names should not be the same as column names. If an SQL statement, such as a SELECT ... INTO statement, contains a reference to a column and a declared local variable with the same name, MySQL currently interprets the reference as the name of a variable. For example, in the following statement, xname is interpreted as a reference to the xname variable rather than the xname column: CREATE PROCEDURE sp1 (x VARCHAR(5)) BEGIN DECLARE xname VARCHAR(5) DEFAULT 'bob'; DECLARE newname VARCHAR(5); DECLARE xid INT; SELECT xname,id INTO newname,xid FROM table1 WHERE xname = xname; SELECT newname; END; When this procedure is called, the newname variable returns the value 'bob' regardless of the value of the table1.xname column. Conditions and Handlers 1. DECLARE Conditions 2. DECLARE Handlers Certain conditions may require specific handling. These conditions can relate to errors, as well as to general flow control inside a routine. DECLARE Conditions DECLARE condition_name CONDITION FOR condition_value 122 | P a g e

condition_value: SQLSTATE [VALUE] sqlstate_value | mysql_error_code This statement specifies conditions that need specific handling. It associates a name with a specified error condition. The name can subsequently be used in a DECLARE HANDLER statement. A condition_value can be an SQLSTATE value or a MySQL error code. For a list of SQLSTATE and error values. DECLARE Handlers DECLARE handler_type HANDLER FOR condition_value[,...] statement

handler_type: CONTINUE | EXIT | UNDO

condition_value: SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION | mysql_error_code The DECLARE ... HANDLER statement specifies handlers that each may deal with one or more conditions. If one of these conditions occurs, the specified statement is executed. Statement can be a simple

123 | P a g e

statement (for example, SET var_name = value), or it can be a compound statement written using BEGIN and END. For a CONTINUE handler, execution of the current routine continues after execution of the handler statement. For an EXIT handler, execution terminates for the BEGIN ... END compound statement in which the handler is declared. (This is true even if the condition occurs in an inner block.) The UNDO handler type statement is not yet supported. If a condition occurs for which no handler has been declared, the default action is EXIT. A condition_value can be any of the following values:

An SQLSTATE value or a MySQL error code. You should not use SQLSTATE value '00000' or error code 0, because those indicate sucess rather than an error condition. For a list of SQLSTATE and error values, see A condition name previously specified with DECLARE ... CONDITION. SQLWARNING is shorthand for all SQLSTATE codes that begin with 01. NOT FOUND is shorthand for all SQLSTATE codes that begin with 02. This is relevant only within the context of cursors and is used to control what happens when a cursor reaches the end of a data set. SQLEXCEPTION is shorthand for all SQLSTATE codes not caught by SQLWARNING or NOT FOUND.

Example: mysql> CREATE TABLE test.t (s1 int,primary key (s1)); Query OK, 0 rows affected (0.00 sec)

mysql> delimiter // mysql> CREATE PROCEDURE handlerdemo () -> BEGIN -> DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; -> SET @x = 1; -> INSERT INTO test.t VALUES (1); -> SET @x = 2;

124 | P a g e

-> INSERT INTO test.t VALUES (1); -> SET @x = 3; -> END; -> // Query OK, 0 rows affected (0.00 sec)

mysql> CALL handlerdemo()// Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x// +------+ | @x | +------+ | 3 | +------+ 1 row in set (0.00 sec) The example associates a handler with SQLSTATE 23000, which occurs for a duplicate-key error. Notice that @x is 3, which shows that MySQL executed to the end of the procedure. If the line DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; had not been present, MySQL would have taken the default path (EXIT) after the second INSERT failed due to the PRIMARY KEY constraint, and SELECT @x would have returned 2. If you want to ignore a condition, you can declare a CONTINUE handler for it and associate it with an empty block. For example:

125 | P a g e

DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END; The statement associated with a handler refer to labels for blocks that enclose is, the scope of a block label does not declared within the block. Consider the REPEAT block has a label of retry: CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN ITERATE retry; # illegal END; END; IF i < 0 THEN LEAVE retry; # legal END IF; SET i = i - 1; UNTIL FALSE END REPEAT; END; The label is in scope for the IF statement within the block. It is not in scope for the CONTINUE handler, so the reference there is invalid and results in an error: ERROR 1308 (42000): LEAVE with no matching label: retry cannot use ITERATE or LEAVE to the handler declaration. That include the code for handlers following example, where the

126 | P a g e

To avoid using references to outer labels in handlers, you can use different strategies:

If you want to leave the block, you can use an EXIT handler: DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END; If you want to iterate, you can set a status variable in the handler that can be checked in the enclosing block to determine whether the handler was invoked. The following example uses the variable done for this purpose:

CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; DECLARE done INT DEFAULT FALSE; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN SET done = TRUE; END; END; IF NOT done AND i < 0 THEN LEAVE retry; END IF; SET i = i - 1; UNTIL FALSE END REPEAT; END;

127 | P a g e

Views
Table of Contents

1. ALTER VIEW Syntax 2. CREATE VIEW Syntax 3. DROP VIEW Syntax


ALTER VIEW Syntax ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER }] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION] This statement changes the definition of a view, which must exist. The syntax is similar to that for CREATE VIEW and the effect is the same as for CREATE OR REPLACE VIEW. This statement requires the CREATE VIEW and DROP privileges for the view, and some privilege for each column referred to in the SELECT statement. CREATE VIEW Syntax CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER }] VIEW view_name [(column_list)] AS select_statement 128 | P a g e

[WITH [CASCADED | LOCAL] CHECK OPTION] The select_statement is a SELECT statement that provides the definition of the view. (When you select from the view, you select in effect using the SELECT statement.) select_statement can select from base tables or other views. The view definition is frozen at creation time, so changes to the underlying tables afterward do not affect the view definition. For example, if a view is defined as SELECT * on a table, new columns added to the table later do not become part of the view. The ALGORITHM clause affects how MySQL processes the view. The DEFINER and SQL SECURITY clauses specify the security context to be used when checking access privileges at view invocation time. The WITH CHECK OPTION clause can be given to constrain inserts or updates to rows in tables referenced by the view. The CREATE VIEW statement requires the CREATE VIEW privilege for the view, and some privilege for each column selected by the SELECT statement. For columns used elsewhere in the SELECT statement you must have the SELECT privilege. If the OR REPLACE clause is present, you must also have the DROP privilege for the view. A view belongs to a database. By default, a new view is created in the default database. To create the view explicitly in a given database, specify the name as db_name.view_name when you create it. mysql> CREATE VIEW test.v AS SELECT * FROM t; Base tables and views share the same namespace within a database, so a database cannot contain a base table and a view that have the same name. Views must have unique column names with no duplicates, just like base tables. By default, the names of the columns retrieved by the SELECT statement are used for the view column names. To define explicit names for the view columns, the optional column_list clause can be given as a list of comma-separated identifiers. The number of names in column_list must be the same as the number of columns retrieved by the SELECT statement. mysql> ALTER VIEW v AS SELECT * FROM t; ERROR 6 (HY000): Error on delete of '.\test\arc/v.frm-0004' (Errcode: 2) mysql> CREATE TABLE t (qty INT, price INT); mysql> INSERT INTO t VALUES(3, 50); mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t; 129 | P a g e

mysql> SELECT * FROM v; +-------+--------+-------+ | qty | price | value | +-------+--------+-------+ | 3 | 50 | 150 | +-------+--------+-------+ A view definition is subject to the following restrictions:

The SELECT statement cannot contain a subquery in the FROM clause. The SELECT statement cannot refer to system or user variables. The SELECT statement cannot refer to prepared statement parameters. Within a stored routine, the definition cannot refer to routine parameters or local variables. Any table or view referred to in the definition must exist. However, after a view has been created, it is possible to drop a table or view that the definition refers to. In this case, use of the view results in an error. To check a view definition for problems of this kind, use the CHECK TABLE statement. The definition cannot refer to a TEMPORARY table, and you cannot create a TEMPORARY view. The tables named in the view definition must already exist. You cannot associate a trigger with a view.

ORDER BY is allowed in a view definition, but it is ignored if you select from a view using a statement that has its own ORDER BY. For other options or clauses in the definition, they are added to the options or clauses of the statement that references the view, but the effect is undefined. For example, if a view definition includes a LIMIT clause, and you select from the view using a statement that has its own LIMIT clause, it is undefined which limit applies. This same principle applies to options such as ALL, DISTINCT, or SQL_SMALL_RESULT that follow the SELECT keyword, and to clauses such as INTO, FOR UPDATE, LOCK IN SHARE MODE, and PROCEDURE. If you create a view and then change the query processing environment by changing system variables, that may affect the results that you get from the view:

130 | P a g e

mysql> CREATE VIEW v (mycol) AS SELECT 'abc'; Query OK, 0 rows affected (0.01 sec)

mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec)

mysql> SELECT "mycol" FROM v; +-------+ | mycol | +-------+ | mycol | +-------+ 1 row in set (0.01 sec)

mysql> SET sql_mode = 'ANSI_QUOTES'; Query OK, 0 rows affected (0.00 sec)

mysql> SELECT "mycol" FROM v; +-------+ | mycol | +-------+ | abc | +-------+ 1 row in set (0.00 sec)

131 | P a g e

If you specify the DEFINER clause, these rules determine the legal DEFINER user values:

If you do not have the SUPER privilege, the only legal user value is your own account, either specified literally or by using CURRENT_USER. You cannot set the definer to some other account. If you have the SUPER privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated.

If the SQL SECURITY value is DEFINER but the definer account does not exist when the view is referenced, an error occurs. Within a stored routine that is defined with the SQL SECURITY DEFINER characteristic, CURRENT_USER returns the routine creator. This also affects a view defined within such a routine, if the view definition contains a DEFINER value of CURRENT_USER. Example: A view might depend on a stored function, and that function might invoke other stored routines. For example, the following view invokes a stored function f(): CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name); Suppose that f() contains a statement such as this: IF name IS NULL then CALL p1(); ELSE CALL p2(); END IF; The privileges required for executing statements within f() need to be checked when f() executes. This might mean that privileges are needed for p1() or p2(), depending on the execution path within f(). Those privileges must be checked at runtime, and the user who must possess the privileges is determined by the SQL SECURITY values of the view v and the function f(). The DEFINER and SQL SECURITY clauses for views are extensions to standard SQL. In standard SQL, views are handled using the rules for SQL SECURITY INVOKER. If you invoke a view that was created before MySQL 5.0.13, it is treated as though it was created with a SQL SECURITY DEFINER clause and with a DEFINER value that is the same as your account. However, because the actual definer is unknown, MySQL issues a warning. To make 132 | P a g e

the warning go away, it is sufficient to re-create the view so that the view definition includes a DEFINER clause. The optional ALGORITHM clause is a MySQL extension to standard SQL. It affects how MySQL processes the view. ALGORITHM takes three values: MERGE, TEMPTABLE, or UNDEFINED. The default algorithm is UNDEFINED if no ALGORITHM clause is present. For MERGE, the text of a statement that refers to the view and the view definition are merged such that parts of the view definition replace corresponding parts of the statement. For TEMPTABLE, the results from the view are retrieved into a temporary table, which then is used to execute the statement. For UNDEFINED, MySQL chooses which algorithm to use. It prefers MERGE over TEMPTABLE if possible, because MERGE is usually more efficient and because a view cannot be updatable if a temporary table is used. A reason to choose TEMPTABLE explicitly is that locks can be released on underlying tables after the temporary table has been created and before it is used to finish processing the statement. This might result in quicker lock release than the MERGE algorithm so that other clients that use the view are not blocked as long. A view algorithm can be UNDEFINED for three reasons:

No ALGORITHM clause is present in the CREATE VIEW statement. The CREATE VIEW statement has an explicit ALGORITHM = UNDEFINED clause. ALGORITHM = MERGE is specified for a view that can be processed only with a temporary table. In this case, MySQL generates a warning and sets the algorithm to UNDEFINED.

As mentioned earlier, MERGE is handled by merging corresponding parts of a view definition into the statement that refers to the view. The following examples briefly illustrate how the MERGE algorithm works.

The examples assume that there is a view v_merge that has this definition: CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS SELECT c1, c2 FROM t WHERE c3 > 100; Example 1: Suppose that we issue this statement: SELECT * FROM v_merge; MySQL handles the statement as follows: 133 | P a g e

v_merge becomes t * becomes vc1, vc2, which corresponds to c1, c2 The view WHERE clause is added

The resulting statement to be executed becomes: SELECT c1, c2 FROM t WHERE c3 > 100; Example 2: Suppose that we issue this statement: SELECT * FROM v_merge WHERE vc1 < 100; This statement is handled similarly to the previous one, except that vc1 < 100 becomes c1 < 100 and the view WHERE clause is added to the statement WHERE clause using an AND connective (and parentheses are added to make sure the parts of the clause are executed with correct precedence). The resulting statement to be executed becomes: SELECT c1, c2 FROM t WHERE (c3 > 100) AND (c1 < 100); Effectively, the statement to be executed has a WHERE clause of this form: WHERE (select WHERE) AND (view WHERE) The MERGE algorithm requires a one-to-one relationship between the rows in the view and the rows in the underlying table. If this relationship does not hold, a temporary table must be used instead. Lack of a one-to-one relationship occurs if the view contains any of a number of constructs:

Aggregate functions (SUM(), MIN(), MAX(), COUNT(), and so forth) DISTINCT GROUP BY HAVING UNION or UNION ALL Subquery in the select list Refers only to literal values (in this case, there is no underlying table)

Some views are updatable. That is, you can use them in statements such as UPDATE, DELETE, or INSERT to update the contents of the underlying table. For a view to be updatable there must be a one-toone relationship between the rows in the view and the rows in the underlying table. There are also certain other constructs that make a view non-updatable. To be more specific, a view is not updatable if it contains any of the following

134 | P a g e

Aggregate functions (SUM(), MIN(), MAX(), COUNT(), and so forth) DISTINCT GROUP BY HAVING UNION or UNION ALL Subquery in the select list Certain joins (see additional join discussion later in this section) Non-updatable view in the FROM clause A subquery in the WHERE clause that refers to a table in the FROM clause Refers only to literal values (in this case, there is no underlying table to update) ALGORITHM = TEMPTABLE (use of a temporary table always makes a view non-updatable)

With respect to insertability (being updatable with INSERT statements), an updatable view is insertable if it also satisfies these additional requirements for the view columns: There must be no duplicate view column names.

The view must contain all columns in the base table that do not have a default value. The view columns must be simple column references and not derived columns. A derived column is one that is not a simple column reference but is derived from an expression. These are examples of derived columns: 3.14159 col1 + 3 UPPER(col2) col3 / col4 (subquery)

A view that has a mix of simple column references and derived columns is not insertable, but it can be updatable if you update only those columns that are not derived. Consider this view: CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t; This view is not insertable because col2 is derived from an expression. But it is updatable if the update does not try to update col2. This update is allowable: UPDATE v SET col1 = 0;

135 | P a g e

This update is not allowable because it attempts to update a derived column: UPDATE v SET col2 = 0; It is sometimes possible for a multiple-table view to be updatable, assuming that it can be processed with the MERGE algorithm. For this to work, the view must use an inner join (not an outer join or a UNION). Also, only a single table in the view definition can be updated, so the SET clause must name only columns from one of the tables in the view. Views that use UNION ALL are disallowed even though they might be theoretically updatable, because the implementation uses temporary tables to process them. For a multiple-table updatable view, INSERT can work if it inserts into a single table. DELETE is not supported. INSERT DELAYED is not supported for views. If a table contains an AUTO_INCREMENT column, inserting into an insertable view on the table that does not include the AUTO_INCREMENT column does not change the value of LAST_INSERT_ID(), because the side effects of inserting default values into columns not part of the view should not be visible. The WITH CHECK OPTION clause can be given for an updatable view to prevent inserts or updates to rows except those for which the WHERE clause in the select_statement is true. In a WITH CHECK OPTION clause for an updatable view, the LOCAL and CASCADED keywords determine the scope of check testing when the view is defined in terms of another view. The LOCAL keyword restricts the CHECK OPTION only to the view being defined. CASCADED causes the checks for underlying views to be evaluated as well. When neither keyword is given, the default is CASCADED. Consider the definitions for the following table and set of views: mysql> CREATE TABLE t1 (a INT); mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2 -> WITH CHECK OPTION; mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0 -> WITH LOCAL CHECK OPTION; mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0 -> WITH CASCADED CHECK OPTION; Here the v2 and v3 views are defined in terms of another view, v1. v2 has a LOCAL check option, so inserts are tested only against the v2 136 | P a g e

check. v3 has a CASCADED check option, so inserts are tested not only against its own check, but against those of underlying views. The following statements illustrate these differences: mysql> INSERT INTO v2 VALUES (2); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO v3 VALUES (2); MORE EXAMPLES: mysql> mysql> mysql> mysql> CREATE TABLE Employee( -> id int, -> first_name VARCHAR(15), -> last_name VARCHAR(15), -> start_date DATE, -> end_date DATE, -> salary FLOAT(8,2), -> city VARCHAR(10), -> description VARCHAR(15) -> ); Query OK, 0 rows affected (0.02 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(1,'Jason','Martin','19960725','20060725 ', 1234.56,'Toronto','Programmer); Query OK, 1 row affected (0.00 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(2,'Alison',Mathews',19760321','198602 21', 6661.78,'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(3,'James','Smith',19781212',19900315' , 6544.78,'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(4,'Celia','Rice','19821024','19990421', 2344.78,'Vancouver','Manager'); 137 | P a g e

Query OK, 1 row affected (0.00 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(5,'Robert','Black','19840115','19980808 ', 2334.78,'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(6,'Linda','Green','19870730','19960104' , 4322.78,'New York','Tester'); Query OK, 1 row affected (0.00 sec) mysql> insert into Employee(id,first_name,last_name,start_date,end_Dat e, salary,City,Description)values(7,'David','Larry','19901231',19980212' , 7897.78,'New York','Manager'); Query OK, 1 row affected (0.00 sec) mysql>insert into Employee(id,first_name,last_name,start_date,end_Date , salary,City,Description)values(8,'James',Cat','19960917',20020415',1 232.78, 'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec)

mysql> select * from Employee; +------+------------+-----------+------------+------------+---------+----------+-------------+ | id | first_name | last_name | start_date | end_date | salary | city | description | +------+------------+-----------+------------+------------+---------+----------+-------------+ | 1 | Jason | Martin | 1996-07-25 | 2006-0725 | 1234.56 | Toronto | Programmer | | 2 | Alison | Mathews | 1976-03-21 | 1986-0221 | 6661.78 | Vancouver | Tester | | 3 | James | Smith | 1978-12-12 | 1990-0315 | 6544.78 | Vancouver | Tester | | 4 | Celia | Rice | 1982-10-24 | 1999-0421 | 2344.78 | Vancouver | Manager | | 5 | Robert | Black | 1984-01-15 | 1998-0808 | 2334.78 | Vancouver | Tester | | 6 | Linda | Green | 1987-07-30 | 1996-0104 | 4322.78 | New York | Tester | | 7 | David | Larry | 1990-12-31 | 1998-02138 | P a g e

12 | 7897.78 | New York | Manager | | 8 | James | Cat | 1996-09-17 | 2002-0415 | 1232.78 | Vancouver | Tester | +------+------------+-----------+------------+------------+---------+----------+-------------+ 8 rows in set (0.00 sec) mysql> CREATE VIEW myView AS -> SELECT id, first_name FROM employee WHERE id = 1; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM myView; +------+------------+ | id | first_name | +------+------------+ | 1 | Jason | +------+------------+ 1 row in set (0.02 sec) mysql> drop view myView; Query OK, 0 rows affected (0.00 sec) mysql> drop table Employee; Query OK, 0 rows affected (0.00 sec) Creating a View with Specified Column Names mysql> mysql> mysql> CREATE TABLE Employee( -> id int, -> first_name VARCHAR(15), -> last_name VARCHAR(15), -> start_date DATE, -> end_date DATE, -> salary FLOAT(8,2), -> city VARCHAR(10), -> description VARCHAR(15) -> ); Query OK, 0 rows affected (0.03 sec) mysql> mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) 139 | P a g e

values (1,'Jason',

'Martin',

'19960725', '20060725', 1234.56,

'Toronto', 'Programmer'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) > values(2,'Alison', 'Mathews', '19760321', '19860221', 6661.78, 'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) >values(3,'James', 'Smith', '19781212', '19900315', 6544.78, ' Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) > values(4,'Celia', 'Rice', '19821024', '19990421', 2344.78, 'Vancouver','Manager'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) > values(5,'Robert', 'Black', '19840115', '199808 08', 2334.78, 'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) > values(6,'Linda', 'Green', '19870730', '199601 04', 4322.78,'New York', 'Tester'); Query OK, 1 row affected (0.00 sec)

140 | P a g e

mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) > values(7,'David', 'Larry', '19901231', '199802 12', 7897.78,'New York', 'Manager'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, en d_Date, salary, City, Description) > values(8,'James', 'Cat', '19960917', '20020415', 1232.78,' Vancouver', 'Tester'); Query OK, 1 row affected (0.00 sec) mysql> mysql> select * from Employee; +------+------------+-----------+------------+------------+--------+-----------+-------------+ | id | first_name | last_name | start_date | end_date | salary | city | description | +------+------------+-----------+------------+------------+--------+-----------+-------------+ | 1 | Jason | Martin | 1996-07-25 | 2006-0725 | 1234.56 | Toronto | Programmer | | 2 | Alison | Mathews | 1976-03-21 | 1986-0221 | 6661.78 | Vancouver | Tester | | 3 | James | Smith | 1978-12-12 | 1990-0315 | 6544.78 | Vancouver | Tester | | 4 | Celia | Rice | 1982-10-24 | 1999-0421 | 2344.78 | Vancouver | Manager | | 5 | Robert | Black | 1984-01-15 | 1998-0808 | 2334.78 | Vancouver | Tester | | 6 | Linda | Green | 1987-07-30 | 1996-0104 | 4322.78 | New York | Tester | | 7 | David | Larry | 1990-12-31 | 1998-0212 | 7897.78 | New York | Manager | | 8 | James | Cat | 1996-09-17 | 2002-0415 | 1232.78 | Vancouver | Tester | +------+------------+-----------+------------+------------+--------+-----------+-------------+ 8 rows in set (0.00 sec)

141 | P a g e

mysql> mysql> mysql> mysql> mysql> CREATE VIEW myView (vid, vfirstname) AS -> SELECT id, first_name FROM employee WHERE id = 1; Query OK, 0 rows affected (0.00 sec) mysql> mysql> mysql> SELECT * FROM myView; +------+------------+ | vid | vfirstname | +------+------------+ | 1 | Jason | +------+------------+ 1 row in set (0.01 sec) mysql> mysql> mysql> drop view myView; Query OK, 0 rows affected (0.00 sec) mysql> mysql> mysql> mysql> mysql> drop table Employee; Query OK, 0 rows affected (0.00 sec)

142 | P a g e

TRIGGERS

1. CREATE TRIGGER Syntax 2. DROP TRIGGER Syntax 3. Using Triggers

1.CREATE TRIGGER Syntax CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt This statement creates a new trigger. A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. The trigger becomes associated with the table named tbl_name, which must refer to a permanent table. You cannot associate a trigger with a TEMPORARY table or a view. MySQL Enterprise For expert advice on creating triggers subscribe to the MySQL Enterprise Monitor. For more information, see http://www.mysql.com/products/enterprise/advisors.html. The DEFINER clause determines the security context to be used when checking access privileges at trigger activation time. trigger_time is the trigger action time. It can be BEFORE or AFTER to indicate that the trigger activates before or after each row to be modified. trigger_event indicates the kind of statement that activates the trigger. The trigger_event can be one of the following:

INSERT: The trigger is activated whenever a new row is inserted into the table; for example, through INSERT, LOAD DATA, and REPLACE statements. UPDATE: The trigger is activated whenever a row is modified; for example, through UPDATE statements. DELETE: The trigger is activated whenever a row is deleted from the table; for example, through DELETE and REPLACE statements. However, DROP TABLE and TRUNCATE statements on the table do not activate this trigger, because they do not use DELETE. It is important to understand that the trigger_event does not represent a literal type of SQL statement that activates the trigger

143 | P a g e

so much as it represents a type of table operation. For example, an INSERT trigger is activated by not only INSERT statements but also LOAD DATA statements because both statements insert rows into a table. A potentially confusing example of this is the INSERT INTO ... ON DUPLICATE KEY UPDATE ... syntax: a BEFORE INSERT trigger will activate for every row, followed by either an AFTER INSERT trigger or both the BEFORE UPDATE and AFTER UPDATE triggers, depending on whether there was a duplicate key for the row. There cannot be two triggers for a given table that have the same trigger action time and event. For example, you cannot have two BEFORE UPDATE triggers for a table. But you can have a BEFORE UPDATE and a BEFORE INSERT trigger, or a BEFORE UPDATE and an AFTER UPDATE trigger. trigger_stmt is the statement to execute when the trigger activates. If you want to execute multiple statements, use the BEGIN ... END compound statement construct. This also enables you to use the same statements that are allowable within stored routines.. MySQL stores the sql_mode system variable setting that is in effect at the time a trigger is created, and always executes the trigger with this setting in force, regardless of the current server SQL mode. you can write triggers such as the one named testref shown in this example: CREATE TABLE test1(a1 INT); CREATE TABLE test2(a2 INT); CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY); CREATE TABLE test4( a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b4 INT DEFAULT 0 );

DELIMITER |

CREATE TRIGGER testref BEFORE INSERT ON test1 FOR EACH ROW BEGIN

144 | P a g e

INSERT INTO test2 SET a2 = NEW.a1; DELETE FROM test3 WHERE a3 = NEW.a1; UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1; END; |

DELIMITER ;

INSERT INTO test3 (a3) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);

INSERT INTO test4 (a4) VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0); Suppose that you insert the following values into table test1 as shown here: mysql> INSERT INTO test1 VALUES -> (1), (3), (1), (7), (1), (8), (4), (4); Query OK, 8 rows affected (0.01 sec) Records: 8 Duplicates: 0 Warnings: 0 As a result, the data in the four tables will be as follows:

145 | P a g e

mysql> SELECT * FROM test1; +------+ | a1 | +------+ | 1 | | 3 | | 1 | | 7 | | 1 | | 8 | | 4 | | 4 | +------+ 8 rows in set (0.00 sec)

mysql> SELECT * FROM test2; +------+ | a2 | +------+ | 1 | | 3 | | 1 | | 7 | | 1 |

146 | P a g e

| 8 | | 4 | | 4 | +------+ 8 rows in set (0.00 sec)

mysql> SELECT * FROM test3; +----+ | a3 | +----+ | 2 | | 5 | | 6 | | 9 | | 10 | +----+ 5 rows in set (0.00 sec)

mysql> SELECT * FROM test4; +----+------+ | a4 | b4 | +----+------+ | 1 | 3 | | 2 | 0 |

147 | P a g e

| 3 | 1 | | 4 | 2 | | 5 | 0 | | 6 | 0 | | 7 | 1 | | 8 | 1 | | 9 | 0 | | 10 | 0 | +----+------+ 10 rows in set (0.00 sec) You can refer to columns in the subject table (the table associated with the trigger) by using the aliases OLD and NEW. OLD.col_name refers to a column of an existing row before it is updated or deleted. NEW.col_name refers to the column of a new row to be inserted or an existing row after it is updated. The DEFINER clause specifies the MySQL account to be used when checking access privileges at trigger activation time. If a user value is given, it should be a MySQL account in 'user_name'@'host_name' format (the same format used in the GRANT statement). The user_name and host_name values both are required. The definer can also be given as CURRENT_USER or CURRENT_USER(). The default DEFINER value is the user who executes the CREATE TRIGGER statement. (This is the same as DEFINER = CURRENT_USER.) If you specify the DEFINER clause, these rules determine the legal DEFINER user values:

If you do not have the SUPER privilege, the only legal user value is your own account, either specified literally or by using CURRENT_USER. You cannot set the definer to some other account. If you have the SUPER privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated.

Although it is possible to create triggers with a non-existent DEFINER value, it is not a good idea for such triggers to be activated until the definer actually does exist. Otherwise, the behavior with respect to privilege checking is undefined. Note: Because MySQL currently requires the SUPER privilege for the use of CREATE TRIGGER, only the second of the preceding rules applies. 148 | P a g e

(MySQL 5.1.6 implements the TRIGGER privilege and requires that privilege for trigger creation, so at that point both rules come into play and SUPER is required only for specifying a DEFINER value other than your own account.) From MySQL checks trigger privileges like this:

At CREATE TRIGGER time, the user that issues the statement must have the SUPER privilege. At trigger activation time, privileges are checked against the DEFINER user. This user must have these privileges: o The SUPER privilege. o The SELECT privilege for the subject table if references to table columns occur via OLD.col_name or NEW.col_name in the trigger definition. o The UPDATE privilege for the subject table if table columns are targets of SET NEW.col_name = value assignments in the trigger definition. o Whatever other privileges normally are required for the statements executed by the trigger. At CREATE TRIGGER time, the user that issues the statement must have the SUPER privilege.

At trigger activation time, privileges are checked against the user whose actions cause the trigger to be activated. This user must have whatever privileges normally are required for the statements executed by the trigger.

2. DROP TRIGGER Syntax DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name This statement drops a trigger. The schema (database) name is optional. If the schema is omitted, the trigger is dropped from the default schema. DROP TRIGGER was added in MySQL 5.0.2. Its use requires the SUPER privilege. Use IF EXISTS to prevent an error from occurring for a trigger that does not exist. Triggers for a table are also dropped if you drop the table. 3. Using Triggers Support for triggers is included beginning with MySQL. This section discusses how to use triggers and some limitations regarding their use.. A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. Some 149 | P a g e

uses for triggers are to perform checks of values to be inserted into a table or to perform calculations on values involved in an update. A trigger is associated with a table and is defined to activate when an INSERT, DELETE, or UPDATE statement for the table executes. A trigger can be set to activate either before or after the triggering statement. For example, you can have a trigger activate before each row that is deleted from a table or after each row that is updated. Important MySQL triggers are activated by SQL statements only. They are not activated by changes in tables made by APIs that do not transmit SQL statements to the MySQL Server; in particular, they are not activated by updates made using the NDB API. Here is a simple example that associates a trigger with a table for INSERT statements. It acts as an accumulator to sum the values inserted into one of the columns of the table. The following statements create a table and a trigger for it: mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2)); mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account -> FOR EACH ROW SET @sum = @sum + NEW.amount; The CREATE TRIGGER statement creates a trigger named ins_sum that is associated with the account table. It also includes clauses that specify the trigger activation time, the triggering event, and what to do with the trigger activates:

The keyword BEFORE indicates the trigger action time. In this case, the trigger should activate before each row inserted into the table. The other allowable keyword here is AFTER. The keyword INSERT indicates the event that activates the trigger. In the example, INSERT statements cause trigger activation. You can also create triggers for DELETE and UPDATE statements. The statement following FOR EACH ROW defines the statement to execute each time the trigger activates, which occurs once for each row affected by the triggering statement In the example, the triggered statement is a simple SET that accumulates the values inserted into the amount column. The statement refers to the column as NEW.amount which means the value of the amount column to be inserted into the new row.

To use the trigger, set the accumulator variable to zero, execute an INSERT statement, and then see what value the variable has afterward: mysql> SET @sum = 0;

150 | P a g e

mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,100.00); mysql> SELECT @sum AS 'Total amount inserted'; +-----------------------+ | Total amount inserted | +-----------------------+ | 1852.48 | +-----------------------+ In this case, the value of @sum after the INSERT statement has executed is 14.98 + 1937.50 - 100, or 1852.48. To destroy the trigger, use a DROP TRIGGER statement. You must specify the schema name if the trigger is not in the default schema: mysql> DROP TRIGGER test.ins_sum; Triggers for a table are also dropped if you drop the table. Trigger names exist in the schema namespace, meaning that all triggers must have unique names within a schema. Triggers in different schemas can have the same name. In addition to the requirement that trigger names be unique for a schema, there are other limitations on the types of triggers you can create. In particular, you cannot have two triggers for a table that have the same activation time and activation event. For example, you cannot define two BEFORE INSERT triggers or two AFTER UPDATE triggers for a table. This should rarely be a significant limitation, because it is possible to define a trigger that executes multiple statements by using the BEGIN ... END compound statement construct after FOR EACH ROW. (An example appears later in this section.) The OLD and NEW keywords enable you to access columns in the rows affected by a trigger. (OLD and NEW are not case sensitive.) In an INSERT trigger, only NEW.col_name can be used; there is no old row. In a DELETE trigger, only OLD.col_name can be used; there is no new row. In an UPDATE trigger, you can use OLD.col_name to refer to the columns of a row before it is updated and NEW.col_name to refer to the columns of the row after it is updated. A column named with OLD is read only. You can refer to it (if you have the SELECT privilege), but not modify it. A column named with NEW can be referred to if you have the SELECT privilege for it. In a BEFORE trigger, you can also change its value with SET NEW.col_name = value if you have the UPDATE privilege for it. This means you can use a

151 | P a g e

trigger to modify the values to be inserted into a new row or that are used to update a row. In a BEFORE trigger, the NEW value for an AUTO_INCREMENT column is 0, not the automatically generated sequence number that will be generated when the new record actually is inserted. OLD and NEW are MySQL extensions to triggers. By using the BEGIN ... END construct, you can define a trigger that executes multiple statements. Within the BEGIN block, you also can use other syntax that is allowed within stored routines such as conditionals and loops. However, just as for stored routines, if you use the mysql program to define a trigger that executes multiple statements, it is necessary to redefine the mysql statement delimiter so that you can use the ; statement delimiter within the trigger definition. The following example illustrates these points. It defines an UPDATE trigger that checks the new value to be used for updating each row, and modifies the value to be within the range from 0 to 100. This must be a BEFORE trigger because the value needs to be checked before it is used to update the row: mysql> delimiter // mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account -> FOR EACH ROW -> BEGIN -> IF NEW.amount < 0 THEN -> SET NEW.amount = 0; -> ELSEIF NEW.amount > 100 THEN -> SET NEW.amount = 100; -> END IF; -> END;// mysql> delimiter ; It can be easier to define a stored procedure separately and then invoke it from the trigger using a simple CALL statement. This is also advantageous if you want to invoke the same routine from within several triggers. There are some limitations on what can appear in statements that a trigger executes when activated:

152 | P a g e

The trigger cannot use the CALL statement to invoke stored procedures that return data to the client or that use dynamic SQL. (Stored procedures are allowed to return data to the trigger through OUT or INOUT parameters.) The trigger cannot use statements that explicitly or implicitly begin or end a transaction such as START TRANSACTION, COMMIT, or ROLLBACK.

MySQL handles errors during trigger execution as follows:


If a BEFORE trigger fails, the operation on the corresponding row is not performed. A BEFORE trigger is activated by the attempt to insert or modify the row, regardless of whether the attempt subsequently succeeds. An AFTER trigger is executed only if the BEFORE trigger (if any) and the row operation both execute successfully. An error during either a BEFORE or AFTER trigger results in failure of the entire statement that caused trigger invocation. For transactional tables, failure of a statement should cause rollback of all changes performed by the statement. Failure of a trigger causes the statement to fail, so trigger failure also causes rollback. For non-transactional tables, such rollback cannot be done, so although the statement fails, any changes performed prior to the point of the error remain in effect.

153 | P a g e

Cursors

1. Declaring Cursors 2. Cursor OPEN Statement 3. Cursor FETCH Statement 4. Cursor CLOSE Statement Cursors are supported inside stored procedures and functions and triggers. The syntax is as in embedded SQL. Cursors currently have these properties:

Asensitive: The server may or may not make a copy of its result table Read only: Not updatable Non-scrollable: Can be traversed only in one direction and cannot skip rows

Cursors must be declared before declaring handlers. Variables and conditions must be declared before declaring either cursors or handlers. Example: CREATE PROCEDURE curdemo() BEGIN DECLARE done INT DEFAULT 0; DECLARE a CHAR (16); DECLARE b,c INT; DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; OPEN cur2; REPEAT 154 | P a g e

FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF NOT done THEN IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END IF; UNTIL done END REPEAT;

CLOSE cur1; CLOSE cur2; END 1. Declaring Cursors DECLARE cursor_name CURSOR FOR select_statement This statement declares a cursor. Multiple cursors may be declared in a routine, but each cursor in a given block must have a unique name. The SELECT statement cannot have an INTO clause. 2. Cursor OPEN Statement OPEN cursor_name This statement opens a previously declared cursor. 3. Cursor FETCH Statement FETCH cursor_name INTO var_name [, var_name] ... This statement fetches the next row (if a row exists) using the specified open cursor, and advances the cursor pointer. 155 | P a g e

If no more rows are available, a No Data condition occurs with SQLSTATE value 02000. To detect this condition, you can set up a handler for it (or for a NOT FOUND condition). 4. Cursor CLOSE Statement CLOSE cursor_name This statement closes a previously opened cursor. If not closed explicitly, a cursor is closed at the end of the compound statement in which it was declared.

Closing the cursor removes the pointer from the data.

mysql> mysql> CREATE TABLE Employee( -> id int, -> first_name VARCHAR(15), -> last_name VARCHAR(15), -> start_date DATE, -> end_date DATE, -> salary FLOAT(8,2), -> city VARCHAR(10), -> description VARCHAR(15) -> ); Query OK, 0 rows affected (0.03 sec) mysql> mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description) > values (1,'Jason', 'Martin', '19960725', '20060725', 1234 .56, 'Toronto', 'Programmer'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_Date,salary, City, Description)->values(2,'Alison', '19760321','19860221', 6661.78, 'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_ Date, salary, City, Description) 'Mathews',

156 | P a g e

> values(3,'James', ', 6544.78, 'Vancouver','Tester'); Query OK, 1 row affected (0.00 sec)

'Smith',

'19781212', '19900315

mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_ Date, salary, City, Description)-> values(4,'Celia', 'Rice', '19821024', '19990421', 2344.78, 'Vancouver','Manager'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, s alary, City, Description) > values(5,'Robert', 'Black', '19840115', '19980808', 2334.7 8, 'Vancouver','Tester'); Query OK, 1 row affected (0.01 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, s alary, City, Description) > values(6,'Linda', 'Green', '19870730', '19960104', 4322.7 8,'New York', 'Tester'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, s alary, City, Description) > values(7,'David', 'Larry', '19901231', '19980212', 7897.7 8,'New York', 'Manager'); Query OK, 1 row affected (0.00 sec) mysql> mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, s alary, City, Description) > values(8,'James', 'Cat', '19960917', '20020415', 1232.7 8,'Vancouver', 'Tester'); Query OK, 1 row affected (0.02 sec) mysql> mysql> select * from Employee;
+------+------------+-----------+------------+------------+---------+-----------+-------------+ | id | first_name | last_name | start_date | end_date | salary | city | description | +------+------------+-----------+------------+------------+---------+-----------+-------------+ | 1 | Jason | Martin | 1996-07-25 | 2006-07-25 | 1234.56 | Toronto | Programmer | | 2 | Alison | Mathews | 1976-03-21 | 1986-02-21 | 6661.78 | Vancouver | Tester | | 3 | James | Smith | 1978-12-12 | 1990-03-15 | 6544.78 | Vancouver | Tester | | 4 | Celia | Rice | 1982-10-24 | 1999-04-21 | 2344.78 | Vancouver | Manager | | 5 | Robert | Black | 1984-01-15 | 1998-08-08 | 2334.78 | Vancouver | Tester | | 6 | Linda | Green | 1987-07-30 | 1996-01-04 | 4322.78 | New York | Tester | | 7 | David | Larry | 1990-12-31 | 1998-02-12 | 7897.78 | New York | Manager | | 8 | James | Cat | 1996-09-17 | 2002-04-15 | 1232.78 | Vancouver | Tester | +------+------------+-----------+------------+------------+---------+-----------+-------------+

8 rows in set (0.00 sec)

157 | P a g e

mysql> mysql> mysql> mysql> mysql> DELIMITER // mysql> CREATE FUNCTION city_list() RETURNS VARCHAR(255) -> BEGIN -> -> DECLARE finished INTEGER DEFAULT 0; -> DECLARE city_name VARCHAR(50) DEFAULT ""; -> DECLARE list VARCHAR(255) DEFAULT ""; -> DECLARE city_cur CURSOR FOR SELECT city FROM employee; -> DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; -> -> OPEN city_cur; -> -> get_city: LOOP -> FETCH city_cur INTO city_name; -> IF finished THEN -> LEAVE get_city; -> END IF; -> SET list = CONCAT(list,", ",city_name); -> END LOOP get_city; -> -> CLOSE city_cur; -> -> RETURN SUBSTR(list,3); -> END -> // Query OK, 0 rows affected (0.00 sec) mysql> DELIMITER ; mysql> mysql> SELECT city_list() AS cities;
+------------------------------------------------------------------------------------+ | cities | +------------------------------------------------------------------------------------+ | Toronto, Vancouver, Vancouver, Vancouver, Vancouver, New York, New York, Vancouver | +------------------------------------------------------------------------------------+

1 row in set (0.00 sec) mysql> mysql> drop function city_list; Query OK, 0 rows affected (0.00 sec) mysql> mysql> mysql> mysql> drop table Employee; Query OK, 0 rows affected (0.01 sec)

158 | P a g e