Vous êtes sur la page 1sur 460

Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
MySQL for Developers
Activity Guide
D61830GC40
Edition 4.0 | June 2016 | D96434

Learn more from Oracle University at oracle.com/education/


Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Disclaimer

This document contains proprietary information and is protected by copyright and other intellectual property laws. You may copy and
print this document solely for your own use in an Oracle training course. The document may not be modified or altered in any way.
Except where your use constitutes "fair use" under copyright law, you may not use, share, download, upload, copy, print, display,
perform, reproduce, publish, license, post, transmit, or distribute this document in whole or in part without the express authorization
of Oracle.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

The information contained in this document is subject to change without notice. If you find any problems in the document, please
report them in writing to: Oracle University, 500 Oracle Parkway, Redwood Shores, California 94065 USA. This document is not
warranted to be error-free.

Restricted Rights Notice

If this documentation is delivered to the United States Government or anyone using the documentation on behalf of the United
States Government, the following notice is applicable:

U.S. GOVERNMENT RIGHTS


The U.S. Government’s rights to use, modify, reproduce, release, perform, display, or disclose these training materials are restricted
ble
by the terms of the applicable Oracle license agreement and/or the applicable U.S. Government contract.
fe r a
Trademark Notice
t r a ns
o n
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their
-
respective
owners.
s an
r ) ha ฺ
Author
m ฺb uide
Mark Lewin
a r ฺco nt G
o n ep tude
Technical Contributors and Reviewers
@ s is S
c i
c Bester, thFilipe Silva, Nuno Mariz, Johannes Schlüter,
Kathy Forte, Anthony Skrabak, r i Shane e
Jonathon Coombes
e r toฺ to us
i ( r ob nse
This book c
i c was published
l i ce using: Oracle Tutor
t o R
r
R obe
Table of Contents
Practices for Lesson 1: Introduction to MySQL ............................................................................................1-1
Practices for Lesson 1: Introduction to MySQL ..............................................................................................1-2
Practice 1-1: Course Environment Overview .................................................................................................1-3
Solution 1-1: Course Environment Overview .................................................................................................1-13
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Practices for Lesson 2: MySQL Connectors and APIs .................................................................................2-1


Practices for Lesson 2: MySQL Connectors and APIs ...................................................................................2-2
Practice 2-1: Quiz — MySQL Connectors and APIs ......................................................................................2-3
Solution 2-1: Quiz — MySQL Connectors and APIs ......................................................................................2-4
Practices for Lesson 3: Using Connectors ....................................................................................................3-1
Practices for Lesson 3: Using Connectors .....................................................................................................3-2
Practice 3-1: Connecting to the MySQL Server in a Web Environment with PHP/PDO .................................3-4
Solution 3-1: Connecting to the MySQL Server in a Web Environment with PHP/PDO .................................3-6
ble
Practice 3-2: Connecting to the MySQL Server in a Web Environment with Connector/J ..............................3-9
fe r a
Solution 3-2: Connecting to the MySQL Server in a Web Environment with Connector/J ..............................3-11
an s
Practice 3-3: Connecting to the MySQL Server in a Web Environment Using Connector/Python ..................3-16
n - t r
Solution 3-3: Connecting to the MySQL Server in a Web Environment Using Connector/Python ..................3-18
a no
h a s
Practice 3-4: Executing SQL in a Web Environment with PHP/PDO..............................................................3-23

ฺ b r) deฺ
Solution 3-4: Executing SQL in a Web Environment with PHP/PDO..............................................................3-25

c o m Gui
Practice 3-5: Executing SQL in a Web Environment with Connector/J ..........................................................3-30

p a rฺ ent
Solution 3-5: Executing SQL in a Web Environment with Connector/J ..........................................................3-32
Practice 3-6: Executing SQL in a Web Environment with Connector/Python .................................................3-37
one s Stud
Solution 3-6: Executing SQL in a Web Environment with Connector/Python .................................................3-40
s
Practices for Lesson 4: Prepared Statements
i c
Practices for Lesson 4: PreparedrStatements e thi
ci@................................................................................................4-2
...............................................................................................4-1

r toฺ intMySQL
o us...............................................................................................4-3
e
Practice 4-1: Preparing Statements
b Statements
i ( roPrepared
Solution 4-1: Preparing
e n sein MySQL...............................................................................................4-4
i c c
Practice 4-2: Using
l i c Statements with PHP/PDO..............................................................................4-6

t o R 4-2: Using Prepared Statements with PHP/PDO..............................................................................4-8


Solution
r
obe Solution 4-3: Using Prepared Statements with Connector/J ..........................................................................4-17
Practice 4-3: Using Prepared Statements with Connector/J ..........................................................................4-15

R Practice 4-4: Using Prepared Statements with Connector/Python .................................................................4-23


Solution 4-4: Using Prepared Statements with Connector/Python .................................................................4-25
Practices for Lesson 5: Handling Errors and Warnings ...............................................................................5-1
Practices for Lesson 5: Handling Errors and Warnings ..................................................................................5-2
Practice 5-1: Quiz – Handling Errors ..............................................................................................................5-3
Solution 5-1: Quiz – Handling Errors ..............................................................................................................5-4
Practice 5-2: Identifying Errors and Warnings with the mysql Command Line Client .....................................5-5
Solution 5-2: Identifying Errors and Warnings with the mysql Command Line Client .....................................5-6
Practice 5-3: Handling Errors and Warnings When Coding with PHP/PDO ...................................................5-8
Solution 5-3: Handling Errors and Warnings When Coding with PHP/PDO ...................................................5-9
Practice 5-4: Handling Errors and Warnings When Coding with Connector/J ................................................5-14
Solution 5-4: Handling Errors and Warnings When Coding with Connector/J ................................................5-15
Practice 5-5: Handling Errors and Warnings When Coding with Connector/Python.......................................5-21
Solution 5-5: Handling Errors and Warnings When Coding with Connector/Python.......................................5-22

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

MySQL for Developers Table of Contents


iii
Practices for Lesson 6: Building Database-Driven Web Applications ........................................................6-1
Practices for Lesson 6: Building Database-Driven Web Applications.............................................................6-2
Practice 6-1: Displaying Query Results in a Table Using PHP/PDO ..............................................................6-3
Solution 6-1: Displaying Query Results in a Table Using PHP/PDO ..............................................................6-4
Practice 6-2: Displaying Query Results in a Table Using Java/JSP ...............................................................6-8
Solution 6-2: Displaying Query Results in a Table Using Java/JSP ...............................................................6-9
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Practice 6-3: Displaying Query Results in a Table Using Python ...................................................................6-13


Solution 6-3: Displaying Query Results in a Table Using Python ...................................................................6-14
Practice 6-4: Paging Query Results Using PHP/PDO ....................................................................................6-19
Solution 6-4: Paging Query Results Using PHP/PDO ....................................................................................6-21
Practice 6-5: Paging Query Results Using Java/JSP .....................................................................................6-26
Solution 6-5: Paging Query Results Using Java/JSP .....................................................................................6-28
Practice 6-6: Paging Query Results Using Python .........................................................................................6-33
Solution 6-6: Paging Query Results Using Python .........................................................................................6-35
ble
Practice 6-7: Enabling Sorting of Query Results Using PHP/PDO .................................................................6-40
fe r a
Solution 6-7: Enabling Sorting of Query Results Using PHP/PDO .................................................................6-41
an s
Practice 6-8: Enabling Sorting of Query Results Using Java/JSP ..................................................................6-45
Solution 6-8: Enabling Sorting of Query Results Using Java/JSP ..................................................................6-46 n - t r
a no
Practice 6-9: Enabling Sorting of Query Results Using Python ......................................................................6-50
a s
Solution 6-9: Enabling Sorting of Query Results Using Python ......................................................................6-51
h
ฺ b r) deฺ
Practices for Lesson 7: Tables and Views .....................................................................................................7-1

o m Gui
Practices for Lesson 7: Tables and Views .....................................................................................................7-2
c
a rฺ ent
Practice 7-1: Creating New Tables from Existing Tables ...............................................................................7-3
p
one s Stud
Solution 7-1: Creating New Tables from Existing Tables ...............................................................................7-4
s
Practice 7-2: Creating a View .........................................................................................................................7-7
c i@ thi
Solution 7-2: Creating a View .........................................................................................................................7-8
c
o ฺ r i u se
Practice 7-3: Updating a View ........................................................................................................................7-10
t
r ........................................................................................................................7-11
Solution 7-3: Updating aeView to
b
ro a View s e
c (
Practice 7-4: Checking
i c e n .......................................................................................................................7-14
7-4: Checkinglia View .......................................................................................................................7-15
Solution c
R i 7-5:
o 7-5: Obtaining
Practice
ertSolution
Obtaining View Metadata ..........................................................................................................7-16

b View Metadata ..........................................................................................................7-17


Ro Practice 7-6: Additional Practice ....................................................................................................................7-19
Solution 7-6: Additional Practice ....................................................................................................................7-20
Practices for Lesson 8: Working with Strings ...............................................................................................8-1
Practices for Lesson 8: Working with Strings .................................................................................................8-2
Practice 8-1: Manipulating String Data With MySQL Expressions .................................................................8-3
Solution 8-1: Manipulating String Data With MySQL Expressions .................................................................8-4
Practice 8-2: Matching Patterns in Strings .....................................................................................................8-8
Solution 8-2: Matching Patterns in Strings .....................................................................................................8-9
Practice 8-3: Using Full-Text Searches ..........................................................................................................8-13
Solution 8-3: Using Full-Text Searches ..........................................................................................................8-14
Practices for Lesson 9: Working with Numeric and Temporal Data ............................................................9-1
Practices for Lesson 9: Working with Numeric and Temporal Data ...............................................................9-2
Practice 9-1: Using Numeric Data in SQL Expressions..................................................................................9-3
Solution 9-1: Using Numeric Data in SQL Expressions..................................................................................9-4
Practice 9-2: Using Temporal Data in SQL Expressions ................................................................................9-8
Solution 9-2: Using Temporal Data in SQL Expressions ................................................................................9-9

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

MySQL for Developers Table of Contents


iv
Practices for Lesson 10: Subqueries .............................................................................................................10-1
Practices for Lesson 10: Subqueries..............................................................................................................10-2
Practice 10-1: Quiz – Subqueries...................................................................................................................10-3
Solution 10-1: Quiz–Subqueries ....................................................................................................................10-4
Practice 10-2: Using Subqueries in the SELECT and FROM Clauses ...........................................................10-5
Solution 10-2: Using Subqueries in the SELECT and FROM Clauses ...........................................................10-6
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Practice 10-3: Using Subqueries in the WHERE Clause................................................................................10-7


Solution 10-3: Using Subqueries in the WHERE Clause................................................................................10-8
Practice 10-4: Additional Practice ..................................................................................................................10-10
Solution 10-4: Additional Practice ..................................................................................................................10-11
Practices for Lesson 11: Modifying Table Data .............................................................................................11-1
Practices for Lesson 11: Modifying Table Data ..............................................................................................11-2
Practice 11-1: Adding New Data to Tables ....................................................................................................11-3
Solution 11-1: Adding New Data to Tables ....................................................................................................11-4
ble
Practice 11-2: Deleting Data from Tables ......................................................................................................11-6
fe r a
Solution 11-2: Deleting Data from Tables ......................................................................................................11-7
an s
t r
Practice 11-3: Updating Table Data ...............................................................................................................11-9
n -
a no
Solution 11-3: Updating Table Data ...............................................................................................................11-10
Practice 11-4: Replacing Table Data..............................................................................................................11-12
h a s
Solution 11-4: Replacing Table Data..............................................................................................................11-13

ฺ b r) deฺ
Practice 11-5: Avoiding Data Insertion Errors ................................................................................................11-14
o m Gui
Solution 11-5: Avoiding Data Insertion Errors ................................................................................................11-15
c
a rฺ ent
Practice 11-6: Truncating Table Data.............................................................................................................11-17
p
one s Stud
Solution 11-6: Truncating Table Data.............................................................................................................11-18
s
Practice 11-7: Modifying Table Data ..............................................................................................................11-20
c i@ thi
Solution 11-7: Modifying Table Data ..............................................................................................................11-21
c
o ฺ i u se
r ..........................................................................................................12-1
t
Practices for Lesson 12: Transactions
r o
12:eTransactionst...........................................................................................................12-2
Practices for Lesson b
(ro– Transactions, e
ns Isolation Levels, and Locking ................................................................12-3
Solutionic
i
Practice 12-1: Quiz
c li c e
12-1: Quiz – Transactions, Isolation Levels, and Locking ................................................................12-4
R
o 12-2: Using Transaction Control Statements....................................................................................12-5
ertSolution
Practice
b 12-2: Using Transaction Control Statements....................................................................................12-6
Ro Practice 12-3: Examining the Effect of Isolation Levels in Concurrent Transactions ......................................12-12
Solution 12-3: Examining the Effect of Isolation Levels in Concurrent Transactions ......................................12-14
Practices for Lesson 13: Query Optimization ................................................................................................13-1
Practices for Lesson 13: Query Optimization .................................................................................................13-2
Practice 13-1: Quiz – Optimization .................................................................................................................13-3
Solutions 13-1: Quiz – Optimization ...............................................................................................................13-4
Practice 13-2: Creating a Table with Indexes .................................................................................................13-5
Solutions 13-2: Creating a Table with Indexes ...............................................................................................13-6
Practice 13-3: Altering the Indexes in an Existing Table ................................................................................13-7
Solutions 13-3: Altering the Indexes in an Existing Table ..............................................................................13-8
Practice 13-4: Removing an Existing Index ....................................................................................................13-9
Solutions 13-4: Removing an Existing Index ..................................................................................................13-10
Practice 13-5: Using Optimization Techniques ..............................................................................................13-11
Solutions 13-5: Using Optimization Techniques .............................................................................................13-12
Practice 13-6: Identifying and Fixing Slow Queries with MySQL Enterprise Monitor Query Analyzer ............13-16
Solution 13-6: Identifying and Fixing Slow Queries with MySQL Enterprise Monitor Query Analyzer ............13-24

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

MySQL for Developers Table of Contents


v
Practices for Lesson 14: Stored Routines .....................................................................................................14-1
Practices for 14: Stored Routines...................................................................................................................14-2
Practice 14-1: Creating Simple Stored Routines ............................................................................................14-3
Solution 14-1: Creating Simple Stored Routines ............................................................................................14-4
Practice 14-2: Creating Stored Routines with Compound Statements ...........................................................14-6
Solution 14-2: Creating Stored Routines with Compound Statements ...........................................................14-7
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Practice 14-3: Creating Stored Routines with Parameter Declarations ..........................................................14-9


Solution 14-3: Creating Stored Routines with Parameter Declarations ..........................................................14-10
Practice 14-4: Examining Stored Routines .....................................................................................................14-12
Solution 14-4: Examining Stored Routines .....................................................................................................14-13
Practice 14-5: Deleting and Re-creating a Stored Routine.............................................................................14-17
Solution 14-5: Deleting and Re-creating a Stored Routine.............................................................................14-18
Practice 14-6: Creating Stored Routines with Flow Control Statements ........................................................14-20
Solution 14-6: Creating Stored Routines with Flow Control Statements ........................................................14-21
ble
Practice 14-7: Working with the DECLARE CONDITION and DECLARE HANDLER Statements .................14-26
fe r a
Solution 14-7: Working with the DECLARE CONDITION and DECLARE HANDLER Statements .................14-27
an s
Practice 14-8: Creating a Stored Function to Retrieve Database Metadata ...................................................14-29
Solution 14-8: Creating a Stored Function to Retrieve Database Metadata ...................................................14-30 n - t r
a no
Practice 14-9: Additional Practice ..................................................................................................................14-32
a s
Solution 14-9: Additional Practice ..................................................................................................................14-33
h
ฺ b r) deฺ
Practices for Lesson 15: Triggers and Scheduled Events ...........................................................................15-1

o m Gui
Practices for Lesson 15: Triggers and Scheduled Events ..............................................................................15-2
c
a rฺ ent
Practice 15-1: Creating and Dropping Triggers ..............................................................................................15-3
p
Practice 15-2: Investigating Triggers in the sakila s oDatabase S tud
ne ..........................................................................15-10
Solution 15-1: Creating and Dropping Triggers ..............................................................................................15-5

c
Solution 15-2: Investigating Triggers in i @sakila Database
the t h is ..........................................................................15-11
o ฺ
Practice 15-3: Creating a Scheduled
t ricEventu...................................................................................................15-15
se
Solution 15-3: Creating e
b r
a Scheduled to ...................................................................................................15-16
Event
(ro16: cReporting e
ns ................................................................................................................16-1
i
Practices for Lesson
c e
icfor Lesson 16:li Reporting ................................................................................................................16-2
Practices
R
o 16-1: Aggregating Data ....................................................................................................................16-3
ertSolution
Practice
b 16-1: Aggregating Data ....................................................................................................................16-5
Ro Practice 16-2: Grouping Aggregated Data .....................................................................................................16-9
Solution 16-2: Grouping Aggregated Data .....................................................................................................16-10
Practice 16-3: Creating a Crosstab Report with a Bar Chart ..........................................................................16-13
Solution 16-3: Creating a Crosstab Report with a Bar Chart ..........................................................................16-14
Practices for Lesson 17: NoSQL.....................................................................................................................17-1
Practices for Lesson 17: Building NoSQL Applications ..................................................................................17-2
Practice 17-1: Configuring the Memcached Plug-in for InnoDB .....................................................................17-4
Solution 17-1: Configuring the Memcached Plug-in for InnoDB .....................................................................17-5
Practice 17-2: Using the Memcached Plug-in for InnoDB with PHP...............................................................17-9
Solution 17-2: Using the Memcached Plug-in for InnoDB with PHP...............................................................17-11
Practice 17-3: Using the Memcached Plug-in for InnoDB with Java ..............................................................17-16
Solution 17-3: Using the Memcached Plug-in for InnoDB with Java ..............................................................17-18
Practice 17-4: Using the Memcached Plug-in for InnoDB with Python ...........................................................17-24
Solution 17-4: Using the Memcached Plug-in for InnoDB with Python ...........................................................17-26

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

MySQL for Developers Table of Contents


vi
Practice 17-5: Manipulating JSON Data .........................................................................................................17-31
Solution 17-5: Manipulating JSON Data .........................................................................................................17-33
Practice 17-6: Querying JSON Data ..............................................................................................................17-37
Solution 17-6: Querying JSON Data ..............................................................................................................17-38
Practices for Lesson 18: Spatial Data ............................................................................................................18-1
Practices for 18: Spatial Data .........................................................................................................................18-2
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Practice 18-1: Creating Spatial Data ..............................................................................................................18-3


Solution 18-1: Creating Spatial Data ..............................................................................................................18-4
Practice 18-2: Using Spatial Indexes for Analysis ..........................................................................................18-6
Solution 18-2: Using Spatial Indexes for Analysis ..........................................................................................18-8
Practices for Lesson 19: Conclusion .............................................................................................................19-1
Practices for Lesson 19: Conclusion ..............................................................................................................19-2
Appendix A: Sample Databases .....................................................................................................................20-1
world Schema Data Model .............................................................................................................................20-2
ble
sakila Schema Data Model ............................................................................................................................20-3
fe r a
Appendix B: MySQL Workbench ....................................................................................................................21-1
t r a ns
n
Appendix B: MySQL Workbench ....................................................................................................................21-2
o -
an
Introduction ....................................................................................................................................................21-3
s
r ) ha ฺ
MySQL Server Administration ........................................................................................................................21-4
SQL Development in MySQL Workbench ......................................................................................................21-10
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
R icc lic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

MySQL for Developers Table of Contents


vii
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 1:
om t Gto
Introduction i
u MySQL
r ฺ c
a 1 den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 1
Practices for Lesson 1: Introduction to MySQL
Practices Overview
This practice introduces you to the course environment.

Assumptions
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

• You are logged in to the Oracle Linux operating system as the root user (password:
oracle).
• MySQL Enterprise Edition (server version 5.7.12 or later) is installed.
• MySQL Workbench (version 6.3.6 or later) is installed.
• MySQL Enterprise Monitor (version 3.2 or later) is installed.
• The Apache web server is installed and running.
• Apache Tomcat is installed and not running. ble
fe r a
• The Mozilla Firefox web browser is installed.
ans
• The sakila and world sample databases are installed.
n - t r
o

an
The employees sample database installation files are located in the
/stage/databases/employees_db directory. s
) a
hscripts.
• The /labs directory contains the course practice files
ฺ b r
and
d e ฺ
om t Gu i
r ฺ
a denc
e p
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 2
Practice 1-1: Course Environment Overview
Overview
This practice introduces you to the tools, sample databases, and other resources that you use in
this course.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 30 minutes to complete.

Tasks
1. This course uses the MySQL Enterprise Edition (server version 5.7.12 or later), which is
installed for you. Confirm that the server is installed correctly.
Enter the following command at the Linux terminal prompt and receive the results shown:
ble
# mysql --version
fe r a
ns
mysql Ver 14.14 Distrib 5.7.12, for Linux (x86_64) using EditLine
wrapper
t r a
-not required
2. MySQL Workbench version 6.3.6 or later is installed in Oracle classrooms. o n
It is
n to interact with
for course activities, but is available in the course environment if you prefer
s a
MySQL by using a graphical tool. Confirm that MySQL Workbench
performing the following steps: r ) ha is installed

by

a. Select the Applications > Programming > MySQL m ฺb uidmenu


Workbench
e option. The
MySQL Workbench window appears. r o
ฺc nt G
b. Select the Help > About Workbench
a
p option
emenu deand check the version number.
o n
s is S t u
c. Press Ctrl + Q to exit MySQL Workbench.
i @
cassumeethatthyou are working with the mysql command-line
Note: These practice guides
r i c
client.
e r toฺ to us
3. In the lessono b “Optimizing
r titled stoeidentifyQueries” you use the Query Analyzer module of the MySQL
i
Enterprise (Monitor
c many other e n
c useful featurespoorly
tool performing queries. MySQL Enterprise Monitor
R i c
includes l i that assist in monitoring server and database
e r t operformance. Confirm that the course environment contains MySQL Enterprise Monitor

R ob version 3.2 or later and configure it for use by performing the following steps:
a. Ensure that the MySQL Enterprise Monitor services are running by entering the
following commands at a Linux terminal prompt and receiving the results shown:
# service mysql-monitor-server status
MySQL Enterprise MySQL is running
MySQL Enterprise Tomcat is running
− Note: If the services shown above are not running, start them by executing the
following command at the Linux terminal prompt:
# service mysql-monitor-server start
Starting mysql service [ OK ]
160511 11:16:51 mysqld_safe Logging to
'/opt/mysql/enterprise/monitor/mysql/runtime/mysqld.log'.
160511 11:16:51 mysqld_safe Starting mysqld daemon with databases from
/opt/mysql/enterprise/monitor/mysql/data/
Starting tomcat service [ OK ]
b. Configure Mozilla Firefox to make it easier to enter the URL of a local server without
Firefox attempting to append “.com” to it. Open Firefox and perform the following steps:
− Enter about:config in the address bar.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 3
− A message warns you about voiding your warranty. Click the “I’ll be careful, I
promise!” button to continue.
− Enter browser.fixup.alternate.enabled in the search box. This filters the
list of settings.
− Check the Value column of the browser.fixup.alternate.enabled
configuration setting in the filtered list. If it is set to False, proceed to step c. If it is
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

set to True, right-click the setting and select Toggle to change its value to False.
c. Enter the following URL in the Mozilla Firefox address bar:
https://localhost:18443/
− A page appears with the message “This Connection is Untrusted.”
d. Click “I understand the risks.”
e. Click the “Add Exception” button.
f. In the “Add Security Exception” dialog box, select the “Permanently store this
ble
exception” check box and click the “Confirm Security Exception” button.
fe r a
− The MySQL Enterprise Dashboard Setup page appears. ans
g. In the “Create user with ‘manager’ role” pane, enter the following: n - t r
− Username: monitormanager a no
− Password: oracle h a s
ฺ b r) deฺ
− Confirm Password: oracle
c o m Gui
ฺ thenfollowing:
h. In the “Create user with ‘agent’ role” pane, renter
a t
p e
− Username: monitoragent ne
s o S tud
− Password: oracle
c i @ this
− Confirm Password:
t o ฺ ricoracle
u se
i. Ensure that the
b e r MySQL tEnterprise
o Dashboard Setup page appears as follows:
r o s e
c c i ( licen
R i
ert o
b
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 4
j. Click the Complete Setup button at the bottom of the page.
− A welcome message appears.
k. In the welcome message dialog box, make any necessary changes to Timezone and
Locale, and click Save.
− The MySQL Enterprise Monitor Dashboard page displays and contains product-
related announcements and system notifications.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

− MySQL Enterprise Monitor is now ready to use.


l. Exit MySQL Enterprise Monitor by selecting Logout from the “monitormanager” user
drop-down list at the top of the page.
m. Press Ctrl + D to bookmark the MySQL Enterprise Monitor login page. In the “Edit this
Bookmark” dialog box that appears:
− Enter “Monitor Dashboard” in the Name field.
− Select “Bookmarks Toolbar” from the Folder drop-down list.
ble
− Click Done. fe r a
n. Make the Bookmarks Toolbar visible by clicking the Settings button to the far right of ans
the address bar, and then clicking Customize. n - t r
− The Customize Firefox tab opens. a no
h a s
o. In the bottom left-hand corner of the Customize Firefox tab, click the Show/Hide
b r) deฺ
Toolbars drop-down list and select the “Bookmarks Toolbar” check box.

o m Gui
p. Click the green “Exit Customize” button in the bottom-right corner of the page.
c
a rฺ ent
q. Verify that the “Monitor Dashboard” link appears on the Bookmarks Toolbar.
p
one s Stud
r. Exit the Mozilla Firefox web browser.
s
c c i@ thi
s. Stop the MySQL Enterprise Monitor services by executing the following command at a
r i se
Linux terminal prompt and receiving the results shown:
o ฺ u
# service e r t to
b mysql-monitor-server
e stop

c i (ro tomcat
Stopping
c e nsservice . [ OK ]
Ric li service 160511 11:19:58 mysqld_safe mysqld from
Stopping mysql pid

e r to file /opt/mysql/enterprise/monitor/mysql/runtime/mysqld.pid ended

ob
. [ OK ]
R 4. This course uses the world, sakila, and employees sample databases. The world
and sakila databases are installed for you. You will install the employees database as
part of the “Optimizing Queries” lesson activities.
a. Verify that the world and sakila databases are installed by entering the following
command at a Linux terminal prompt and receiving the results shown:
# ls -l /var/lib/mysql
total 122956
-rw-r----- 1 mysql mysql 56 May 10 13:08 auto.cnf
-rw------- 1 mysql mysql 1680 May 10 13:08 ca-key.pem
-rw-r--r-- 1 mysql mysql 1075 May 10 13:08 ca.pem
-rw-r--r-- 1 mysql mysql 1079 May 10 13:08 client-cert.pem
-rw------- 1 mysql mysql 1676 May 10 13:08 client-key.pem
-rw-r----- 1 mysql mysql 1119 May 10 13:12 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 May 10 13:14 ibdata1
-rw-r----- 1 mysql mysql 50331648 May 10 13:14 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 May 10 13:08 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 May 10 13:14 ibtmp1
drwxr-x--- 2 mysql mysql 4096 May 10 13:08 mysql

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 5
-rw-rw---- 1 root root 5 May 10 13:14 mysqld_safe.pid
srwxrwxrwx 1 mysql mysql 0 May 10 13:14 mysql.sock
-rw------- 1 mysql mysql 5 May 10 13:14 mysql.sock.lock
drwxr-x--- 2 mysql mysql 4096 May 10 13:08 performance_schema
-rw------- 1 mysql mysql 1680 May 10 13:08 private_key.pem
-rw-r--r-- 1 mysql mysql 452 May 10 13:08 public_key.pem
drwxr-x--- 2 mysql mysql 4096 May 10 13:11 sakila
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

-rw-r--r-- 1 mysql mysql 1079 May 10 13:08 server-cert.pem


-rw------- 1 mysql mysql 1676 May 10 13:08 server-key.pem
drwxr-x--- 2 mysql mysql 12288 May 10 13:08 sys
drwxr-x--- 2 mysql mysql 4096 May 10 13:11 world
b. Verify that the installation files for the employees database are located in the
/stage/databases/employees_db directory by entering the following command at
a Linux terminal prompt and receiving the results shown:
# ls /stage/databases/employees_db
ble
Changelog load_departments.dump load_titles.dump
fe r a
employees_partitioned2.sql load_dept_emp.dump objects.sql
ans
employees_partitioned3.sql load_dept_manager.dump
employees_partitioned.sql load_employees.dump
README
n - t r
test_employees_md5.sql
a no
employees.sql
test_employees_sha.sql
load_salaries.dump
h a s
5. The coding practices in this course can be completed using ฺ b ) Java,
rPHP, e ฺ or Python,
depending on which programming language you are m comfortable
omost i d
u with. The titles of the
coding practices and their associated solutions r ฺ c
a indicate t G
n language they refer to. The
which
e p u d e
/labs directory has subdirectories specific
need to complete the practices for s onlanguage.
that
to
s
each
S tYoulanguage
will also
that contain the files you
write SQL code regardless
i @ h i
t which you will store in the sql subdirectory.
of your choice of programming
ฺ r i cc language,
s e
and u
Linux terminal b e rtoand receive
Verify that these directories
t o files are available. Enter the following command at the

( r o prompt
n s e the results shown:

i ci -l16/labs
# ls
c l i ce
t o R drwxr-xr-x 3 root root 4096 May 10 13:11 java
total

be r drwxr-xr-x 3 root root 4096 May 10 13:11 php


Ro drwxr-xr-x 3 root root 4096 May 10 13:11 python
drwxr-xr-x 2 root root 4096 May 10 13:11 sql
6. Many of the coding practices take place in a web environment. The PHP and Python
practices use the Apache web server and the Java practices use the Tomcat application
server. The language-specific directories you looked at in the previous task all contain a
subdirectory called web, which is a symbolic link to the appropriate web server document
directories. Each language-specific directory also contains a cli subdirectory for the
command-line applications you will write in the course practices.
Verify that the web subdirectory symbolic links are set to point to the document directories
of the appropriate web server. Enter the following command at the Linux terminal prompt
and receive the results shown:
# tree /labs
/labs
├── java
│ ├── cli
│ │ └── ...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 6
│ └── web -> /opt/apache-tomcat-7.0.64/webapps/
├── php
│ ├── cli
│ │ └── ...
│ └── web -> /var/www/html/php
├── python
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

│ ├── cli
│ │ └── ...
│ └── web -> /var/www/cgi-bin
├── scripts
│ └── ...
└── sql
└── ...
ble
fe r a
18 directories, 98 files
an s
7. For the web-based practices to work correctly, you must ensure that the relevant web
n - t r
server is running and, if not, start it manually. The commands you use to do this depend on o
an
whether you are using the Apache web server or Tomcat application server.
s
If you are using Apache (for PHP and Python):
r ) ha ฺ
ฺb uide
a. Enter the following commands at the Linux terminal prompt to verify that you can start,
m
a r ฺco nt G
restart, and check the status of the Apache web server:
# service httpd status
o n ep tude
httpd (pid 16248) is running...
@ s is S
# service httpd stop
c c i th
Stopping httpd:
r i us e [ OK ]
# service httpd
e r toฺstatust o
robhttpd:
httpd is stopped
(
# service
n e
httpd sstart
c i c e
Ri#c servicelihttpd status
Starting [ OK ]

e r to httpd (pid 16355) is running...

R ob # service httpd restart


Stopping httpd: [ OK ]
Starting httpd: [ OK ]
# service httpd status
httpd (pid 16390) is running...
− Ensure that the Apache web server is running before proceeding
Note: Your pid (process ID) numbers will probably be different from those shown in
the output.
b. Open Mozilla Firefox and enter the following URL in the address bar:
http://localhost
− Verify that you can see the Apache 2 Test Page. If you cannot, ensure that the
Apache web server is running.
If you are using Tomcat (for Java):
a. Enter the following commands at the Linux terminal prompt to verify that you can start,
stop, restart, and check the status of the Tomcat server using the tc_* alias
commands provided. Enter the following commands at the Linux terminal prompt and
receive the results shown:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 7
# tc_status
root 19920 14213 0 11:20 pts/1 00:00:00 grep tomcat
− The Tomcat service is not running. The only entry in the process list is for the Linux
grep command used to search for Tomcat processes.
# tc_start
Using CATALINA_BASE: /opt/apache-tomcat-7.0.64
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Using CATALINA_HOME: /opt/apache-tomcat-7.0.64


Using CATALINA_TMPDIR: /opt/apache-tomcat-7.0.64/temp
Using JRE_HOME: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/
Using CLASSPATH: /opt/apache-tomcat-
7.0.64/bin/bootstrap.jar:/opt/apache-tomcat-7.0.64/bin/tomcat-juli.jar
Tomcat started.
− The Tomcat server has started.
# tc_restart
Using CATALINA_BASE: /opt/apache-tomcat-7.0.64
ble
Using CATALINA_HOME: /opt/apache-tomcat-7.0.64
fe r a
Using CATALINA_TMPDIR: /opt/apache-tomcat-7.0.64/temp
ans
Using JRE_HOME: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/
n - t r
no
Using CLASSPATH: /opt/apache-tomcat-
a
7.0.64/bin/bootstrap.jar:/opt/apache-tomcat-7.0.64/bin/tomcat-juli.jar
s
Using CATALINA_BASE: /opt/apache-tomcat-7.0.64
h a
Using CATALINA_HOME: /opt/apache-tomcat-7.0.64
ฺ b
Using CATALINA_TMPDIR: /opt/apache-tomcat-7.0.64/tempr) deฺ
Using JRE_HOME: o m Gui
/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/
c
Using CLASSPATH:
a rฺ ent
/opt/apache-tomcat-
p
one s Stud
7.0.64/bin/bootstrap.jar:/opt/apache-tomcat-7.0.64/bin/tomcat-juli.jar
Tomcat started.
s i
− The Tomcat server stops
c c i@and then
t hrestarts.
# tc_status
o i
ฺr 1 5u11:24 e
s pts/1 00:00:03 /usr/lib/jvm/jre-
root
e r
19994t t o
i ( rob ense
1.7.0-openjdk.x86_64//bin/java -

cc lic
Djava.util.logging.config.file=/opt/apache-tomcat-

to Ri7.0.64/conf/logging.properties -

e r Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -

ob
Djava.endorsed.dirs=/opt/apache-tomcat-7.0.64/endorsed -classpath
R /opt/apache-tomcat-7.0.64/bin/bootstrap.jar:/opt/apache-tomcat-
7.0.64/bin/tomcat-juli.jar -Dcatalina.base=/opt/apache-tomcat-7.0.64 -
Dcatalina.home=/opt/apache-tomcat-7.0.64 -Djava.io.tmpdir=/opt/apache-
tomcat-7.0.64/temp org.apache.catalina.startup.Bootstrap start
root 20035 14213 0 11:25 pts/1 00:00:00 grep tomcat
− The Tomcat server is running under the process ID (pid) 19994.
− Note: The pid number on your system will probably be different.
b. Open the Mozilla Firefox web browser and enter the following URL in the address bar:
http://localhost:8080
− Ensure that you can see the Tomcat page. If not, use the tc_start command at
the Linux terminal prompt to start the Tomcat server. Ensure that the Tomcat
application server is running before proceeding.
c. Exit the Mozilla Firefox web browser.
8. This Activity Guide contains the practices and solutions for each lesson. The course
environment includes lab scripts and solution files that you can use to copy and paste
commands and statements to complete the practices. However, you are encouraged to

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 8
enter these yourself. They are provided only to save time if you find that a practice takes
longer than anticipated.
The solution code for each of the language-specific activities is included in the php, java,
and python subdirectories.
Lab scripts for activities that are not language-specific are stored in the scripts
subdirectory.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following command at the Linux terminal prompt and receive the results shown:
# tree -l /labs
/labs
├── java
│ ├── cli
│ │ ├── activity17-3
│ │ │ └── MemcachedTest.java
ble
│ │ ├── activity5-4
fe r a
│ │ │ ├── ExceptionExample_soln.java
ans
│ │ │ └── ExceptionExample_start.java
n - t r
│ │ └── lib o
│ │ ├── commons-pool-1.5.6.jar s an
│ │ ├── java_memcached-release_2.6.6.jar
r ) ha ฺ
│ │ ฺb uide
├── mysql-connector-java-commercial-5.1.38-
m
a r ฺco nt G
bin.jar



│ o n ep tude
├── slf4j-api-1.6.1.jar
└── slf4j-simple-1.6.1.jar
@ s is S

c c i
└── web -> /opt/apache-tomcat-7.0.64/webapps/
th
r i e
toฺ to us
│ ├── activity3-2
│ │ e r
├── conn_soln.inc

i ( rob ense
│ ├── conn_start.inc
c lic
Ric
│ │ ├── index_soln.jsp

e r to │ │ ├── index_start.jsp

R ob │



└── WEB-INF
├── classes
│ │ └── lib
│ ├── activity3-5
│ │ ├── index_soln.jsp
│ │ ├── index_start.jsp
│ │ └── WEB-INF
│ │ ├── classes
│ │ ├── conn.inc
│ │ └── lib
│ ├── activity4-3
│ │ ├── addfilm_soln.jsp
│ │ ├── addfilm_start.jsp
│ │ ├── findfilm_soln.jsp
│ │ ├── findfilm_start.jsp
│ │ ├── index.html
│ │ └── WEB-INF
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 9
│ │ ├── classes
│ │ ├── conn.inc
│ │ └── lib
│ ├── activity6-2
│ │ ├── index_soln.jsp
│ │ ├── index_start.jsp
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

│ │ └── WEB-INF
│ │ ├── classes
│ │ ├── conn.inc
│ │ └── lib
│ ├── activity6-5
│ │ ├── index.jsp
│ │ ├── results_soln.jsp
ble
│ │ ├── results_start.jsp
fe r a
│ │ └── WEB-INF
ans
│ │ ├── classes
n - t r
o
an
│ │ ├── conn.inc
│ │ └── lib s
ha ฺ
│ └── activity6-8 r )
ฺb uide
│ ├── index_soln.jsp m
│ ├── index_start.jsp
a r ฺco nt G
│ └── WEB-INF
o n ep tude
│ ├── classes
@ s is S
│ c
├── conn.inc
c i th
r i e

├── php e r toฺ to us
└── lib

│ ( rob ense
├── cli
i
c lic
to Ric│



├── activity17-2
│ └── memcached_test.php
e r
R ob │



└── activity5-3
├── ExceptionExample_soln.php
│ │ └── ExceptionExample_start.php
│ └── web -> /var/www/html/php
│ ├── activity3-1
│ │ ├── conn_soln.php
│ │ ├── conn_start.php
│ │ ├── index_soln.php
│ │ └── index_start.php
│ ├── activity3-4
│ │ ├── conn.php
│ │ ├── index_soln.php
│ │ └── index_start.php
│ ├── activity4-2
│ │ ├── addfilm_soln.php
│ │ ├── addfilm_start.php

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 10
│ │ ├── conn.php
│ │ ├── findfilm_soln.php
│ │ ├── findfilm_start.php
│ │ └── index.html
│ ├── activity6-1
│ │ ├── conn.php
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

│ │ ├── index.php
│ │ ├── layout_soln.php
│ │ └── layout_start.php
│ ├── activity6-4
│ │ ├── conn.php
│ │ ├── index.php
│ │ ├── layout.php
ble
│ │ ├── results_soln.php
fe r a
│ │ └── results_start.php
ans
│ └── activity6-7
n - t r
o
an
│ ├── conn.php
│ ├── index.php s
ha ฺ
│ └── index_start.php r )
ฺb uide
├── python m
│ ├── cli
a r ฺco nt G
│ │ ├── activity17-4
o n ep tude
│ │ │ s is S
└── memcached_test.py
@
│ │ └── activity5-5
c c i th
r i e



│ e r toฺ to us
├── ExceptionExample_soln.py
└── ExceptionExample_start.py
│ ( rob ense
└── web -> /var/www/cgi-bin
i
c lic
to Ric│

├── activity3-3
│ ├── conn_soln.py
e r
R ob │



├── conn_start.py
├── index_soln.py
│ │ └── index_start.py
│ ├── activity3-6
│ │ ├── conn.py
│ │ ├── index_soln.py
│ │ └── index_start.py
│ ├── activity4-4
│ │ ├── addfilm_soln.py
│ │ ├── addfilm_start.py
│ │ ├── conn.py
│ │ ├── findfilm_soln.py
│ │ ├── findfilm_start.py
│ │ └── index.py
│ ├── activity6-3
│ │ ├── conn.py

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 11
│ │ ├── index.py
│ │ ├── layout_soln.py
│ │ └── layout_start.py
│ ├── activity6-6
│ │ ├── conn.py
│ │ ├── index.py
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

│ │ ├── layout.py
│ │ ├── results_soln.py
│ │ └── results_start.py
│ └── activity6-9
│ ├── conn.py
│ ├── index_soln.py
│ ├── index_start.py
ble
│ └── results.py
fe r a
├── scripts
ans
│ ├── Practice_01-1.lab
n - t r
o
an
│ ├── Practice_02-1.lab
│ ├── Practice_03-1.lab s
ha ฺ
│ └── ... r )
ฺb uide
└── sql m
├── employees2.sql
a r ฺco nt G
├── film2.sql
o n ep tude
├── logins.sql
@ s is S
└── sensor.sql
c c i th
r i us e
e r
54 directories, toฺ 172to files
b terminal
roLinux se windows.
(
9. Exit any open
i e n
R icc lic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 12
Solution 1-1: Course Environment Overview

There is no solution for this practice.


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 13
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 1: Introduction to MySQL


Chapter 1 - Page 14
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 2:
MySQL omConnectors
u i and APIs
r ฺ c
a 2 den t G
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 2: MySQL Connectors and APIs


Chapter 2 - Page 1
Practices for Lesson 2: MySQL Connectors and APIs
Practices Overview
This practice tests your knowledge of MySQL Connectors and APIs.

Assumptions
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

None

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 2: MySQL Connectors and APIs


Chapter 2 - Page 2
Practice 2-1: Quiz — MySQL Connectors and APIs
Overview
In this practice, you test your knowledge of MySQL Connectors and drivers.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 5 minutes to complete.

Questions
1. Where must you install Connectors?
a. You must install the Connector on every client host where programs that use the
connector run.
b. You must install the Connector on the server host only. This makes it available to all
clients connecting from remote hosts. ble
fe r a
c. You must install the Connector on both the server host and all client hosts.
ans
2. Which of the following statements are true? (Choose all that apply.)
n - t r
o
an
a. Drivers for MySQL are available for all operating systems that MySQL supports.
b. MySQL server distributions include drivers for MySQL. s
ha ฺ
c. The MySQL GUI tools include drivers for MySQL. r )
ฺb uide
m
d. Oracle Corporation ships drivers for MySQL independently of MySQL Server
distributions.
a r ฺco nt G
o n ep tude
e. Third parties ship drivers for MySQL independently of MySQL Server distributions.
3. s is S
Which of the following is a good reason for using PDO instead of mysqli when developing
@
PHP/MySQL web applications?
c c i th
r i e
e r toฺ to us
a. PDO supports more features of MySQL than mysqli.

i ( rob ense
b. PDO is newer than mysqli and therefore more reliable.
c lic
c. PDO is more portable than mysqli.

to Ric
d. PDO can be run as an Apache server module, and mysqli cannot.
e r
4. All MySQL Connectors are based on MySQL’s C API and are implemented using the
R ob MySQL C client library.
a. True
b. False
5. MySQL Connectors are written in C, like all other MySQL client programs.
a. True
b. False

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 2: MySQL Connectors and APIs


Chapter 2 - Page 3
Solution 2-1: Quiz — MySQL Connectors and APIs
Answers
1. a. You must install the Connector on every client host where programs that use the
Connector run.
2. d and e. The following website contains links to many popular drivers, some of which you
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

download directly from Oracle Corporation and others from third-party websites:
http://www.mysql.com/products/connector/
3. c. The primary reason for using PDO is that it provides a standard way to access many
different relational databases.
4. b. False. There are many different architectures for Connectors. Some Connectors are
based on MySQL’s C API (using libmysql). Others implement the MySQL protocol entirely
within the host language or environment. One (the MySQL JavaScript Connector for
Node.js and MySQL Cluster) is written partly in JavaScript and partly in C, but without ble
libmysql. fe r a
ans
5. b. False. Developers create Connectors using many languages. For example, Connector/J
is written entirely in Java. n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 2: MySQL Connectors and APIs


Chapter 2 - Page 4
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 3: Using
Connectorsom t Gu i
r ฺ c
a 3 den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 1
Practices for Lesson 3: Using Connectors
Practices Overview
These practices test your knowledge of using MySQL Connectors. They assume that you are
using the Linux operating system environment provided in Oracle classrooms. For non-Oracle
classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Important: The coding practices in this lesson are available in PHP, Java, and Python. Perform
all the practices for this and all future coding activities in only one language, choosing the
language you are most familiar with. If in doubt, perform the PHP activities. Ensure that you
complete all practices that are not language-specific.
For this lesson, perform the following practices:
• If your chosen programming language is PHP:
− Practice 3-1: Connecting to the MySQL Server in a Web Environment with ble
PHP/PDO
fe r a
− Practice 3-4: Executing SQL in a Web Environment with PHP/PDO ans
• If your chosen programming language is Java: n - t r
a no
− Practice 3-2: Connecting to the MySQL Server in a Web Environment with
Connector/J h a s
ฺ b r) deฺ
− Practice 3-5: Executing SQL in a Web Environment with PHP/PDO
• If your chosen programming language is Python: c o m Gui
p a rฺ ent
− Practice 3-3: Connecting to the MySQL Server in a Web Environment with
Connector/Python
s one s Stud
c c i@ thi
− Practice 3-6: Executing SQL in a Web Environment with Connector/Python
o ฺ r i u se
Assumptions e r t to
b e
• You have
c i (rodecided
c e s programming language (PHP, Java, or Python) to use for the
nwhich
R
practices.
li
iIfcyou are completing

e r to − The Apache web server the coding practices in PHP:

R ob is installed and running on port 80


− PHP 5.3.3 or later is installed, including the PDO module
• If you are completing the coding practices in Java:
− The Tomcat application server is installed and running on port 8080
− Java SE 7 JDK or later (or a compatible JDK) is installed.
− The MySQL Connector/J and JSTL .jars are in the $CATALINA_HOME/lib
directory
(Installed for you in Oracle classroom installations).

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 2
• If you are completing the coding practices in Python:
− Python 2.6.6 or later is installed. (This is installed for you in Oracle classroom
environments.)
− The Apache web server is installed and running on port 80.
− Connector/Python is installed.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

• You have access to the MySQL server root account (password: oracle).
• The MySQL server contains the world and sakila databases.
• The /labs directory contains the course practice files and scripts.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 3
Practice 3-1: Connecting to the MySQL Server in a Web Environment
with PHP/PDO
Overview
In this practice, you write a web application in PHP/PDO that connects to the world database
on your local MySQL server.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You are logged in as the Linux root user at a terminal prompt.
• The Apache server is running.

Duration
This practice should take you approximately 20 minutes to complete.
ble
Tasks fe r a
ans
1. In a Linux terminal window logged in as the root Linux user, change the current working
directory to /labs/php and use the ls -al command to display a long list of the directory n - t r
o
contents.
s an
What does the /labs/php/web directory represent?
r ) ha ฺ
ฺb uide
2. Change the current working directory to /labs/php/web/activity3-1 and list the files
m
within that directory.
a r ฺco nt G
3. Copy the index_start.php and conn_start.php files to index.php and conn.php,
respectively.
o n ep tude
@ s is S
4. Examine the PHP code in conn.php in a text editor such as gedit, emacs, or vim.
c c i th
r i e
5. Under the comment labelled “A. Create the DSN”, add a suitable DSN (data source name)
r toฺ to us
to connect to the world database on the local MySQL server. Store the DSN in a variable
e
called $dsn.
i ( rob ense
c lic
6. Under the comment labelled “B. Connect to the database server”, create a new instance of

to Ric
the PDO class, passing in the DSN, the MySQL user name root, and the password
e r oracle. If the connection is successful, display a suitable message to the user.

R ob 7. Under the comment labelled “C. Disconnect from the database server”, close the
connection to the MySQL server and display a suitable message to the user.
8. Save and close the conn.php file.
9. Examine the HTML markup in index.php in your chosen text editor.
10. Under the comment labelled “D. Add a reference to the conn.php utility library file”, write
PHP code that references the conn.php utility library file.
11. Save and close the index.php file.
12. Open the index.php page in the Firefox browser using the following URL: http://localhost
/php/web/activity3-1/index.php.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 4
13. Verify that you receive the following messages in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
The application connects to the database and then immediately ฺ b r) disconnects,
d e ฺ displaying an
om t Gu i
appropriate message at each stage of the process.
r ฺ c
a youdprobablyn have an error in your PHP
p
Note: If the page does not display as expected,
e e
code. To diagnose the error, examine
s n contents
othe S tuof the Apache error log file (located at
/var/log/httpd/error_log
c i in Oracle s
i in theenvironments.)
classroom
@last fewthentries Use a suitable Linux
terminal command to display
t o ฺ ric use
the log, such as:
r to
# tail -10 /var/log/httpd/error_log
b e
(roandcthe
14. Leave Firefox e
s terminal window open for the next practice.
nLinux
c i li e
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 5
Solution 3-1: Connecting to the MySQL Server in a Web Environment
with PHP/PDO
Solution Steps
1. In a Linux terminal window logged in as the root Linux user, change the current working
directory to /labs/php and use the ls -al command to display a long list of the directory
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

contents.
What does the /labs/php/web directory represent?
Enter the following commands at the Linux terminal prompt and receive the results shown:
# ls -al
total 12
drwxr-xr-x 3 root root 4096 May 10 13:11 .
drwxr-xr-x 6 root root 4096 May 10 13:11 ..
drwxr-xr-x 4 root root 4096 Apr 15 09:07 cli
ble
lrwxrwxrwx 1 root root 17 May 10 13:11 web -> /var/www/html/php
fe r a
Answer: The /labs/php/web directory is a symbolic link to a folder called php in the ans
Apache server’s document root (var/www/html.) n - t r
2. no
Change the current working directory to /labs/php/web/activity3-1 and list the files
a
within that directory.
h a s
ฺ b r) deฺ
Enter the following command at the Linux terminal prompt and receive the results shown:
# cd /labs/php/web/activity3-1
c o m Gui
# ls
conn_soln.php conn_start.php ep
arฺ dent index_start.php
index_soln.php
3. Copy the index_start.php and s on s Stu files to index.php and conn.php,
i@ thi
conn_start.php
respectively.
i c c
t o ฺ
Enter the following commandsr atuthe seLinux terminal prompt and receive the results shown:
b e r toindex.php
ro ens conn.php
# cp index_start.php
(conn_start.php e
# cp
c
c lsi lic
R i#conn.php
erto conn_soln.php index.php
conn_start.php index_soln.php
b index_start.php
Ro 4. Examine the PHP code in conn.php in a text editor such as gedit, emacs, or vim.
The contents of the conn.php file are as follows:
<?php

# conn.php: utility library for connecting to the MySQL Server

try {
# A. Create the DSN

# B. Connect to the database server

}
catch (PDOException $e) {
die ("<p>Cannot connect to the database server</p>");
}

# C. Disconnect from the database server

?>
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 6
5. Under the comment labelled “A. Create the DSN”, add a suitable DSN (data source name)
to connect to the world database on the local MySQL server. Store the DSN in a variable
called $dsn.
Enter the following line of code under the comment labelled “A. Create the DSN”:
...
try {
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# A. Create the DSN


$dsn = "mysql:localhost;dbname=world";

# B. Connect to the database server


...
6. Under the comment labelled “B. Connect to the database server”, create a new instance of
the PDO class, passing in the DSN, the MySQL user name root, and the password
oracle. If the connection is successful, display a suitable message to the user.
Enter the following lines of code under the comment labelled “B. Connect to the database ble
server”: fe r a
ans
...
n - t r
no
try {
# A. Create the DSN
s a
$dsn = "mysql:host=localhost;dbname=world";
h a
# B. Connect to the database server
ฺ b r) deฺ
$dbh = new PDO ($dsn, "root", "oracle");
c o m Gui
echo "<p>Connected to the database
p a rฺ ent
server</p>";

one s Stud
}
...
s
7. Under the comment labelledc“C.
i c e t hi from the database server”, close the
i@Disconnect
connection to the MySQL
r t o ฺr serveruand
s display a suitable message to the user.
be linessofePHP
Enter the following o
t code under the comment labelled “C. Disconnect from the
r o
database server”:
i ( licen
i c
...c
t o R
e r # C. Disconnect from the database server

R ob $dbh = NULL;
echo "<p>Disconnected from the database server</p>";
?>
...
8. Save and close the conn.php file.
9. Examine the HTML markup in index.php in your chosen text editor.
The index.php file contains the following HTML markup:
<!doctype html>
<html>
<head>
<title>Activity 3-1 (PHP)</title>
</head>
<body>
<h1>Activity 3-1 (PHP)</h1>
<p>
<strong>Connection status:</strong>
<?php
# D. Add a reference to the conn.php utility library file

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 7
?>
</body>
</html>
10. Under the comment labelled “D. Add a reference to the conn.php utility library file”, write
PHP code that references the conn.php utility library file.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following line of PHP code under the comment labelled “D. Add a reference to the
conn.php utility library file”:
<body>
<h1>Activity 3-1 (PHP)</h1>
<p>
<strong>Connection status:</strong>
<?php
# D. Add a reference to the conn.php utility library file
require_once("conn.php");
ble
?>
fe r a
</body>
ans
11. Save and close the index.php file.
n - t r
o
/php/activity3-1/index.php. s an
12. Open the index.php page in the Firefox browser using the following URL: http://localhost

) ha ฺ
13. Verify that you receive the following messages in the webpage:
r
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

The application connects to the database and then immediately disconnects, displaying an
appropriate message at each stage of the process.
Note: If the page does not display as expected, you probably have an error in your PHP
code. To diagnose the error, examine the contents of the Apache error log file (located at
/var/log/httpd/error_log in Oracle classroom environments.) Use a suitable Linux
terminal command to display the last few entries in the log, such as:
# tail -10 /var/log/httpd/error_log
14. Leave Firefox and the Linux terminal window open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 8
Practice 3-2: Connecting to the MySQL Server in a Web Environment
with Connector/J
Overview
In this practice, you write a web application in Java using JSTL (JSP standard tag library) that
connects to the world database on your local MySQL server.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You are logged in as the Linux root user at a terminal prompt.
• The Tomcat server is running.

Duration
This practice should take you approximately 20 minutes to complete.
ble
Tasks fe r a
ans
1. In a Linux terminal window logged in as the root Linux user, display the contents of the
$CATALINA_HOME/lib folder. Verify that the .jar files for Connector/J and JSTL (the n - t r
o
JSP standard tag library) are present.
s an
r ) ha ฺ
Note: $CATALINA_HOME refers to the root of the Tomcat server installation. The lib

Tomcat server instance. m ฺb uide


subdirectory contains several .jar files which are accessible by all applications within the

a r ฺco nt G
2. Change the current working directory to /labs/java and use the ls -al command to

o n ep tude
display a long list of the directory contents.
s is S
What does the /labs/java/web directory represent?
@
c c i th
i e
3. Change the current working directory to /labs/java/web/activity3-2 and list the files
r
e r toฺ to us
within that directory and its subdirectories.
Notes:
i ( rob ense
c lic
− You can use the tree command to display a hierarchical listing of this folder’s

to Ric subdirectories and its contents.


e r − The server only makes files in the application’s document root available to clients.
R ob Files placed within WEB-INF are never served directly to clients.
4. Copy the index_start.jsp file to index.jsp within the document root.
5. Copy the conn_start.inc file to a new file called conn.inc within the application’s
WEB-INF directory. This file contains connection information. Clients should never use this
file directly.
6. Examine the JSTL code in WEB-INF/conn.inc in a text editor such as gedit, emacs, or
vim.
7. Provide suitable values for the setDataSource tag’s attributes so that the
activity3-2 application accesses the world database on your local MySQL server.
8. Save and close the WEB-INF/conn.inc file.
9. Examine the JSTL code in index.jsp in the activity3-2 directory.
10. Under the comment labelled “A. Unsuccessful connection attempt”, provide a <c:when>
tag which tests whether an exception is raised by the code in WEB-INF/conn.inc. If an
exception occurs, display an “error connecting to the database” method to the user.
11. Under the comment labelled “B. Successful connection attempt” within a <c:otherwise>
tag, display a “connected to the database” message to the user.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 9
12. Save and close the index.jsp file.
13. Open the index.jsp page in the Firefox browser using the following URL:
http://localhost:8080/activity3-2/index.jsp.
Verify that you receive the following message in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
The application connects to the database o neand then d
tuimmediately disconnects, displaying an
s s S
appropriate message at each stage
i c c
of
e
the
t hi consider the following:
i@as expected,
process.
Note: If the page does not
r t o ฺr display
us You can use the tc_status alias in Oracle
− Is the Tomcate server t o
running?
r ob environments
classroom
i ( n se to check if Tomcat is running, and use tc_start and
i−cctc_stop l e
icto start and stop the Tomcat server.
R You might have an error in your JSTL markup. To diagnose the error, review the
berto stack trace displayed in the browser, or examine the Tomcat log files
Ro (localhost.[date].log) in $CATALINA_HOME/logs.
14. Leave Firefox and the Linux terminal window open for the next practice

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 10
Solution 3-2: Connecting to the MySQL Server in a Web Environment
with Connector/J
Solution Steps
1. In a Linux terminal window logged in as the root Linux user, display the contents of the
$CATALINA_HOME/lib folder. Verify that the .jar files for Connector/J and JSTL (the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

JSP standard tag library) are present.


Note: $CATALINA_HOME refers to the root of the Tomcat server installation. The lib
subdirectory contains several .jar files which are accessible by all applications within the
Tomcat server instance.
Enter the following command at the Linux terminal prompt and receive the results shown:
# ls $CATALINA_HOME/lib
annotations-api.jar servlet-api.jar
ble
catalina-ant.jar
catalina-ha.jar
tomcat7-websocket.jar
tomcat-api.jar fe r a
catalina.jar tomcat-coyote.jar
ans
catalina-tribes.jar - t
tomcat-dbcp.jar
n r
ecj-4.4.2.jar
el-api.jar a no tomcat-i18n-es.jar
tomcat-i18n-fr.jar
jasper-el.jar
h a s tomcat-i18n-ja.jar
jasper.jar
ฺ b r) deฺ tomcat-jdbc.jar
jsp-api.jar
c o m Gui tomcat-util.jar
jstl-1.2.jar
p a
mysql-connector-java-commercial-5.1.35-bin.jarrฺ ent websocket-api.jar

The JSTL and Connector/J .jar files o nepresent


are
d available to all applications running
tuand
s S
on this Tomcat server instance.
c i @ this
2. Change the current working
o ฺ r ic directory
u s eto /labs/java and use the ls -al command to
e t
display a long list ofr the directory
t o contents.
b e
What does r
c i (theo /labs/java/web
c e ns at thedirectory represent?

R ic
Enter the li
following commands Linux terminal prompt and receive the results shown:

erto # ls -al
# cd /labs/java
b
Ro total 12
drwxr-xr-x 3 root root 4096 May 11 14:42 .
drwxr-xr-x 6 root root 4096 May 10 13:11 ..
drwxr-xr-x 5 root root 4096 May 10 13:11 cli
lrwxrwxrwx 1 root root 34 May 10 13:11 web -> /opt/apache-tomcat-
7.0.64/webapps/
Answer: The /labs/java/web directory is a symbolic link to the Tomcat server’s
webapps directory (/opt/apache-tomcat-7.0.64/webapps in Oracle classroom
environments.)
3. Change the current working directory to /labs/java/web/activity3-2 and list the files
within that directory and its subdirectories.
Notes:
− You can use the tree command to display a hierarchical listing of this folder’s
subdirectories and its contents.
− The server only makes files in the application’s document root available to clients.
Files placed within WEB-INF are never served directly to clients.
Enter the following command at the Linux terminal prompt and receive the results shown:
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 11
# cd /labs/java/web/activity3-2
# tree
.
├── conn_soln.inc
├── conn_start.inc
├── index_soln.jsp
├── index_start.jsp
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

└── WEB-INF
├── classes
└── lib
• The root of the activity3-2 directory (the “document root”) contains start and
solution versions of the files that the web application requires.
• The WEB-INF directory contains all application resources that are not found within the
document root, including any deployment descriptor file.
ble
• The WEB-INF/classes directory is for any Java servlet and utility classes the web
fe r a
application requires, and is currently empty.
ans
• The WEB-INF/libs directory contains any application-specific .jar files and is
n - t r
currently empty.
n o
4. Copy the index_start.jsp file to index.jsp within the document root. s a
h a
ฺ b r) deฺ
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp index_start.jsp index.jsp
c o m Gui
# ls
conn_soln.inc index.jsp
p a rฺ ent
index_start.jsp
conn_start.inc index_soln.jsp
s one sWEB-INF
S tud
5. Copy the conn_start.inc file i@to a new
ccontains i called conn.inc within the application’s
thfile
WEB-INF directory. Thisrfile
ฺ i c s econnection information. Clients should never use this
file directly. r t o u
toat the Linux terminal prompt and receive the results shown:
b e e
i ro ens
Enter the following commands
(conn_start.inc
#c
R
cp
lic
i#c ls WEB-INF WEB-INF/conn.inc

e r to classes conn.inc lib


R ob 6. Examine the JSTL code in WEB-INF/conn.inc in a text editor such as gedit, emacs, or
vim.
The conn.inc file contains the following markup:
<c:catch var="connexception">
<sql:setDataSource
var="conn"
driver=""
url=""
user=""
password=""
/>
</c:catch>
Notes:
− The conn.inc file contains the JSTL setDataSource tag from the sql tag
library. It specifies the variable name that code using the data source must refer to it
by (conn), and several other attributes that you must set.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 12
− The setDataSource tag is surrounded by catch tags from the core JSTL tag
library. It throws an exception if the setDataSource operation within the catch
block is unable to create a MySQL connection object.
7. Provide suitable values for the setDataSource tag’s attributes so that the
activity3-2 application accesses the world database on your local MySQL server.
Enter the following values in WEB-INF/conn.inc to complete the data source definition:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<c:catch var="connexception">
<sql:setDataSource
var="conn"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql//localhost/world"
user="root"
password="oracle"
/>
</c:catch>
ble
8. Save and close the WEB-INF/conn.inc file.
fe r a
9. Examine the JSTL code in index.jsp in the activity3-2 directory. ans
The index.jsp file contains the following JSTL code: n - t r
o
s an
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

r ) ha ฺ
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ include file="/WEB-INF/conn.inc" %>
m ฺb uide
<!DOCTYPE html>
a r ฺco nt G
ep tude
<html>
<head>
<title>Activity 3-2 s o n S
i @ h s
(Java)</title>
i
</head>
<body>
ฺ r i cc se t
<h1>Activityr u
to 3-2to(Java)</h1>
e
ob A. nUnsuccessful
i
<c:choose>
( r<%-- e se connection attempt --%>
c c l i c
to Ri <%-- B. Successful connection attempt --%>
e r
R ob </c:choose>
</body>
</html>
Notes:
− The taglib directives at the top of the file define tag prefixes for the JSTL core
and sql tag libraries respectively.
− The include directive makes the contents of the conn.inc file you created in
WEB-INF available to the page.
− The <c:choose> tag must contain one or more <c:when> tags with a test
attribute to allow for conditional processing.
10. Under the comment labelled “A. Unsuccessful connection attempt”, provide a <c:when>
tag which tests whether an exception is raised by the code in WEB-INF/conn.inc. If an
exception occurs, display an “error connecting to the database” method to the user.
Enter the following lines of JSTL code in the index.jsp file:
...
<c:choose>
<%-- A. Unsuccessful connection attempt --%>
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 13
<c:when test="${not empty connexception}">
<p>Error connecting to the database</p>
</c:when>
<%-- B. Successful connection attempt --%>
</c:choose>
...
11. Under the comment labelled “B. Successful connection attempt” within a <c:otherwise>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

tag, display a “connected to the database” message to the user.


Enter the following lines of code in the index.jsp file:
...
<c:choose>
<%-- A. Unsuccessful connection attempt --%>
<c:when test="${not empty connexception}">
<p>Error connecting to the database</p>
</c:when>
ble
<%-- B. Successful connection attempt --%>
fe r a
<c:otherwise>
ans
<p>Connected to the database</p>
</c:otherwise>
n - t r
</c:choose>
a no
...
h a s
12. Save and close the index.jsp file.
ฺ b r) deฺ
13. Open the index.jsp page in the Firefox browser using
o m Gthe i URL:
following
u
http://localhost:8080/activity3-2/index.jsp.
a c
rฺ ent
Verify that you receive the following message
n p
e thein
u dwebpage:
o
s is S t
c i @ th
r i c e
e r toฺ to us
i ( rob ense
R icc lic
berto
Ro

The application connects to the database and then immediately disconnects, displaying a
message that signifies either success or failure.
Note: If the page displays an error message, consider the following:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 14
− Is the Tomcat server running? You can use the tc_status alias in Oracle
classroom environments to check if Tomcat is running, and use tc_start and
tc_stop to start and stop the Tomcat server.
− You might have an error in your JSTL markup. To diagnose the error, review the
stack trace displayed in the browser, or examine the Tomcat log files
(localhost.[date].log) in $CATALINA_HOME/logs.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

14. Leave Firefox and the Linux terminal window open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 15
Practice 3-3: Connecting to the MySQL Server in a Web Environment
Using Connector/Python
Overview
In this practice, you write a web application in Python that connects to the world database on
your local MySQL server.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You are logged in as the Linux root user at a terminal prompt.
• The Apache server is running.

Duration
This practice should take you approximately 20 minutes to complete.
ble
Tasks fe r a
ans
1. In a Linux terminal window logged in as the root Linux user, change the current working
directory to /labs/python and use the ls -al command to display a long list of the n - t r
o
directory contents.
s an
What does the /labs/python/web directory represent?
r ) ha ฺ
ฺb uide
2. Change the current working directory to /labs/python/web/activity3-3 and list the
m
contents of the directory.
a r ฺco nt G
3. Copy the index_start.py and conn_start.py files to index.py and conn.py
respectively.
o n ep tude
@ s is S
4. Examine the Python code in conn.py in a text editor such as gedit, emacs, or vim.
c c i th
r i e
5. Under the comment labelled “A. Add a reference to the Connector/Python module”, provide
r toฺ to us
the necessary import statement to include the Connector/Python module in your
e
application.
i ( rob ense
c lic
6. Under the comment labelled “B. Provide appropriate connection parameters”, enter values

to Ric
for the conn_params dictionary object’s properties that allows the object to be used in a
e r call to the Connector/Python connect() method. This creates a connection to the world

R ob database on the local MySQL server instance as the root user (password: oracle).
7. Under the comment labelled “C. Connect to the database and return the connection object”
within the dbconnect() function:
• Call the Connector/Python module’s connect() method, passing the conn_params
object as the parameter.
• Store the resulting connection object in the global variable conn.
• Display a suitable message to indicate to the user that the connection was successful.
• Return the connection object to the script that calls the conn.py library file’s
dbconnect() function.
8. Save and close conn.py.
9. Examine the Python code in index.py in your chosen text editor.
10. Under the comment labelled “D. Create a reference to the conn library file”, add an import
statement to reference the conn.py file.
11. Under the comment labelled “E. Connect to the database”, call the dbconnect() method
in the conn.py library file. Store the connection object that the dbconnect() method
returns in a variable called dbconn.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 16
12. Under the comment labelled “F. Disconnect from the database”, display a “Disconnecting
from the database server” message and call the close() method on the dbconn object.
13. Save and close index.py.
14. Make the conn.py and index.py scripts executable.
15. Execute the index.py script in the Firefox browser using the following URL:
http://localhost/cgi-bin/activity3-3/index.py
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Verify that you receive the following message in the webpage:

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e t
r to the to database and then immediately disconnects, displaying an
The applicationbconnects e
i o
(rmessage natseach stage of the process.
appropriate
c c e
icIf the pageli does not display as expected, you probably have an error in your Python
Note:
R
bertocode. To diagnose the error, examine the contents of the Apache error log file (located at
/var/log/httpd/error_log in Oracle classroom environments.) Use a suitable Linux
Ro terminal command to display the last few entries in the log, such as:
# tail -10 /var/log/httpd/error_log
16. Leave Firefox and the Linux terminal window open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 17
Solution 3-3: Connecting to the MySQL Server in a Web Environment
Using Connector/Python
Solution Steps
1. In a Linux terminal window logged in as the root Linux user, change the current working
directory to /labs/python and use the ls -al command to display a long list of the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

directory contents.
What does the /labs/python/web directory represent?
Enter the following commands at the Linux terminal prompt and receive the results shown:
# ls -al
total 12
drwxr-xr-x 3 root root 4096 May 10 13:11 .
drwxr-xr-x 6 root root 4096 May 10 13:11 ..
drwxr-xr-x 4 root root 4096 Apr 15 09:38 cli
ble
lrwxrwxrwx 1 root root 16 May 10 13:11 web -> /var/www/cgi-bin
fe r a
Answer: The /labs/python/web directory is a symbolic link to the Apache server’s ans
cgi-bin directory. The cgi-bin directory is where the web server stores CGI (common n - t r
no
gateway interface) scripts. CGI is a standard method used to generate dynamic webpage
a
content.
h a s
2. r) deฺ
Change the current working directory to /labs/python/web/activity3-3 and list the
ฺ b
contents of the directory.
c o m Gui
p a rฺ ent
Enter the following commands at the Linux terminal prompt and receive the results shown:

one s Stud
# cd /labs/python/web/activity3-3
# ls s
conn_soln.py conn_start.py
i c c e hi
i@ tindex_soln.py index_start.py
3. Copy the index_start.py
r t o ฺr anduconn_start.py
s files to index.py and conn.py.
respectively. e t o
( rob ecommands
Enter the following
i n se at the Linux terminal prompt and receive the results shown:
R i#cccp index_start.py
lic index.py

e rt o # cp conn_start.py conn.py

o b # ls
R conn.py conn_soln.py
index_start.py
conn_start.py index.py index_soln.py

4. Examine the Python code in conn.py in a text editor such as gedit, emacs, or vim.
The contents of the conn.py file are as follows:
# conn.py: library file for connecting to MySQL using the
# Connector/Python module

# A. Add a reference to the Connector/Python module

conn = None

# B. Provide appropriate connection parameters


conn_params = {
"database": "",
"host": "",
"user": "",
"password": ""
}
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 18
def dbconnect():
try:
global conn

# C. Connect to the database and return the connection object


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

except:
print('''<p>Could not connect to the database</p>''')

def dbclose():
if conn is None:
print('''</p>Can't disconnect: there is no connection</p>''')
else:
# D. Close the connection

print('''<p>Disconnected from the database</p>''') ble


5. Under the comment labelled “A. Add a reference to the Connector/Python module”, provide fe r a
the necessary import statement to include the Connector/Python module in yourra n s
application.
o n -t
Enter the following line of code under the comment labelled “A. Connection
s a n details”:
...
r ) ha ฺ
# A. Add a reference to the Connector/Python
m ฺb module
u ide
import mysql.connector
r o
ฺc nt G
...
a e
p udconnection
eappropriate
6. Under the comment labelled “B. Provide
s o n S t parameters”, enter values
for the conn_params dictionary object’s
i @ h i s
properties that allows the object to be used in a
t method. This creates a connection to the world
call to the Connector/Python

database on the localoMySQL r iccconnect()
u s
servereinstance as the root user (password: oracle).
e r t t o
rob “B. e to appropriate
Assign the following values the conn_params object’s member variables under the
(
commenti labelled e n s
Provide connection parameters”:
c c
i... l i c
o R
ert
# B. Provide appropriate connection parameters
b conn_params = {
Ro "database": "world",
"host": "localhost",
"user": "root",
"password": "oracle",
}
...
7. Under the comment labelled “C. Connect to the database and return the connection object”
within the dbconnect() function:
• Call the Connector/Python module’s connect() method, passing the conn_params
object as the parameter.
• Store the resulting connection object in the global variable conn.
• Display a suitable message to indicate to the user that the connection was successful.
• Return the connection object to the script that calls the conn.py library file’s
dbconnect() function.
Enter the following lines of code under the comment labelled “C. Connect to the database
and return the connection object”:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 19
...
def dbconnect():
try:
global conn

# C. Connect to the database and return the connection object


conn = mysql.connector.connect(**conn_params)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

print('''<p>Connected to the database</p>''')


return conn
except:
print('''<p>Could not connect to the database</p>''')
8. Save and close conn.py.
9. Examine the Python code in index.py in your chosen text editor.
The contents of the index.py file are as follows:
#!/usr/bin/python
ble
fe r a
# D. Create a reference to the conn library file
ans
n - t r
o
print('''Content-Type: text/html
s an
<html>
r ) ha ฺ
ฺb uide
<head><title>Activity 3-3 (Python)</title></head>
m
ฺco nt G
<body>
''')
a r
o n ep tude
s is S
print("<h1>Activity 3-3 (Python)</h1>")
@
c i
cdatabase th
# E. Connect to the
r i e
e r toฺ to us
( rob ensfrom
# F. Disconnect
i
e the database
cc
Riprint(''' lic
e r to </body>

R ob </html>
''')
10. Under the comment labelled “D. Create a reference to the conn library file”, add an import
statement to reference the conn.py file.
Enter the following line of code under the comment labelled “D. Create a reference to the
conn file”:
#!/usr/bin/python

# D. Create a reference to the conn library file


import conn
...
11. Under the comment labelled “E. Connect to the database”, call the dbconnect() method
in the conn.py library file. Store the connection object that the dbconnect() method
returns in a variable called dbconn.
Enter the following line of code under the comment labelled “E. Connect to the databaset”:
...
print("<h1>Activity 2-4 (Python)</h1>")

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 20
# E. Connect to the database
dbconn = conn.dbconnect()
...
12. Under the comment labelled “F. Disconnect from the database”, display a “Disconnecting
from the database server” message and call the close() method on the dbconn object.
Enter the following lines of code under the comment labelled “F. Disconnect from the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

database”:
...
# F. Disconnect from the database
print("<p>Disconnecting from the database server</p>")
dbconn.close()

print('''
</body>
</html>
''')
ble
13. Save and close index.py.
fe r a
14. Make the conn.py and index.py scripts executable. ans
Enter the following commands at the Linux terminal prompt and receive the results shown: n - t r
a no
# chmod +x conn.py
# ls -al
index.py
h a s
total 24
root 4096 May 11 15:31 ฺ.b
r) deฺ
drwxr-xr-x 2 root
c o m .. Gui
drwxr-xr-x. 3 root

11r 15:28 n
root 4096 May 11 15:24
root 814 May a t
-rwxr-xr-x 1 root
p e conn.py
ud conn_soln.py
e 11 t15:23
-rw-r--r-- 1 root root
root s o0nMay S
-rw-r--r-- 1 root
-rwxr-xr-x 1 root
c i
root
652
is11 15:33 index.py
May 11
@ 418 tMay
h
15:26 conn_start.py


-rw-r--r-- 1 root
t o ricrootu e0 May 11 15:23 index_soln.py
s313
r
-rw-r--r-- 1 root
e t o
root May 11 15:31 index_start.py

robmayenread,
The file's owner
i ( sewrite, and execute the conn.py and index.py files. Users in
c grouplcan
the root
icexecute ic read and execute the conn.py and index.py files. Other users can
R
only the conn.py and index.py files.

berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 21
15. Execute the index.py script in the Firefox browser using the following URL:
http://localhost/cgi-bin/activity3-3/index.py
Verify that you receive the following message in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
The application connects to the databaseeand p rฺ immediately
athen e n t disconnects, displaying an
appropriate message at each stage of
s S tud
onthe process.
Note: If the page does not display
c i t h is you probably have an error in your Python
@as expected,

code. To diagnose the error,
t o ric examine
u s ethe contents of the Apache error log file (located at
e r
/var/log/httpd/error_log
b tothe last
in Oracle classroom environments.) Use a suitable Linux
( ro ens
terminal command to e
display few entries in the log, such as:
i
R i#cctail -10lic/var/log/httpd/error_log
erto
16. Leave Firefox and the Linux terminal window open for the next practice.
b
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 22
Practice 3-4: Executing SQL in a Web Environment with PHP/PDO
Overview
In this practice, you execute queries against a table in the world database and insert a new
record into the table from PHP/PDO code.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You are logged in as the Linux root user at a terminal prompt.
• Mozilla Firefox is open.
• The Apache server is running.

Duration
This practice should take you approximately 20 minutes to complete.
ble
Tasks fe r a
ans
1. Log in to the mysql command line client as the root user (password: oracle).
n - t r
2. Create a new table in the world database called GelderlandDist, which consists of the o
an
Name, District, and CountryCode columns for all cities in the City table within the
s
Gelderland district.
r ) ha ฺ
3. Exit the mysql command line client.
m ฺb uide
contents of the directory. a r ฺco nt G
4. Change the current working directory to /labs/php/web/activity3-4 and list the

o n ep tude
5. Examine the PHP code in the conn.php file in your chosen text editor.
@ s is S
i th
6. Copy the index_start.php file to index.php.
c c
r i e
toฺ to us
7. Examine the contents of the index.php file in your chosen text editor.
e r
8. Under the comment labelled “A. Define the query”, populate the variable $sql1 with a SQL
( rob ense
statement that retrieves all rows from the GelderlandDist table.
i
c lic
to Ric
9. Under the comment labelled “B. Execute the query”, call the appropriate method on the
$dbh connection object to execute the query using the SQL statement in $sql1. Store the
e r returned statement handle in a variable called $sth.
R ob 10. Under the comment labelled “C. Display the returned rows”, create a while loop that
returns a row from the result set as an associative array of column values by using the
$sth->fetch() method. Display the contents of the row to the user as a comma-
separated list of column values. Continue looping through the rows until you have displayed
all the rows in the GelderlandDist table.
11. Under the comment labelled “D. Define the insert”, populate the variable $sql2 with a SQL
statement that inserts a new row into the GelderlandDist table with the following column
values:
• Name: Atlantis
• District: Gelderland
• CountryCode: NLD
12. Under the comment labelled “E. Execute the insert”, call the appropriate method on the
$dbh connection object to execute the INSERT statement in variable $sql2. Store the
return value in a variable called $num and display this value to the user with a suitable
message.
What is the value of $num if the insert operation completes successfully?
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 23
13. Under the comment labelled “F. Execute the first query again and display the returned
rows”, write PHP code to display the contents of the GelderlandDist table. This time,
retrieve the column values in each row using the position of the columns in the row array
instead of the column names. For example, use $row[0] instead of $row["Name"].
14. Under the comment labelled “G. Close the connection to the database server”, write PHP
code to close the connection to the MySQL server and display a suitable message to the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

user.
15. Save and close the index.php file.
16. Open the index.php page in the Firefox browser using the following URL:
http://localhost/php/activity3-4/index.php.
17. Verify that you receive the following messages in the webpage:

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

The application connects to the MySQL server’s world database and displays the contents
of the GelderlandDist table. It then inserts a new row into the table, reports the number
of rows affected, and then displays the new contents of the table. Finally, the application
disconnects from the MySQL server.
18. Close the Firefox browser and any open terminal windows.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 24
Solution 3-4: Executing SQL in a Web Environment with PHP/PDO
Solution Steps
1. Log in to the mysql command line client as the root user (password: oracle).
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -uroot -poracle


mysql: [Warning] Using a password on the command line interface can be
insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.7.7-rc-enterprise-commercial-advanced MySQL
Enterprise Server - Advanced Edition (Commercial)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights
reserved.
ble
fe r a
Oracle is a registered trademark of Oracle Corporation and/or its
ans
affiliates. Other names may be trademarks of their respective
n - t r
no
owners.
a
s current input
Type 'help;' or '\h' for help. Type '\c' to clear the
h a
statement.
ฺ b r) deฺ
mysql>
c o m Gui
2. Create a new table in the world database p a rฺ GelderlandDist,
called e n t which consists of the
Name, District, and CountryCode e
on columns d
tufor all cities in the City table within the
Gelderland district. s s S
Enter the following statementsi c c i@
at thee t hi prompt and receive the results shown:
r t o ฺr us
mysql

e
mysql> USE world
b information t o
Readingotable
(
You i canr turn e n sethis feature for completion of table and column names

c c l i
iDatabase changedc off to get a quicker startup with -A

o R
b e rt mysql> CREATE TABLE GelderlandDist AS
R o -> SELECT Name, District, CountryCode
-> FROM City
-> WHERE District = 'Gelderland';
Query OK, 4 rows affected (#.## sec)
Records: 4 Duplicates: 0 Warnings: 0
The statement creates the GelderlandDist table with four rows.
3. Exit the mysql command line client.
Enter the following command at the mysql prompt and receive the results shown:
mysql> EXIT
Bye
#
4. Change the current working directory to /labs/php/web/activity3-4 and list the
contents of the directory.
Enter the following command at the Linux terminal prompt and receive the results shown:
# cd /labs/php/web/activity3-4
# ls
conn.php index_start.php index_soln.php
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 25
5. Examine the PHP code in the conn.php file in your chosen text editor.
The contents of the conn.php file are as follows:
<?php

# conn.php: utility library for connecting to the MySQL Server


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

try {
# Create the DSN
$dsn = "mysql:host=localhost;dbname=world";

# Connect to the database server


$dbh = new PDO ($dsn, "root", "oracle");
echo "<p>Connected to the database server</p>";
}
catch (PDOException $e) {
die ("<p>Cannot connect to the database server</p>");
ble
}
fe r a
ans
?>
n - t r
This code is the same as you used in the previous activity, except the code that o
disconnects from the MySQL server is removed.
s an
6. Copy the index_start.php file to index.php.
r ) ha ฺ
ฺb uide
Enter the following commands at the Linux terminal prompt and receive the results shown:
m
# cp index_start.php index.php
a r ฺ co nt G
# ls
o n de
ep tuindex_start.php
conn.php index.php index_soln.php
@ s fileisinSyour chosen text editor.
i
7. Examine the contents of the index.php
c h
c file earetas
ฺ r
The contents of the index.php
o i u s follows:
r t o
<html>
r o be se t
c c i ( licen 3-4 (PHP)</title>
<head>

R i</head>
<title>Activity

ert o <body>
b
Ro
<h1>Activity 3-4 (PHP)</h1>
<p>

<?php
require_once "conn.php";

# A. Define the query

# B. Execute the query

echo("<p>Contents of GelderlandDist table:</p>");


# C. Display the returned rows

# D. Define the insert

echo("<p>Inserting new row into table</p>");


# E. Execute the insert

echo("<p>Contents of GelderlandDist table:</p>");


Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 26
# F. Execute the first query again and display the returned rows

# G. Close the connection to the database server

?>
</p>
</body>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

</html>
8. Under the comment labelled “A. Define the query”, populate the variable $sql1 with the
SQL statement that retrieves all rows from the GelderlandDist table.
Enter the following line of code under the comment labelled “A. Define the query”:
...
<?php
require_once "conn.php";

ble
# A. Define the query
fe r a
ns
$sql1 = "SELECT * FROM GelderlandDist";
...
t r a
-the end of
Note: The usual semicolon SQL statement terminator is not required, because o n
the string serves as the statement terminator.
s an
9. Under the comment labelled “B. Execute the query”, call the appropriate
) h a method on the
$dbh connection object to execute the query using the SQL ฺ b rstatement
d e ฺin $sql1. Store the
returned statement handle in a variable called $sth. om t Gu i
r ฺ c
a labelled
Enter the following line of code under the comment n “B. Execute the query”:
e p d e
...
# B. Execute the query s
on s Stu
$sth = $dbh->query($sql1);
c c i@ thi
...
o ฺ r i u se
e t
r labelledt“C. o Display the returned rows”, create a while loop that
b
10. Under the comment e
(rofromcthe
returns ai row
c e s set as an associative array of column values by using the
nresult
ic list oflicolumn
$sth->fetch()
R method. Display the contents of the row to the user as a comma-

ertoall the rows in the GelderlandDist table.


separated values. Continue looping through the rows until you have displayed
b
Ro Enter the following lines of code under the comment labelled “C. Display the returned rows”:
...
echo("<p>Contents of GelderlandDist table:</p>");
# C. Display the returned rows
while ($row = $sth->fetch (PDO::FETCH_ASSOC)) {
printf("%s, %s, %s<br/>", $row["Name"], $row["District"],
$row["CountryCode"]);
}
...
11. Under the comment labelled “D. Define the insert”, populate the variable $sql2 with a SQL
statement that inserts a new row into the GelderlandDist table with the following column
values:
• Name: Atlantis
• District: Gelderland
• CountryCode: NLD
Enter the following line of code under the comment labelled “D. Define the insert”:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 27
...
# D. Define the insert
$sql2 = "INSERT INTO GelderlandDist (Name, District, CountryCode)" .
" VALUES ('Atlantis', 'Gelderland', 'NLD')";
...
12. Under the comment labelled “E. Execute the insert”, call the appropriate method on the
$dbh connection object to execute the INSERT statement in variable $sql2. Store the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

return value in a variable called $num and display this value to the user with a suitable
message.
Enter the following lines of code under the comment labelled “E. Execute the insert”:
...
echo("<p>Inserting new row into table</p>");
# E. Execute the insert
$num = $dbh->exec($sql2);
printf("%s row(s) inserted", $num);
ble
...
fe r a
What is the value of $num if the insert operation completes successfully?
ans
Answer: 1. The exec() function returns the number of rows affected by the operation.
n - t r
no
13. Under the comment labelled “F. Execute the first query again and display the returned
a
h a s
rows”, write PHP code to display the contents of the GelderlandDist table. This time,

ฺ b r) deฺ
retrieve the column values in each row using the position of the columns in the row array
instead of the column names. For example, use $row[0] instead of $row["Name"].
c o m Gui
query again and display the returned rows”:p a rฺ ent
Enter the following lines of PHP code under the comment labelled “F. Execute the first

... s one s Stud


echo("<p>Contents of iGelderlandDist
i c c e hi and
@query tagain table:</p>");

t o ฺ r
# F. Execute the first
u s display the returned rows
r= $sth->fetch
$sth = $dbh->query($sql1);
b e to (PDO::FETCH_NUM)) {
while ($row
(ro cen%s, e
s %s<br/>", $row[0], $row[1], $row[2]);
c c i
printf("%s,
li
Ri...
}

e r
14.
toUnder the comment labelled “G. Close the connection to the database server”, write PHP
R ob code to close the connection to the MySQL server and display a suitable message to the
user.
Enter the following lines of PHP code under the comment labelled “G. Close the connection
to the database server”:
...
# G. Close the connection to the database server
$dbh = NULL;
echo("<p>Disconnected from the database server</p>");

?>
</p>
</body>
</html>
15. Save and close the index.php file.
16. Open the index.php page in the Firefox browser using the following URL:
http://localhost/php/activity3-4/index.php.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 28
17. Verify that you receive the following messages in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
The application connects to the MySQL server’s world database and displays the contents
of the GelderlandDist table. It then inserts a new row into the table, reports the number
of rows affected, and then displays the new contents of the table. Finally, the application
disconnects from the MySQL server.
18. Close the Firefox browser and any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 29
Practice 3-5: Executing SQL in a Web Environment with Connector/J
Overview
In this practice, you execute queries against a table in the world database and insert a new
record into the table from Java/JSTL code.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You are logged in as the Linux root user at a terminal prompt.
• Mozilla Firefox is open.
• The Tomcat server is running.

Duration
This practice should take you approximately 20 minutes to complete.
ble
Tasks fe r a
ans
1. Log in to the mysql command line client as the root user (password: oracle).
n - t r
2. Create a new table in the world database called GelderlandDist, which consists of the o
an
Name, District, and CountryCode columns for all cities in the City table within the
s
Gelderland district.
r ) ha ฺ
3. Exit the mysql command line client.
m ฺb uide
4.
a r ฺco nt G
Change the current working directory to /labs/java/web/activity3-5 and list the
contents of the directory by using the tree command.
5. o n ep tude
Examine the JSTL code in the WEB-INF/conn.inc file in your chosen text editor.
@ s is S
6. i th
Copy the index_start.jsp file to index.jsp.
c c
r i e
toฺ to us
7. Examine the contents of the index.jsp file in your chosen text editor.
8. e r
Under the comment labelled “A. Define the query”, use a <sql:query> tag to define a
( rob ense
query that selects all rows from the GelderlandDist table into a variable called rs.
i
c lic
9.
to Ric
Under the comment labelled “B. Display query results”, use a <c:forEach> tag to iterate
through the collection of rows stored in the variable rs. Retrieve each row by calling the rs
e r collection’s rowsByIndex() method. Display each row as a comma-separated list of
R ob column values.
10. Under the comment labelled “C. Define the update”, use a <sql:update> tag to define a
SQL statement that inserts a new row into the GelderlandDist table with the following
column values:
• Name: Atlantis
• District: Gelderland
• CountryCode: NLD
Specify a variable within the <sql:update> tag to store the return value of the operation,
which is the number of rows affected.
11. Under the comment labelled “D. Report the number of rows affected by the update”, display
the return value of the update operation.
12. Under the comment labelled “E. Requery the database”, reissue the query that lists all the
rows in the GelderlandDist table.
13. Save and close the index.jsp file.
14. Open the index.jsp page in the Firefox browser using the following URL:
http://localhost:8080/activity3-5/index.jsp.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 30
Verify that you receive the following messages in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
15. Close the Firefox browser and any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 31
Solution 3-5: Executing SQL in a Web Environment with Connector/J
Solution Steps
1. Log in to the mysql command line client as the root user (password: oracle).
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -uroot -poracle


mysql: [Warning] Using a password on the command line interface can be
insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.7.7-rc-enterprise-commercial-advanced MySQL
Enterprise Server - Advanced Edition (Commercial)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights
reserved.
ble
fe r a
Oracle is a registered trademark of Oracle Corporation and/or its
ans
affiliates. Other names may be trademarks of their respective
n - t r
no
owners.
a
s current input
Type 'help;' or '\h' for help. Type '\c' to clear the
h a
statement.
ฺ b r) deฺ
mysql>
c o m Gui
2. Create a new table in the world database p a rฺ GelderlandDist,
called e n t which consists of the
Name, District, and CountryCode e
on columns d
tufor all cities in the City table within the
Gelderland district. s s S
Enter the following statementsi c c i@
at thee t hi prompt and receive the results shown:
r t o ฺr us
mysql

e
mysql> USE world
b information t o
Readingotable
(
You i canr turn e n sethis feature for completion of table and column names

c c l i
iDatabase changedc off to get a quicker startup with -A

o R
b e rt mysql> CREATE TABLE GelderlandDist AS
R o -> SELECT Name, District, CountryCode
-> FROM City
-> WHERE District = 'Gelderland';
Query OK, 4 rows affected (#.## sec)
Records: 4 Duplicates: 0 Warnings: 0
The statement creates the GelderlandDist table with four rows.
3. Exit the mysql command line client.
Enter the following command at the mysql prompt and receive the results shown:
mysql> EXIT
Bye
#
4. Change the current working directory to /labs/java/web/activity3-5 and list the
contents of the directory by using the tree command.
Enter the following command at the Linux terminal prompt and receive the results shown:
# cd /labs/java/web/activity3-5
# tree
.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 32
├── index_soln.jsp
├── index_start.jsp
└── WEB-INF
├── classes
├── conn.inc
└── lib
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

3 directories, 3 files
5. Examine the JSTL code in the WEB-INF/conn.inc file in your chosen text editor.
The contents of the WEB-INF/conn.inc file are as follows:
<c:catch var="connexception">
<sql:setDataSource
var="conn"
driver="com.mysql.jdbc.Driver"
ble
url="jdbc:mysql://localhost/world"
user="root" fe r a
password="oracle"
ans
/>
n - t r
</c:catch>
a no
The conn.inc file creates a connection to the world database onsthe MySQL server. This
file is identical to the conn.inc file you created in the previous) a activity.
hJava
ฺ b r d e ฺ
6. Copy the index_start.jsp file to index.jsp. m Gu
oprompt i
ฺ c
a dent and receive the results shown:
Enter the following commands at the Linux terminalr
# cp index_start.jsp index.jspep
# ls s on s Stu
index.jsp index_soln.jsp
i c c e t hi
i@ index_start.jsp WEB-INF
7. Examine the contentsoofฺrthe index.jsp us file in your chosen text editor.
e r t
The contents ofbthe index.jsp t o
( r o n s e file are as follows:
<%@ i taglib uri="http://java.sun.com/jsp/jstl/core"
e
i c c tagliblicuri="http://java.sun.com/jsp/jstl/sql" prefix="c" %>

t o R <%@ include file="/WEB-INF/conn.inc" %>


<%@ prefix="sql" %>

be r
Ro <!DOCTYPE html>
<html>
<head>
<title>Activity 3-5 (Java)</title>
</head>
<body>
<h1>Activity 3-5 (Java)</h1>
<c:choose>
<%-- Unsuccessful connection attempt --%>
<c:when test="${not empty connexception}">
<p>Error connecting to the database</p>
</c:when>
<%-- Successful connection attempt --%>
<c:otherwise>
<p>Connected to the database</p>
</c:otherwise>
</c:choose>

<p>Contents of the GelderlandDist table:</p>

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 33
<%-- A. Define the query --%>

<%-- B. Display query results --%>

<%-- C. Define the update --%>


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<p>Inserting new row into table</p>

<%-- D. Report the number of rows affected by the update --%>

<br/>

<p>Contents of the GelderlandDist table:</p> ble


fe r a
<%-- E. Requery the database --%>
ans
n - t r
<p>Done</p>
</body>
a no
</html>
h a s
The index.jsp file contains JSTL code for connecting tobthe
ฺ r) worldd e ฺ
database server and
o m Gu
some markup for displaying information to the user. There are a i
number of comments that
describe the functionality you must implement. rฺ
a c n t
p e
one s Stud table into a variable called rs.
8. Under the comment labelled “A. Define the query”, use a <sql:query> tag to define a
query that selects all rows from thesGelderlandDist
c
Enter the following lines ofcJSTL
i the comment labelled “A. Define the Query”:
i@markupthunder
o ฺr i us e
...
e r t t o
r o b
<p>Contents
s e
of the GelderlandDist table:</p>

c ( A.ceDefine
i <%-- n the query --%>
R c l i
i <sql:query dataSource="${conn}" var="rs">
ert o SELECT * FROM GelderlandDist
b
Ro
</sql:query>
...
Notes:
− The JSTL <sql:query> tag provides a convenient tag-based equivalent for the
Connector/J Statement.executeQuery() method.
− The usual semicolon SQL statement terminator is not required because the end of
the tag serves as the statement terminator.
9. Under the comment labelled “B. Display query results”, use a <c:forEach> tag to iterate
through the collection of rows stored in the variable rs. Retrieve each row by calling the rs
collection’s rowsByIndex() method. Display each row as a comma-separated list of
column values.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 34
Enter the following lines of JSTL markup under the comment labelled “B. Display query
results”:
...
<%-- B. Display query results --%>
<c:forEach items="${rs.rowsByIndex}" var="row">
<c:out value="${row[0]}, ${row[1]}, ${row[2]}"/><br />
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

</c:forEach>
...
10. Under the comment labelled “C. Define the update”, use a <sql:update> tag to define a
SQL statement that inserts a new row into the GelderlandDist table with the following
column values:
• Name: Atlantis
• District: Gelderland
• CountryCode: NLD
ble
Specify a variable within the <sql:update> tag to store the return value of the operation,
fe r a
which is the number of rows affected.
ans
Enter the following lines of JSTL markup under the comment labelled “C. Define the n - t r
update”:
a no
...
h a s
<%-- C. Define the update --%>
ฺ b r) deฺ
<sql:update dataSource="${conn}" var="num">
o mDistrict,u i CountryCode)
INSERT INTO GelderlandDist (Name,
VALUES ('Atlantis', 'Gelderland', a c
rฺ e'NLD')
n t G
p
one s Stud
</sql:update>
... s
Note: The JSTL <sql:update>
i c c e t hi a convenient tag-based equivalent for the
i@tag provides
r t o ฺr
Connector/J Statement.executeUpdate() us method.
11. Under the comment e
bof thelabelled t o
e “D.operation.
Report the number of rows affected by the update”, display
the return ( r o
value n s
update
i
Enter c ci l
the following i celine of JSTL markup under the comment labelled “D. Report the number
t o R
of rows affected by the update”:
be r
Ro
...
<%-- D. Report the number of rows affected by the update --%>
<c:out value="${num} row(s) affected"/>
<br/>
...
12. Under the comment labelled “E. Requery the database”, reissue the query that lists all the
rows in the GelderlandDist table.
Enter the following lines of JSTL markup under the comment labelled “E. Requery the
database”:
...
<p>Contents of the GelderlandDist table:</p>

<%-- E. Requery the database --%>


<sql:query dataSource="${conn}" var="rs">
SELECT * FROM GelderlandDist
</sql:query>
<c:forEach items="${rs.rowsByIndex}" var="row">
<c:out value="${row[0]}, ${row[1]}, ${row[2]}"/><br />
</c:forEach>
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 35
<p>Done</p>
</body>
</html>
13. Save and close the index.jsp file.
14. Open the index.jsp page in the Firefox browser using the following URL:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

http://localhost:8080/activity3-5/index.jsp.
Verify that you receive the following messages in the webpage:

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

15. Close the Firefox browser and any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 36
Practice 3-6: Executing SQL in a Web Environment with
Connector/Python
Overview
In this practice, you execute queries against a table in the world database and insert a new
record into the table from Python code.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You are logged in as the Linux root user at a terminal prompt.
• Mozilla Firefox is open.
• The Apache server is running.

Duration
ble
This practice should take you approximately 20 minutes to complete.
fe r a
ans
Tasks
n - t r
1. Log in to the mysql command line client as the root user (password: oracle). o
2. s an
Create a new table in the world database called GelderlandDist, which consists of the
r ) ha ฺ
Name, District, and CountryCode columns for all cities in the City table within the
Gelderland district.
m ฺb uide
3. Exit the mysql command line client.
a r ฺco nt G
contents of the directory. o n ep tude
4. Change the current working directory to /labs/python/web/activity3-6 and list the

@ s is S
i th
5. Examine the Python code in the conn.py file in your chosen text editor.
c c
r i e
e r toฺ to us
6. Copy the index_start.py file to index.py.
7. Examine the contents of the index.py file in your chosen text editor.
( rob ense
8. Under the comment labelled “A. Define the query, create a variable called sql1 which
i
c lic
to Ric
contains a SQL statement that retrieves all rows from the GelderlandDist table.
9. Under the comment labelled “B. Execute the query”, call the appropriate method on the
e r
R ob dbconn connection object that returns a cursor to allow you to work with the query results.
Store the returned cursor object in a variable called cursor. Then call the
cursor.execute() method, passing in the SQL statement you created in the previous
step.
10. Under the comment labelled “C. Display query results”, create a for loop that uses the
cursor object to retrieve rows from the GelderlandDist table. Display the contents of
each row to the user as a comma-separated list of column values. Call the appropriate
method on the cursor object to close the cursor when you have retrieved all the rows.
11. Under the comment labelled “D. Define the insert”, create a variable called sql2 which
contains a SQL statement that inserts a new row into the GelderlandDist table with the
following column values:
• Name: Atlantis
• District: Gelderland
• CountryCode: NLD

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 37
12. Under the comment labelled “E. Execute the insert”:
• Create a new cursor from the dbconn connection object. Call the
cursor.execute() method, passing in the sql2 SQL statement you created in the
previous step.
• Call dbconn.commit() to persist the change. (This is important, because
Connector/Python does not support autocommit, which is discussed in the lesson
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

titled “Transactions.”)
• Use the cursor.rowcount property to display the number of rows affected by the
insert operation to the user.
What is the value of cursor.rowcount when the insert operation completes
successfully?
13. Under the comment labelled “F. Execute the first query again and display the returned
rows”, write Python code to display the contents of the GelderlandDist table. Close the
cursor object you created in the previous step when you have displayed all the rows. ble
14. Make the index.py and conn.py files executable. fe r a
ans
15. Save and close the index.py file.
n - t r
16. Open the index.py page in the Firefox browser using the following URL: o
http://localhost/cgi-bin/activity3-6/index.py.
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 38
17. Verify that you receive the following messages in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
18. Close the Firefox browser and any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 39
Solution 3-6: Executing SQL in a Web Environment with
Connector/Python
Solution Steps
1. Log in to the mysql command line client as the root user (password: oracle).
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following command at the Linux terminal prompt and receive the results shown:
# mysql -uroot -poracle
mysql: [Warning] Using a password on the command line interface can be
insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.7.7-rc-enterprise-commercial-advanced MySQL
Enterprise Server - Advanced Edition (Commercial)

ble
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights
reserved. fe r a
ans
Oracle is a registered trademark of Oracle Corporation and/or its
n - t r
affiliates. Other names may be trademarks of their respective
a no
owners.
h a s
Type 'help;' or '\h' for help. Type '\c' to clear
ฺ b r) dtheeฺcurrent input
statement.
c o m Gui
mysql>
p a rฺ ent
2. Create a new table in the world database
s one called
S ud
tGelderlandDist, which consists of the
Name, District, and CountryCode
c i @ t h i s
columns for all cities in the City table within the
Gelderland district. i c
ฺr atuthe e
s mysql prompt and receive the results shown:
e t o
Enter the following rstatements t o
mysql>ro b worldse
c i ( USE
c e ninformation for completion of table and column names
R c
Reading
l i
table
iYou can turn off this feature to get a quicker startup with -A
ert o
b
Ro
Database changed
mysql> CREATE TABLE GelderlandDist AS
-> SELECT Name, District, CountryCode
-> FROM City
-> WHERE District = 'Gelderland';
Query OK, 4 rows affected (#.## sec)
Records: 4 Duplicates: 0 Warnings: 0
The statement creates the GelderlandDist table with four rows.
3. Exit the mysql command line client.
Enter the following command at the mysql prompt and receive the results shown:
mysql> EXIT
Bye
#

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 40
4. Change the current working directory to /labs/python/web/activity3-6 and list the
contents of the directory.
Enter the following command at the Linux terminal prompt and receive the results shown:
# cd /labs/python/web/activity3-6
# ls
conn.py index_soln.py index_start.py
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

5. Examine the Python code in the conn.py file in your chosen text editor.
The contents of the conn.py file are as follows:
# conn.py: library file for connecting to MySQL using the
# Connector/Python module

import mysql.connector

conn = None
ble
conn_params = { fe r a
"database": "world",
ans
"host": "localhost",
n - t r
"user": "root",
"password": "oracle" a no
}
h a s
ฺ b r) deฺ
def dbconnect():
c o m Gui
try:
global conn
p a rฺ ent
ne Stud
conn = mysql.connector.connect(**conn_params)
print('''<p>Connectedso
@ this
to the database</p>''')
return conn
c i
except:
t o ฺ ric not u seconnect to the database</p>''')
r
print('''<p>Could
b e to
This code isro
( the same e
nass youfile
used in the previous activity.
c i li c e
6. Copy
R ic the index_start.py to index.py.

e r toEnter the following commands at the Linux terminal prompt and receive the results shown:
R ob # cp index_start.py index.py
# ls
conn.py index.py index_soln.py index_start.py
7. Examine the contents of the index.py file in your chosen text editor.
The contents of the index.py file are as follows:
#!/usr/bin/python

import conn

print('''Content-Type: text/html

<html>
<head><title>Activity 3-6 (Python)</title></head>
<body>
''')

print("<h1>Activity 3-6 (Python)</h1>")

# Connect to the database

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 41
dbconn = conn.dbconnect()

# A. Define the query

print("<p>Contents of GelderlandDist table:</p>")


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# B. Execute the query

# C. Display query results

# D. Define the insert

print("<p>Inserting new row into table</p>") ble


fe r a
# E. Execute the insert
ans
n - t r
print("<p>Contents of GelderlandDist table:</p>")
a no
# F. Execute the first query again and display) the h asreturned rows
ฺ b r deฺ
c o m Gui
print("<p>Disconnecting from the database
p a rฺ enserver</p>")
t
dbconn.close()
s o ne Stud
print('''
c i @ t h is
</body>
t o ฺ ric use
</html>
b e r to
''')
ro elabelled
(comment e
ns “A. Define the query, create a variable called sql1 which
8. Under the
c i i c
R ic a SQL lstatement
contains that retrieves all rows from the GelderlandDist table.
o
ert Enter the following lines of code under the comment labelled “A. Define the query”:
b
Ro ...
# A. Define the query
sql1 = '''
SELECT * FROM GelderlandDist
'''
...
Note: The usual semicolon SQL statement terminator is not required, because the end of
the string serves as the statement terminator.
9. Under the comment labelled “B. Execute the query”, call the appropriate method on the
dbconn connection object that returns a cursor to allow you to work with the query results.
Store the returned cursor object in a variable called cursor. Then call the
cursor.execute() method, passing in the SQL statement you created in the previous
step.
Enter the following lines of code under the comment labelled “B. Execute the query”:
...
print("<p>Contents of GelderlandDist table:</p>")

# B. Execute the query


Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 42
cursor = dbconn.cursor()
cursor.execute(sql1)
...
10. Under the comment labelled “C. Display query results”, create a for loop that uses the
cursor object to retrieve rows from the GelderlandDist table. Display the contents of
each row to the user as a comma-separated list of column values. Call the appropriate
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

method on the cursor object to close the cursor when you have retrieved all the rows.
Enter the following lines of code under the comment labelled “C. Display query results”:
...
# C. Display query results
for (name, district, countrycode) in cursor:
print("%s, %s, %s<br />" % (name, district, countrycode))
cursor.close()
...
11. Under the comment labelled “D. Define the insert”, create a variable called sql2 which ble
contains a SQL statement that inserts a new row into the GelderlandDist table with the fe r a
following column values: ans
• Name: Atlantis n - t r
• District: Gelderland a no
• CountryCode: NLD h a s
ฺ b r) deฺ
c o m Gui
Enter the following line of code under the comment labelled “D. Define the update”:
...
p a rฺ ent
ne Stud
# D. Define the insert
sql2 = '''
s o
c i @
INSERT INTO GelderlandDist (Name,
t h is District, CountryCode)

ric use
VALUES ('Atlantis', 'Gelderland', 'NLD')
'''
r t o ฺ
...
b e e to
12. Under the
i ro elabelled
(comment ns “E. Execute the insert”:
c
c a new
• iCreate
c
li cursor from the dbconn connection object. Call the
R
berto cursor.execute() method, passing in the sql2 SQL statement you created in the
previous step.
Ro • Call dbconn.commit() to persist the change. (This is important, because
Connector/Python does not support autocommit, which is discussed in the lesson
titled “Transactions.”)
• Use the cursor.rowcount property to display the number of rows affected by the
insert operation to the user.
Enter the following lines of code under the comment labelled “E. Execute the insert”:
...
print("<p>Inserting new row into table</p>")

# E. Execute the insert


cursor = dbconn.cursor()
cursor.execute(sql2)
dbconn.commit()
print("<p>%d rows affected</p>" % cursor.rowcount)
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 43
What is the value of cursor.rowcount when the insert operation completes
successfully? Answer: 1.The value of cursor.rowcount corresponds to the number of
rows affected by the operation.
13. Under the comment labelled “F. Execute the first query again and display the returned
rows”, write Python code to display the contents of the GelderlandDist table. Close the
cursor object you created in the previous step when you have displayed all the rows.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following lines of Python code under the comment labelled “F. Execute the first
query again and display the returned rows”:
...
print("<p>Contents of GelderlandDist table:</p>")

# F. Execute the first query again and display the returned rows
cursor.execute(sql1)
for (name, district, countrycode) in cursor:
print("%s, %s, %s<br />" % (name, district, countrycode))
ble
cursor.close()
fe r a
...
ans
14. Make the index.py and conn.py files executable.
n - t r
o
an
Enter the following commands at the Linux terminal prompt and receive the results shown:
s
# chmod +x index.py conn.py
# ls -al
r ) ha ฺ
total 24
m ฺb uide
drwxr-xr-x 2 root root 4096 May 11 16:37
drwxr-xr-x. 4 root root 4096 May a
co ...t G
11rฺ16:25 n
-rwxr-xr-x 1 root root 453 May
o n ep 11 u de conn.py
16:26
t
-rwxr-xr-x 1 root root 1241
@ s Mayis11S16:37 index_soln.py
May 11 16:36 index.py
-rwxr-xr-x 1 root root
r i c ci 6791241
e h 11 16:34 index_start.py
tMay
toฺ tofile. us
-rw-r--r-- 1 root root
15. Save and close thee rindex.py
( rob enpage
16. Open the index.py
i sein the Firefox browser using the following URL:
icc lic
http://localhost/cgi-bin/activity3-6/index.py.
R
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 44
17. Verify that you receive the following messages in the webpage:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
18. Close the Firefox browser and any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 45
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 3: Using Connectors


Chapter 3 - Page 46
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 4:
Prepared u i
om Statements
r ฺ c
a 4 den t G
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 1
Practices for Lesson 4: Prepared Statements
Practices Overview
These practices test your knowledge of using prepared statements in MySQL. They assume
that you are using the Linux operating system environment provided in Oracle classrooms. For
non-Oracle classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Important: The coding practices in this lesson are available in PHP, Java, and Python. Perform
all the practices for this and all future coding activities in only one language, choosing the
language you are most familiar with. If in doubt, perform the PHP activities. Ensure that you
complete all practices that are not language-specific
For this lesson, perform the following practices:
• Practice 4-1: Preparing Statements in MySQL
• If your chosen programming language is PHP: ble
− Practice 4-2: Using Prepared Statements with PHP/PDO fe r a
ans
• If your chosen programming language is Java:
n - t r
− Practice 4-3: Using Prepared Statements with Connector/J o
• If your chosen programming language is Python: s an
) ha ฺ
− Practice 4-4: Using Prepared Statements with Connector/Python
r
m ฺb uide
Assumptions
a r ฺ co nt G
• If you are completing the coding practices
o n e p in PHP:
t u de
− The Apache web server is running on S
port 80
i @s practices
• If you are completing theccoding t h i s in Java:
r i c e
− The Tomcat tapplication
r us is running on port 8080
oฺ to server
• If you areo b e
completing ethe coding practices in Python:
( r
i Apache n s
i− cThe
c l i ceweb server is installed and running on port 80.
•R The sakila sample database is installed
r t o
R obe • The film2.sql file is available in the /labs/sql directory

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 2
Practice 4-1: Preparing Statements in MySQL
Overview
In this practice, you work with prepared statements directly on the database server.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 10 minutes to complete.

Tasks
1. Use the mysql command-line client to connect to the MySQL server as the root user
(password: oracle).
2. Create a prepared statement called mystmt. The statement selects the title from the film
table in the sakila database for a given film_id, which you provide in a variable.
ble
3. Create a variable called fid and set its value to 803.
fe r a
4. Execute the prepared statement with the variable created in the preceding step.
ans
5. Assign 380 to the fid variable.
n - t r
o
6.
7. s an
Re-execute the prepared statement with the new variable value.
Issue a statement which explicitly removes the prepared statement.
8. r ) ha ฺ
Keep the mysql command-line client open for the next practice.
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 3
Solution 4-1: Preparing Statements in MySQL
Solution Steps
1. Use the mysql command-line client to connect to the MySQL server as the root user
(password: oracle).
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql –u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
2. Create a prepared statement called mystmt. The statement selects the title from the film
table in the sakila database for a given film_id, which you provide in a variable.
Enter the following statement at the mysql prompt and receive the results shown: ble
fe r a
mysql> USE sakila
ans
Reading table information
... n - t r
Database changed
a no
mysql> PREPARE mystmt FROM
-> 'SELECT title FROM film WHERE film_id=?'; h a s
Query OK, 0 rows affected (#.## sec)
ฺ b r) deฺ
Statement prepared
c o m Gui
rฺ803. ent
3. Create a variable called fid and set its valueato
p
ne prompt
Enter the following statement at the mysql
o d receive the results shown:
tuand
mysql> SET @fid = 803;@
s S
issec)
c i t h
t o ฺ ric use
Query OK, 0 rows affected (#.##
4. Execute the prepared
b e r statement
to with the variable created in the preceding step.
(ro cestatement
Enter the following e
ns at the mysql prompt and receive the results shown:
c c i li mystmt USING @fid;
R imysql> EXECUTE

erto | title
+------------------+
|
b
Ro +------------------+
| SLACKER LIAISONS |
+------------------+
1 row in set (#.## sec)
5. Assign 380 to the fid variable.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SET @fid = 380;
Query OK, 0 rows affected (#.## sec)
6. Re-execute the prepared statement with the new variable value.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> EXECUTE mystmt USING @fid;
+----------------+
| title |
+----------------+
| GREEK EVERYONE |
+----------------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 4
7. Issue a statement which explicitly removes the prepared statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> DEALLOCATE PREPARE mystmt;
Query OK, 0 rows affected (#.## sec)
8. Keep the mysql command-line client open for the next practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 5
Practice 4-2: Using Prepared Statements with PHP/PDO
Overview
In this practice, you create a prepared statement to insert a new row into a table using
information supplied by a user. You then test a PHP script to see if it is vulnerable to a SQL
injection attack and make any necessary changes to prevent this from occurring.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a Linux terminal window open logged in as the root user (password:
oracle).
• The Apache web server is installed and running on port 80.

Duration
This practice should take you approximately 30 minutes to complete. ble
fe r a
Tasks
t r a ns
1. Display the contents of the /labs/sql/film2.sql file in the Linux terminal.nWhat
o - does
the SQL code in this file do?
2. Execute the /labs/sql/film2.sql script to create the film2a s ainnthe sakila
table
database. r ) h ฺ
3. Verify that the film2 table exists and contains 1,000m
b
ฺ uide
records.
r
4. Change the current working directory to /labs/php/web/activity4-2
o
ฺc nt G and list the files
within that directory. p
e tuda e
5. Copy the addfilm_start.php file s otonaddfilm.php.
s S
i @ h i
6. Copy the findfilm_start.php
ฺ r i cc sfileetot findfilm.php
7. Examine the contents r o u
toof the tindex.html file in a text editor such as vi, emacs, or gedit.
e
rob Clicking
The index.html
field andi a(button.
file
e n s e
displays
the
a simple
button for
webpage
the “New
with two forms. Each form contains a text
Film” text box invokes the
i c c l i c
script, and clicking the button for the “Search Films” text box invokes the
o R
addfilm.php

ert
findfilm.php script.
b
Ro
8. Examine the contents of the addfilm.php file in your chosen text editor. You complete
the code in the addfilm.php file to insert a new row into the films2 table.
9. Examine the contents of the findfilm.php file in your chosen text editor. The PHP code
in the findfilm.php file enables a user to search for a film by its title.
10. In the addfilm.php file, enter code under the comment labelled “A. Prepare the insert
statement” to prepare a statement that inserts a new row into the films2 table. Use
named placeholders for the title and description columns.
11. In the addfilm.php file, enter code under the comment labelled “B. Bind parameters”, and
enter code to bind local variables to the named parameters in the SQL statement.
12. In the addfilm.php file, enter code under the comment labelled “C. Execute the insert
statement” to execute the prepared statement you created in the preceding step. The
execute() method must pass an array of column values. Populate the title column
with the name of the new film title supplied by the user. For the description column,
enter any text string.
13. Save your work, open the Firefox browser and visit the following URL:
http://localhost/php/activity4-2/index.html.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 6
14. Enter “ANOTHER TRIP” into the “New Film” text box and click its associated “Submit
Query” button.
15. Verify that the row has been added to the table. Navigate back to the main page of your
application by clicking the Firefox browser’s “back” button. Enter “ANOTHER TRIP” into the
“Search Films” text box and click its associated “Submit Query” button.
16. The query in the findfilm.php script is not a prepared statement and there is no
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

validation of the value the user enters. This makes it vulnerable to SQL injection attacks by
malicious users. Enter the following expression exactly as shown into the “Search Films”
text box and click its associated “Submit Query” button. What happens, and why?
' OR 'X' = 'X
17. In the findfilm.php script, comment out the existing query.
18. Under the comment labelled “D. Replace the query with a prepared statement”, rewrite the
query as a prepared statement.
19. Save the findfilm.php file and reload the index.html page in Firefox. Enter the ble
following expression exactly as shown into the “Search Films” text box. Click its associated fe r a
“Submit Query” button. What happens this time, and why? ans
n - t r
' OR 'X' = 'X
o
20. Close Firefox and any open terminal windows. s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 7
Solution 4-2: Using Prepared Statements with PHP/PDO
Solution Steps
1. Display the contents of the /labs/sql/film2.sql file in the Linux terminal. What does
the SQL code in this file do?
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/sql/
# cat film2.sql
USE sakila
DROP TABLE IF EXISTS `film2`;
CREATE TABLE `film2` AS SELECT `film_id`, `title`, `description` FROM
`film`;
ALTER TABLE `film2` MODIFY `film_id` SMALLINT(5) UNSIGNED NOT NULL
PRIMARY KEY AUTO_INCREMENT;
ble
Answer: The SQL in film2.sql creates a copy of the film table in the sakila
fe r a
database called film2, preserving only the film_id, title and description columns.
ans
The ALTER TABLE statement adds the auto_increment and primary key attributes to
the film_id column. n - t r
2. a no
Execute the /labs/sql/film2.sql script to create the film2 table in the sakila
database. h a s
ฺ b r) deฺ
Enter the following command at the Linux terminal prompt and receive the results shown:
# mysql -uroot -poracle < film2.sql com u i
mysql: [Warning] Using a passwordaon n G
rฺ the ecommand
t line interface can be
p
one s Stud
insecure.
# s
i c
3. Verify that the film2 tablecexists
e hi 1,000 records.
i@and contains
t
t o ฺr at the
Enter the following rcommand usLinux terminal prompt and receive the results shown:
e t o
i ( r b en-poracle
# mysqlo-uroot se\ \

i>ccSHOW CREATE
lic TABLE film2\G \
> -e "USE sakila;
R
erto mysql: [Warning] Using a password on the command line interface can be
> SELECT COUNT(*) FROM film2;"
b
Ro insecure.
*************************** 1. row ***************************
Table: film2
Create Table: CREATE TABLE `film2` (
`film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8,
PRIMARY KEY (`film_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1
+----------+
| COUNT(*) |
+----------+
| 1000 |
+----------+
[root@edddr9p1 sql]#
4. Change the current working directory to /labs/php/web/activity4-2 and list the files
within that directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/php/web/activity4-2
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 8
# ls
addfilm_soln.php addfilm_start.php conn.php findfilm_soln.php
findfilm_start.php index.html
5. Copy the addfilm_start.php file to addfilm.php.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp addfilm_start.php addfilm.php
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# ls
addfilm.php addfilm_start.php findfilm_soln.php index.html
addfilm_soln.php conn.php findfilm_start.php
6. Copy the findfilm_start.php file to findfilm.php
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp findfilm_start.php findfilm.php
# ls
addfilm.php addfilm_start.php findfilm.php
ble
findfilm_start.php
fe r a
addfilm_soln.php conn.php findfilm_soln.php index.html
an s
7. Examine the contents of the index.html file in a text editor such as vi, emacs, or gedit.
n - t r
o
an
The index.html file displays a simple web page with two forms. Each form contains a text
field and a button. Clicking the button for the “New Film” text box invokes the
s
r ) ha ฺ
addfilm.php script, and clicking the button for the “Search Films” text box invokes the
findfilm.php script.
m ฺb uide
a r ฺ co nt G
The index.html file contains the following HTML markup:
<!doctype html>
<html>
o n ep tude
<head>
@ s is S
c i
<title>Activity 4-2 (PHP)</title>
c th
</head>
r i
oฺ (PHP)</h1>us e
<body>
e r t4-2 t o
rob ense
<h1>Activity
<p>
i (
cc
Ri<br/><br/>lic
e r to <form action="addfilm.php" method="post">

R ob New Film: <input type="text" name="name">


<input type="submit">
</form>

<form action="findfilm.php" method="post">


Search Films: <input type="text" name="name">
<input type="submit">
</form>

<br/><br/>

</body>
</html>
8. Examine the contents of the addfilm.php file in your chosen text editor. You complete
the code in the addfilm.php file to insert a new row into the films2 table.
The addfilm.php file contains the following PHP code:
<?php

require_once "conn.php";

# Retrieve name of film submitted by the user


Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 9
$newFilm = $_POST["name"];

# A. Prepare the insert statement

# B. Bind Parameters
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# C. Execute the insert statement

echo $newFilm . " added to the database";

?>
9. Examine the contents of the findfilm.php file in your chosen text editor. The PHP code
in the findfilm.php file enables a user to search for a film by its title.
The findfilm.php file contains the following PHP code: ble
fe r a
<?php
ans
require_once "conn.php";
n - t r
a no
# Retrieve search text submitted by the user h a s
$title = $_POST["name"];
ฺ b r) deฺ
o m WHERE u i
$sql = "SELECT title, description FROM
a r ฺ c film2
n t G title = '" . $title
. "'";
$sth = $dbh->query($sql);
o n ep tude
@ s is S
# D. Replace the query
c c i with athprepared statement
r i e
e r toฺ to us
i ( rob ense $sql);
printf("<p>%s</p>",

c c
echo
l i c
"<p><strong>Search results:</strong></p>";

to Ri printf("%s<br/>", $row[0]
while ($row = $sth->fetch (PDO::FETCH_NUM)) {
. ": " . $row[1]);
e r
ob
}
R ?>
10. In the addfilm.php file, enter code under the comment labelled “A. Prepare the insert
statement” to prepare a statement that inserts a new row into the films2 table. Use
named placeholders for the title and description columns.
Enter the following PHP code in the addfilm.php file under the comment labelled “A.
Prepare the insert statement”:
<?php

require_once "conn.php";

# Retrieve name of film submitted by the user


$newFilm = $_POST["name"];

# A. Prepare the insert statement


$psh = $dbh->prepare("INSERT INTO film2 (title, description)
VALUES(:title, :description)");

# B. Bind parameters

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 10
# C. Execute the insert statement

echo $newFilm . " added to the database";

?>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

11. In the addfilm.php file, enter code under the comment labelled “B. Bind parameters”, and
enter code to bind local variables to the named parameters in the SQL statement.
Enter the following PHP code in the addfilm.php file under the comment labelled “B.
Bind parameters”:
...
# B. Bind Parameters
$psh->bindParam(':title', $title);
$psh->bindParam(':description', $description);
ble
...
fe r a
12. In the addfilm.php file, enter code under the comment labelled “C. Execute the insert
ans
statement” to execute the prepared statement you created in the preceding step. The
n - t r
o
an
execute() method must pass an array of column values. Populate the title column

enter any text string.


s
with the name of the new film title supplied by the user. For the description column,
ha ฺ
r )
ฺb uide
Enter the following PHP code in the addfilm.php file under the comment labelled “A.
Prepare the insert statement”: m
co nt G
a r ฺ
...
o n ep bytuthedeuser
@
$newFilm = $_POST["name"];s is S
# Retrieve name of film submitted
i th
cc statement
...
i
# C. Execute theฺrinsert e
e r to to us
$title = $newFilm;

i ( rob e=n"Temporary
$description se description";

cc lic
$psh->execute();
Ri...
e r
13.toSave your work, open the Firefox browser and visit the following URL:
R ob http://localhost/php/activity4-2/index.html.
The browser displays the following web page:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 11
14. Enter “ANOTHER TRIP” into the “New Film” text box and click its associated “Submit
Query” button.
The browser redirects to the addfilm.php script and inserts the new row into the film2
table:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

15. Verify that the row has been added to the table. Navigate back to the main page of your
application by clicking the Firefox browser’s “back” button. Enter “ANOTHER TRIP” into the
ble
“Search Films” text box and click its associated “Submit Query” button.
fe r a
The browser redirects to the findfilm.php script to display the new row in the film2
ans
table and the SQL statement that it used to locate the row.
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
16. The c in thelifindfilm.php script is not a prepared statement and there is no
Riquery
e r tovalidation of the value the user enters. This makes it vulnerable to SQL injection attacks by
R ob malicious users. Enter the following expression exactly as shown into the “Search Films”
text box and click its associated “Submit Query” button. What happens, and why?
' OR 'X' = 'X
Answer: The findfilm.php script displays the entire contents of the film2 table. This is
because the actual query generated by the script is as follows:
SELECT title, description FROM film2 WHERE title = '' OR 'X' = 'X'
The initial single quote you entered terminated the first search string, allowing you to
append an OR clause to the SQL expression. Because 'X' always equals 'X', the expression
evaluates to true for every record in the film2 table. This could potentially be a security
risk, especially if the table contains sensitive information.
17. In the findfilm.php script, comment out the existing query.
Comment out the following lines in the findfilm.php script:
<?php

require_once "conn.php";

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 12
# Retrieve search text submitted by the user
$title = $_POST["name"];

# $sql = "SELECT title, description FROM film2 WHERE title ...


# $sth = $dbh->query($sql);

# D. Replace the query with a prepared statement


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

printf("<p>%s</p>", $sql);
echo "<p><strong>Search results:</strong></p>";
while ($row = $sth->fetch (PDO::FETCH_NUM)) {
printf("%s<br/>", $row[0] . ": " . $row[1]);
}
?>
18. Under the comment labelled “D. Replace the query with a prepared statement”, rewrite the
query as a prepared statement.
ble
Enter the following PHP code under the comment labelled “D. Replace the query with a
fe r a
prepared statement.”
ans
... n - t r
# D. Replace the query with a prepared statement
a no
h a s
$sql = "SELECT title, description FROM film2 WHERE title = :title";

r) deฺ
$sth = $dbh->prepare($sql);
$sth->bindParam(':title', $title);
ฺ b
m Gui
$sth->execute();
c o
rฺ ent
p a
ne Stud
printf("<p>%s</p>", $sql);
o
echo "<p><strong>Search results:</strong></p>";
s
@ t.hi":s " . $row[1]);
while ($row = $sth->fetch (PDO::FETCH_NUM))
printf("%s<br/>",ci$row[0]
{

}
t o ฺ ric use
?>
b e r to
e
(ro cens file and reload the index.html page in Firefox. Enter the
19. Save the findfilm.php
c i li exactly as shown into the “Search Films” text box. Click its associated
R ic Query”
following expression

erto
“Submit button. What happens this time, and why?
b
Ro
' OR 'X' = 'X
Answer: The server is unable to process the query. SQL injection is a risk because user
input is used as part of the SQL statement. By using prepared statements you can force the
user input to be handled as the content of a parameter and not as a part of the SQL
statement.
20. Close Firefox and any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 13
Practice 4-3: Using Prepared Statements with Connector/J
Overview
In this practice, you create a prepared statement to insert a new row into a table using
information supplied by a user. You then test a Java Server Page to see if it is vulnerable to a
SQL injection attack and make any necessary changes to prevent this from occurring.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a Linux terminal window open logged in as the root user (password:
oracle).
• The Tomcat application server is installed and running on port 8080.

Duration
This practice should take you approximately 30 minutes to complete. ble
fe r a
Tasks
t r a ns
1. Display the contents of the /labs/sql/film2.sql file in the Linux terminal.nWhat
o - does
the SQL code in this file do?
2. Execute the /labs/sql/film2.sql script to create the film2a s ainnthe sakila
table
database. r ) h ฺ
3. Verify that the film2 table exists and contains 1,000m
b
ฺ uide
records.
r o
ฺc nt G
4. Change the current working directory to /labs/java/web/activity4-3 and list the files
within that directory and its subdirectories. p
e tuda e
5. Copy the addfilm_start.jsp file s otonaddfilm.jsp.
s S
i @ h i
6. Copy the findfilm_start.jsp
ฺ r i cc sfileetot findfilm.jsp.
7. Examine the contents r o u
toof the tindex.html file in a text editor such as vi, emacs, or gedit.
e
rob Clicking
The index.html
field andi a(button.
file
e n s e
displays
the
a simple
button for
web
the
page with two forms. Each form contains a text
“New Film” text box invokes the
i c c l i c
page, and clicking the button for the “Search Films” text box invokes the
o R
addfilm.jsp

ert
findfilm.jsp page.
b
Ro
8. Examine the contents of the addfilm.jsp file in your chosen text editor. You complete
the code in the addfilm.jsp file to insert a new row into the films2 table.
9. Examine the contents of the findfilm.jsp file in your chosen text editor. The code in the
findfilm.jsp file enables a user to search for a film by its title.
10. In the addfilm.jsp file, enter a <sql:update> tag under the comment labelled “A.
Prepare and execute the insert statement” to prepare and execute a statement that inserts
a new row into the films2 table. Use placeholders for the title and description
columns, and supply the actual values to the statement by using <sql:param> tags.
Populate the title column with the name of the new film title supplied by the user. For the
description column, supply any text string.
11. Save your work, open the Firefox browser and visit the following URL:
http://localhost:8080/activity4-3/index.html.
12. Enter “ANOTHER TRIP” into the “New Film” text box and click its associated “Submit
Query” button.
13. Verify that the row has been added to the table. Navigate back to the main page of your
application by clicking the Firefox browser’s “back” button. Enter “ANOTHER TRIP” into the
“Search Films” text box and click its associated “Submit Query” button.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 14
14. The query in the findfilm.jsp page is not a prepared statement and there is no
validation of the value the user enters. This makes it vulnerable to SQL injection attacks by
malicious users. Enter the following expression exactly as shown into the “Search Films”
text box and click its associated “Submit Query” button. What happens, and why?
' OR 'X' = 'X
15. In the findfilm.jsp page under the comment labelled “B. Replace the query with a
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

prepared statement”, rewrite the query as a prepared statement.


16. Save the findfilm.jsp file and reload the index.html page in Firefox. Enter the
following expression exactly as shown into the “Search Films” text box. Click its associated
“Submit Query” button. What happens this time, and why?
' OR 'X' = 'X
17. Close Firefox and any open terminal windows.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 15
Solution 4-3: Using Prepared Statements with Connector/J
Solution Steps
1. Display the contents of the /labs/sql/film2.sql file in the Linux terminal. What does
the SQL code in this file do?
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/sql/
# cat film2.sql
USE sakila
DROP TABLE IF EXISTS `film2`;
CREATE TABLE `film2` AS SELECT `film_id`, `title`, `description` FROM
`film`;
ALTER TABLE `film2` MODIFY `film_id` SMALLINT(5) UNSIGNED NOT NULL
PRIMARY KEY AUTO_INCREMENT;
ble
Answer: The SQL in film2.sql creates a copy of the film table in the sakila
fe r a
database called film2, preserving only the film_id, title, and description
ans
columns. The ALTER TABLE statement adds the auto_increment and primary key
attributes to the film_id column. n - t r
2. a no
Execute the /labs/sql/film2.sql script to create the film2 table in the sakila
database. h a s
ฺ b r) deฺ
Enter the following command at the Linux terminal prompt and receive the results shown:
# mysql -uroot -poracle < film2.sql com u i
mysql: [Warning] Using a passwordaon n G
rฺ the ecommand
t line interface can be
p
one s Stud
insecure.
# s
i c
3. Verify that the film2 tablecexists
e hi 1,000 records.
i@and contains
t
t o ฺr at the
Enter the following rcommand usLinux terminal prompt and receive the results shown:
e t o
i ( r b en-poracle
# mysqlo-uroot se\ \

i>ccSHOW CREATE
lic TABLE film2\G \
> -e "USE sakila;
R
erto mysql: [Warning] Using a password on the command line interface can be
> SELECT COUNT(*) FROM film2;"
b
Ro insecure.
*************************** 1. row ***************************
Table: film2
Create Table: CREATE TABLE `film2` (
`film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8,
PRIMARY KEY (`film_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1
+----------+
| COUNT(*) |
+----------+
| 1000 |
+----------+
[root@edddr9p1 sql]#
4. Change the current working directory to /labs/java/web/activity4-3 and list the files
within that directory and its subdirectories.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/java/web/activity4-3
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 16
# tree
.
├── addfilm_soln.jsp
├── addfilm_start.jsp
├── findfilm_soln.jsp
├── findfilm_start.jsp
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

├── index.html
└── WEB-INF
├── classes
├── conn.inc
└── lib

3 directories, 6 files
5. Copy the addfilm_start.jsp file to addfilm.jsp.
Enter the following commands at the Linux terminal prompt and receive the results shown: ble
fe r a
# cp addfilm_start.jsp addfilm.jsp
# ls
t r a ns
addfilm.jsp addfilm_soln.jsp addfilm_start.jsp
o n -
findfilm_soln.jsp
findfilm_start.jsp index.html WEB-INF
s an
6. Copy the findfilm_start.jsp file to findfilm.jsp.
) h a
Enter the following commands at the Linux terminal prompt ฺ b r e
and receive
d ฺ the results shown:
# cp findfilm_start.jsp findfilm.jsp om u i
# ls r
a denฺ c t G
addfilm.jsp addfilm_soln.jsp ep
o n
s is S
findfilm_soln.jsp findfilm_start.jsp t u
addfilm_start.jsp
index.html
findfilm.jsp
WEB-INF
7. Examine the contents of the i @
cindex.html th file in a text editor such as vi, emacs, or gedit.
r i c e
s web page with two forms. Each form contains a text
field and a button.e t ฺ the
The index.html fileodisplays
r
Clicking t o
ausimple
button for the “New Film” text box invokes the
i
addfilm.jsp( robpage,e n seclicking the button for the “Search Films” text box invokes the
and
icc
findfilm.jsp
R
c
lipage.
e r toThe index.html file contains the following HTML markup:
R ob <!doctype html>
<html>
<head>
<title>Activity 4-3 (Java)</title>
</head>
<body>
<h1>Activity 4-3 (Java)</h1>
<p>

<br/><br/>

<form action="addfilm.jsp" method="post">


New Film: <input type="text" name="name">
<input type="submit">
</form>

<form action="findfilm.jsp" method="post">


Search Films: <input type="text" name="name">
<input type="submit">
</form>

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 17
<br/><br/>

</body>
</html>
8. Examine the contents of the addfilm.jsp file in your chosen text editor. You complete
the code in the addfilm.jsp file to insert a new row into the films2 table.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

The addfilm.jsp file contains the following Java/JSTL code:


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ include file="/WEB-INF/conn.inc" %>

<c:choose>
<%-- Unsuccessful connection attempt --%>
<c:when test="${not empty connexception}">
<p>Error connecting to the database server</p>
ble
</c:when>
fe r a
<%-- Successful connection attempt --%>
ans
<c:otherwise>
<p>Connected to the database server</p>
n - t r
</c:otherwise>
a no
</c:choose>
h a s
<%--A. Prepare and execute the insert statement
ฺ b r) --%> d e ฺ
omadded u i
<p><c:out value="${param.name}"></c:out>
r ฺ c
afile in your t G to the database</p>
nchosen text editor. The code in the
9. Examine the contents of the findfilm.jsp e p d e
findfilm.jsp file enables a usersto
n for
osearch S taufilm by its title.
The findfilm.jsp file contains c t s
hi Java/JSTL code:
i@the following
ฺr i c e
r t o us
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"
t o
<%@ taglibeuri="http://java.sun.com/jsp/jstl/sql"
prefix="c" %>

rob efile="/WEB-INF/conn.inc"
se
prefix="sql" %>

c i (
<%@ include
c n %>

R c
i<c:choose>li
berto <%-- Unsuccessful connection attempt --%>

Ro
<c:when test="${not empty connexception}">
<p>Error connecting to the database server</p>
</c:when>
<%-- Successful connection attempt --%>
<c:otherwise>
<p>Connected to the database server</p>
</c:otherwise>
</c:choose>

<%
String newFilm = request.getParameter("name");
String sql = "SELECT title, description FROM film2 WHERE title =
'" + newFilm + "'";
%>

<%-- B. Replace the query with a prepared statement --%>


<sql:query dataSource="${conn}" var="rs">
<%= sql %>
</sql:query>

<p><%= sql %></p>


Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 18
<p><strong>Search results:</strong></p>

<c:forEach items="${rs.rowsByIndex}" var="row">


<c:out value="${row[0]} : ${row[1]}"/><br />
</c:forEach>
10. In the addfilm.jsp file, enter a <sql:update> tag under the comment labelled “A.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Prepare and execute the insert statement” to prepare and execute a statement that inserts
a new row into the films2 table. Use placeholders for the title and description
columns and supply the actual values to the statement by using <sql:param> tags.
Populate the title column with the name of the new film title supplied by the user. For the
description column, supply any text string.
Add the following code to the addfilm.jsp file under the comment labelled “A. Prepare
and execute the insert statement”:
ble
...
<%--A. Prepare and execute the insert statement --%>
fe r a
<sql:update dataSource="${conn}" var="num">
ans
INSERT INTO film2 (title, description)
n - t r
VALUES (?,?)
<sql:param value="${param.name}" /> a no
<sql:param value="Temporary description" />
h a s
</sql:update>
ฺ b r) deฺ
...
o mfollowingu i
11. Save your work, open the Firefox browser and r
a ฺ c
visit the
n t G URL: http://localhost:8080/
activity4-3/index.html.
ep tude
onpage:
The browser displays the followings web
i s S
i @ h
ฺ r i cc se t
e r to to u
i ( rob ense
R icc lic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 19
12. Enter “ANOTHER TRIP” into the “New Film” text box and click its associated “Submit
Query” button.
The browser redirects to the addfilm.jsp page and inserts the new row into the film2
table:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

13. Verify that the row has been added to the table. Navigate back to the main page of your
application by clicking the Firefox browser’s “back” button. Enter “ANOTHER TRIP” into the
ble
“Search Films” text box and click its associated “Submit Query” button.
fe r a
The browser redirects to the findfilm.jsp page to display the new row in the film2
ans
table and the SQL statement that it used to locate the row.
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
14. The c in thelifindfilm.jsp page is not a prepared statement and there is no
Riquery
e r tovalidation of the value the user enters. This makes it vulnerable to SQL injection attacks by
R ob malicious users. Enter the following expression exactly as shown into the “Search Films”
text box and click its associated “Submit Query” button. What happens, and why?
' OR 'X' = 'X
Answer: The findfilm.jsp page displays the entire contents of the film2 table. This is
because the actual query generated by the page is as follows:
SELECT title, description FROM film2 WHERE title = '' OR 'X' = 'X'
The initial single quote you entered terminated the first search string, allowing you to
append an OR clause to the SQL expression. Because 'X' always equals 'X', the expression
evaluates to true for every record in the film2 table. This could potentially be a security
risk, especially if the table contains sensitive information.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 20
15. In the findfilm.jsp page under the comment labelled “B. Replace the query with a
prepared statement”, rewrite the query as a prepared statement.
Make the following adjustments to the code in the findfilm.jsp page:
...
<%
String newFilm = request.getParameter("name");
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

String sql = "SELECT title, description FROM film2 " +


"WHERE title = ?";
%>

<%-- B. Replace the query with a prepared statement --%>


<sql:query dataSource="${conn}" var="rs">
<%= sql %>
<sql:param value="${param.name}" />
</sql:query>
ble
<p><%= sql %></p>
fe r a
ans
<p><strong>Search results:</strong></p>
n - t r
no
...
a
16. Save the findfilm.jsp file and reload the index.html page in Firefox. Enter the
s
h a
following expression exactly as shown into the “Search Films” text box. Click its associated
“Submit Query” button. What happens this time, and why? ฺ b r) deฺ
c o m Gui
rฺ eninjection
' OR 'X' = 'X
Answer: The server is unable to process the p a
query. SQL
t is a risk because user
n
input is used as part of the SQL statement.
e By t
usingu d
o of aSparameter and not as a partyouof the
prepared statements, can force
the user input to be handled asi@thescontentis SQL
statement. c
ic use t h
t o ฺ r
r open tterminal
17. Close Firefox and any
b e o windows.
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 21
Practice 4-4: Using Prepared Statements with Connector/Python
Overview
In this practice, you create a prepared statement to insert a new row into a table using
information supplied by a user. You then test a Python script to see if it is vulnerable to a SQL
injection attack and make any necessary changes to prevent this from occurring.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a Linux terminal window open logged in as the root user (password:
oracle).
• The Apache web server is installed and running on port 80.

Duration
This practice should take you approximately 30 minutes to complete. ble
fe r a
Tasks
t r a ns
1. Display the contents of the /labs/sql/film2.sql file in the Linux terminal.nWhat
o - does
the SQL code in this file do?
2. Execute the /labs/sql/film2.sql script to create the film2a s
table
ainnthe sakila
database. r ) h ฺ
3. Verify that the film2 table exists and contains 1,000m
b
ฺ uide
records.
r o
ฺc nt G
4. Change the current working directory to /labs/python/web/activity4-4 and list the
p a e
files within that directory.
5. Copy the addfilm_start.py filestooaddfilm.py.
ne Stud
c i t h is
@file to findfilm.py.
6. Copy the findfilm_start.py
o ฺ ic use
rthe
7. Examine the contents
e r t of
t o
index.py file in a text editor such as vi, emacs, or gedit. The
index.py file
r o b
outputs a
s e
simple webpage with two forms. Each form contains a text field
c i (
and a button.
c e
Clicking nthe button for the “New Film” text box invokes the addfilm.py
c l i
i and clicking the button for the “Search Films” text box invokes the findfilm.py
script,
R
ert oscript.
b
Ro
8. Examine the contents of the addfilm.py file in your chosen text editor. You complete the
code in the addfilm.py file to insert a new row into the films2 table.
9. Examine the contents of the findfilm.py file in your chosen text editor. The code in the
findfilm.py file enables a user to search for a film by its title.
10. In the addfilm.py file under the comment labelled “A. Prepare the insert statement”,
create a variable called sql that contains a SQL statement which inserts a new row into the
films2 table. Use placeholders for the title and description columns.
11. In the addfim.py file under the comment labelled “B. Execute the insert statement”, create
a cursor object by calling the cursor() method on the database connection instance,
passing in prepared=True as the method argument.
12. In the addfilm.py file under the comment labelled “B. Execute the insert statement”, call
the cursor object’s execute() method, passing in the SQL statement and a tuple that
contains both the film title supplied by the user and any descriptive text string.
13. Close the cursor and call the database connection object’s commit() method to persist the
change to the database.
14. Save your work, and make the conn.py, index.py, addfilm.py, and findfilm.py
files executable.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 22
15. Open the Firefox browser and visit the following URL:
http://localhost/cgi-bin/activity4-4/index.py.
16. Enter “ANOTHER TRIP” into the “New Film” text box and click its associated “Submit
Query” button.
17. Verify that the row has been added to the table. Navigate back to the main page of your
application by clicking the Firefox browser’s “back” button. Enter “ANOTHER TRIP” into the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

“Search Films” text box and click its associated “Submit Query” button.
18. The query in the findfilm.py script is not a prepared statement and there is no
validation of the value the user enters. This makes it vulnerable to SQL injection attacks by
malicious users. Enter the following expression exactly as shown into the “Search Films”
text box and click its associated “Submit Query” button. What happens, and why?
' OR 'X' = 'X
19. In the findfilm.py page under the comment labelled “C. Replace with a prepared
statement”, rewrite the query as a prepared statement. ble
20. Save the findfile.py file and reload the index.html page in Firefox. Enter the fe r a
following expression exactly as shown into the “Search Films” text box. Click its associated ans
“Submit Query” button. What happens this time, and why? n - t r
o
' OR 'X' = 'X
s an
21. Close Firefox and any open terminal windows.
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 23
Solution 4-4: Using Prepared Statements with Connector/Python
Solution Steps
1. Display the contents of the /labs/sql/film2.sql file in the Linux terminal. What does
the SQL code in this file do?
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/sql/
# cat film2.sql
USE sakila
DROP TABLE IF EXISTS `film2`;
CREATE TABLE `film2` AS SELECT `film_id`, `title`, `description` FROM
`film`;
ALTER TABLE `film2` MODIFY `film_id` SMALLINT(5) UNSIGNED NOT NULL
PRIMARY KEY AUTO_INCREMENT;
ble
Answer: The SQL in film2.sql creates a copy of the film table in the sakila
fe r a
database called film2, preserving only the film_id, title, and description
ans
columns. The ALTER TABLE statement adds the auto_increment and primary key
attributes to the film_id column. n - t r
2. a no
Execute the /labs/sql/film2.sql script to create the film2 table in the sakila
database. h a s
ฺ b r) deฺ
Enter the following command at the Linux terminal prompt and receive the results shown:
# mysql -uroot -poracle < film2.sql com u i
mysql: [Warning] Using a passwordaon n G
rฺ the ecommand
t line interface can be
p
one s Stud
insecure.
# s
i c
3. Verify that the film2 tablecexists
e hi 1,000 records.
i@and contains
t
t o ฺr at the
Enter the following rcommand usLinux terminal prompt and receive the results shown:
e t o
i ( r b en-poracle
# mysqlo-uroot se\ \

i>ccSHOW CREATE
lic TABLE film2\G \
> -e "USE sakila;
R
erto mysql: [Warning] Using a password on the command line interface can be
> SELECT COUNT(*) FROM film2;"
b
Ro insecure.
*************************** 1. row ***************************
Table: film2
Create Table: CREATE TABLE `film2` (
`film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8,
PRIMARY KEY (`film_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1
+----------+
| COUNT(*) |
+----------+
| 1000 |
+----------+
[root@edddr9p1 sql]#
4. Change the current working directory to /labs/python/web/activity4-4 and list the
files within that directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/python/web/activity4-4
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 24
# ls
addfilm_soln.py addfilm_start.py conn.py findfilm_soln.py
findfilm_start.py index.py
5. Copy the addfilm_start.py file to addfilm.py.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp addfilm_start.py addfilm.py
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# ls
addfilm.py addfilm_start.py findfilm_soln.py index.py
addfilm_soln.py conn.py findfilm_start.py
6. Copy the findfilm_start.py file to findfilm.py.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp findfilm_start.py findfilm.py
# ls
addfilm.py addfilm_start.py findfilm.py findfilm_start.py
ble
addfilm_soln.py conn.py findfilm_soln.py index.py
fe r a
7. Examine the contents of the index.py file in a text editor such as vi, emacs, or gedit. The
ans
index.py file outputs a simple webpage with two forms. Each form contains a text field
n - t r
o
s an
and a button. Clicking the button for the “New Film” text box invokes the addfilm.py
script, and clicking the button for the “Search Films” text box invokes the findfilm.py
script.
r ) ha ฺ
ฺb uide
The index.py file contains the following Python code:
m
#!/usr/bin/python
a r ฺco nt G
o
print('''Content-Type: text/htmln ep tude
@ s is S
c c i th
<html>
r i us e
<head>
e r toฺ4-4 t(Python)</title>
<title>Activity o
</head>ob se
i ( r e n
cc lic 4-4 (Python)</h1>
<body>

to Ri<h1>Activity
e r <p>

R ob <br/><br/>

<form action="addfilm.py" method="post">


New Film: <input type="text" name="name">
<input type="submit">
</form>

<form action="findfilm.py" method="post">


Search Films: <input type="text" name="name">
<input type="submit">
</form>

<br/><br/>

</body>
</html>
''')
8. Examine the contents of the addfilm.py file in your chosen text editor. You complete the
code in the addfilm.py file to insert a new row into the films2 table.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 25
The addfilm.py file contains the following Python code:
#!/usr/bin/python

import conn
import cgi

print('''Content-Type: text/html
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<html>
<head><title>Activity 4-4 (Python)</title></head>
<body>
''')

# Get user input


params = cgi.FieldStorage()
newFilm = params['name'].value
ble
fe r a
# Connect to the database
dbconn = conn.dbconnect()
ans
n - t r
o
an
# A. Prepare the insert statement
s
ha ฺ
# B. Execute the insert statement r )
ฺb uide
m
a r ฺco % nnewFilm)
t G
ep tude
print("<p>%s added to the database</p>"

print("<p>Disconnecting from o n S
s theisdatabase server</p>")
i @ h
dbconn.close()
ฺ r i cc se t
</body> be
print(''' rto to u
i (
</html>ro ense
cc
Ri''') lic
e r
9. toExamine the contents of the findfilm.py file in your chosen text editor. The code in the
R ob findfilm.py file enables a user to search for a film by its title.
The findfilm.py file contains the following Python code:
#!/usr/bin/python

import conn
import cgi

print('''Content-Type: text/html

<html>
<head><title>Activity 4-4 (Python)</title></head>
<body>
''')

# Get user input


params = cgi.FieldStorage()
filmTitle = params['name'].value

# Connect to the database


dbconn = conn.dbconnect()
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 26
# C: Replace with prepared statement
sql = "SELECT title, description FROM film2 WHERE title='" + filmTitle
+ "'"
cursor = dbconn.cursor()
cursor.execute(sql)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

print("<p>" + sql + "</p>")


print("<p><strong>Search results:</strong></p>")

for (title, description) in cursor:


print("%s : %s<br />" % (title, description))
cursor.close()

print("<p>Disconnecting from the database server</p>")


dbconn.close()
ble
print(''' fe r a
</body>
ans
</html>
n - t r
''')
a no
10. In the addfilm.py file under the comment labelled “A. Prepare thesinsert statement”,
r )
create a variable called sql that contains a SQL statement whichhainserts
ฺ a new row into the
ฺ b
films2 table. Use placeholders for the title and description
m e
idlabelled “A. Prepare the
columns.
c o G u
insert statement”: p a rฺ ent
Add the following code to the addfilm.py file under the comment

...
s o ne Stud
# Connect to the database
c i @ this
t o ฺ ric use
dbconn = conn.dbconnect()

b e r the insert
to statement
# A. Prepare
o
sql =(r"INSERT e
s film2 (title, description) VALUES (%s, %s)"
nINTO
c i li c e
R ic
berto # B. Execute the insert statement
Ro
print("<p>%s added to the database</p>" % newFilm)

print("<p>Disconnecting from the database server</p>")


dbconn.close()
...
11. In the addfim.py file under the comment labelled “B. Execute the insert statement”, create
a cursor object by calling the cursor() method on the database connection instance,
passing in prepared=True as the method argument.
Add the following code to the addfilm.py file under the comment labelled “B. Execute the
insert statement”:
...
# Connect to the database
dbconn = conn.dbconnect()

# A. Prepare the insert statement


sql = "INSERT INTO film2 (title, description) VALUES (%s, %s)"

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 27
# B. Execute the insert statement
cursor = dbconn.cursor(prepared=True)

print("<p>%s added to the database</p>" % newFilm)

print("<p>Disconnecting from the database server</p>")


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

dbconn.close()
...
12. In the addfilm.py file under the comment labelled “B. Execute the insert statement”, call
the cursor object’s execute() method, passing in the SQL statement and a tuple that
contains both the film title supplied by the user and any descriptive text string.
Add the following code to the addfilm.py file under the comment labelled “B. Execute the
insert statement”:
...
ble
# Connect to the database
fe r a
dbconn = conn.dbconnect()
ans
n - t r
no
# A. Prepare the insert statement
sql = "INSERT INTO film2 (title, description) VALUES (%s, %s)"
s a
h a
# B. Execute the insert statement
cursor = dbconn.cursor(prepared=True)
ฺ b r) deฺ
cursor.execute(sql, (newFilm, "Temporarym
o u i
description"))
a c
rฺ %ennewFilm)
t G
p
ne Stud
print("<p>%s added to the database</p>"

s o
i
print("<p>Disconnecting from the
c @ thisdatabase server</p>")
dbconn.close()
...
t o ฺ ric use
13. Close the cursorb e r thetodatabase connection object’s commit() method to persist the
and call e
change toi rodatabase.
(the e ns
c c
icthe followingli code to the addfilm.py file under the comment labelled “B. Execute the
R
Add

bertoinsert statement”
Ro ...
# Connect to the database
dbconn = conn.dbconnect()

# A. Prepare the insert statement


sql = "INSERT INTO film2 (title, description) VALUES (%s, %s)"

# B. Execute the insert statement


cursor = dbconn.cursor(prepared=True)
cursor.execute(sql, (newFilm, "Temporary description"))
cursor.close()
dbconn.commit()

print("<p>%s added to the database</p>" % newFilm)

print("<p>Disconnecting from the database server</p>")


dbconn.close()
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 28
14. Save your work, and make the conn.py, index.py, addfilm.py, and findfilm.py
files executable.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# chmod +x conn.py index.py addfilm.py findfilm.py
# ls -al
total 32
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

drwxr-xr-x 2 root root 4096 May 12 09:07 .


drwxr-xr-x. 5 root root 4096 May 12 09:03 ..
-rwxr-xr-x 1 root root 690 May 12 09:10 addfilm.py
-rw-r--r-- 1 root root 503 May 12 09:06 addfilm_start.py
-rwxr-xr-x 1 root root 454 May 12 09:03 conn.py
-rwxr-xr-x 1 root root 721 May 12 09:07 findfilm.py
-rw-r--r-- 1 root root 721 May 12 09:06 findfilm_start.py
-rwxr-xr-x 1 root root 433 May 12 09:06 index.py
15. Open the Firefox browser and visit the following URL:
ble
http://localhost/cgi-bin/activity4-4/index.py.
fe r a
The browser displays the following web page:
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
Ric
toQuery” button.
16. Enter “ANOTHER TRIP” into the “New Film” text box and click its associated “Submit
e r
R ob The browser redirects to the addfilm.py script and inserts the new row into the film2
table:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 29
17. Verify that the row has been added to the table. Navigate back to the main page of your
application by clicking the Firefox browser’s “back” button. Enter “ANOTHER TRIP” into the
“Search Films” text box and click its associated “Submit Query” button.
The browser redirects to the findfilm.py script to display the new row in the film2
table and the SQL statement that it used to locate the row.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
n o
18. The query in the findfilm.py script is not a prepared statement and a
s there is no
validation of the value the user enters. This makes it vulnerablehtoaSQL injection attacks by
malicious users. Enter the following expression exactly as ฺ b r) into
shown
d e ฺ “Search Films”
the
text box and click its associated “Submit Query” button. omWhat u i
happens, and why?
r ฺ
a den c t G
' OR 'X' = 'X
e p
Answer: The findfilm.py script displays
s tu contents of the film2 table. This is
on stheSentire
because the actual query generated
i c c e hi page is as follows:
i@ by tthe
r t o ฺr
SELECT title, description
u s FROM film2 WHERE title = '' OR 'X' = 'X'
b
The initial single o
equote eyout entered terminated the first search string, allowing you to
r o
append an(OR clausen
i tosthe SQL expression. Because 'X' always equals 'X', the expression
c
icespecially
evaluates c e
li for every record in the film2 table. This could potentially be a security
to true
R
erto
risk, if the table contains sensitive information.
b 19. In the findfilm.py page under the comment labelled “C. Replace with a prepared
Ro statement”, rewrite the query as a prepared statement.
Make the following adjustments to the code in the findfilm.py file under the comment
labelled “C. Replace with a prepared statement”:
...
# Connect to the database
dbconn = conn.dbconnect()

# C: Replace with prepared statement


sql = "SELECT title, description FROM film2 WHERE title=%s"
cursor = dbconn.cursor(prepared=True)
cursor.execute(sql, (filmTitle,))

print("<p>" + sql + "</p>")


print("<p><strong>Search results:</strong></p>")

for (title, description) in cursor:


print("%s : %s<br />" % (title, description))
cursor.close()
...
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 30
20. Save the findfilm.py file and reload the index.html page in Firefox. Enter the
following expression exactly as shown into the “Search Films” text box. Click its associated
“Submit Query” button. What happens this time, and why?
' OR 'X' = 'X
Answer: The server is unable to process the query. SQL injection is a risk because user
input is used as part of the SQL statement. By using prepared statements, you can force
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

the user input to be handled as the content of a parameter and not as a part of the SQL
statement.
21. Close Firefox and any open terminal windows.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 31
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 4: Prepared Statements


Chapter 4 - Page 32
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 5:
Handling om Errors i
u and
r ฺ
a denc t G
Warnings
p
e
on Chaptertu5
s s S
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 1
Practices for Lesson 5: Handling Errors and Warnings
Practices Overview
These practices test your knowledge of handling errors and warnings when coding with
Connectors. They assume that you are using the Linux operating system environment provided
in Oracle classrooms. For non-Oracle classrooms, you might need to make some adjustments
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

to the file locations.


Important: The coding practices in this lesson are available in PHP, Java, and Python. Perform
all the practices for this and all future coding activities in only one language, choosing the
language you are most familiar with. If in doubt, perform the PHP activities. Ensure that you
complete all practices that are not language-specific
For this lesson, perform the following practices:
• Practice 5-1: Quiz – Handling Errors
ble
• Practice 5-2: Identifying Error and Warnings with the mysql Command Line Client
fe r a
• If your chosen programming language is PHP: ans
− Practice 5-3: Handling Errors and Warnings When Coding with PHP/PDO n - t r
• If your chosen programming language is Java: a no
h a s
− Practice 5-4: Handling Errors and Warnings When Coding with Connector/J
ฺ b r) deฺ
• If your chosen programming language is Python:
c o m Gui
p a rฺ ent
− Practice 5-5: Handling Errors and Warnings When Coding with Connector/Python

Assumptions s one s Stud


• If you are completing the coding
i c c i@ practices
e t hi in PHP:
− The Apache web
r t o ฺrserver isuinstalled
s and running on port 80
o
be sethet coding practices in Java:
• If you are completing
r o
i ( Tomcat n
i
− The
c c l i c eapplication server is installed and running on port 8080
•R If you are completing the coding practices in Python:
r t o
obe
− The Apache web server is installed and running on port 80.
R • The world and sakila sample databases are installed

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 2
Practice 5-1: Quiz – Handling Errors
Overview
In this practice, you test your knowledge of SQL modes, warnings, and errors.

Assumptions
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

None

Duration
This practice should take approximately 5 minutes to complete.

Tasks
1. Which of the following statements is true?
ble
a. Setting the SQL mode affects all clients that connect to the server.
fe r a
b. If you want to set two SQL modes (for example, the STRICT_ALL_TABLES and
ans
ERROR_FOR_DIVISION_BY_ZERO modes), you must issue two SET statements.
n - t r
o
an
c. Unless you explicitly declare otherwise, setting the SQL mode affects only the client
that sets the mode. s
) ha ฺ
d. SQL modes affect the behavior of the server. For example, they influence the way in
r
which the server handles invalid input data.
m ฺb uide
a r ฺco nt G
e. SQL modes affect the features that the server provides for a client. For example, you

o n ep tude
can turn InnoDB support on and off using SQL modes.
2.
s is S
What is the syntax for changing the SQL mode to STRICT_TRANS_TABLES and
@
PIPES_AS_CONCAT?
c c i th
r i e
3.
e r toฺ to us
If you attempt to store a negative value in an UNSIGNED column, MySQL converts it to the
'nearest' legal value for the column. Which value is that?
4. ( rob ense
What type of values are inserted into table1 with the following INSERT statement?
i
cc INTO
RiINSERT lictable1 VALUES();
e r
5. toWith a particular setting for the SQL mode, MySQL adjusts invalid input values to legal
R ob values when possible and generates warning messages. You can also adjust the SQL
mode to issue errors instead of warnings. What is the general term for SQL modes that
enable this behavior?
6. The MySQL server generates warnings or errors when it cannot fully comply with a request
or when an action has possible unintended side effects. Which two statements do you use
to view these errors and warnings?
7. List the three levels of severity for warnings.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 3
Solution 5-1: Quiz – Handling Errors
1. The truth or falsity of each of the statements is as follows:
a. False. SQL modes exist as global and session variables. By default, the SQL mode is
for the session and applies to the client that sets the mode. To affect all clients, you
need to set the global variable.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

b. False. You can set multiple SQL modes by specifying them in a comma-delimited list.
c. True
d. True
e. False. SQL modes control some aspects of MySQL syntax, and how MySQL performs
data validation.
2. The syntax for changing the SQL mode to STRICT_TRANS_TABLES and
PIPES_AS_CONCAT is as follows:
ble
SET sql_mode = 'STRICT_TRANS_TABLES,PIPES_AS_CONCAT';
fe r a
3. The “nearest” legal value for an UNSIGNED column that is assigned a negative number is
ans
zero.
n - t r
4. no
The INSERT statement generates default values for the columns in table1, or NULL
a
where no default value is specified
h a s
5. r) deฺ
The general term for the SQL modes that enable the described behavior is “strict mode.”
ฺ b
c o m Gui
Strict mode comprises the SQL modes STRICT_ALL_TABLES and
STRICT_TRANS_TABLES.
p a rฺ ent
6. Display warnings and errors with the SHOW
o n e tud and SHOW ERRORS statements,
WARNINGS
respectively.
@ s is S
c
7. The three levels of severity for
c i warningsthare:
r i e
• Note
e r toฺ to us
• Warning b
i ( ro ense
icc
• Error
R lic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 4
Practice 5-2: Identifying Errors and Warnings with the mysql
Command Line Client
Overview
In this practice, you generate errors and warnings, and investigate those errors and warnings
using the mysql command line client.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have the Firefox web browser open
• You have a Linux terminal window open and logged in as the root user (password:
oracle).

Duration
ble
This practice should take approximately 10 minutes to complete.
fe r a
ans
Tasks
n - t r
1.
no
Find the pages in the MySQL Reference Manual that list the MySQL server, and mysql
client error codes and messages. a
2. h a s
Use the perror utility to determine what operating system error the error code 130
represents. ฺ b r) deฺ
3. c o m Gui
Change the current database to sakila and attempt to display all the rows in a non-
p a rฺ ent
existent table called no_such_table. Do you receive an error or a warning?
4. one s Stud
Look up the code generated by the preceding statement in the MySQL Reference Manual.
s
5. i@ thi
Display the current SQL mode setting.
c c
6. ฺ r i se
Change the SQL mode to ANSI. Confirm the change.
o u
e t
rthe table tnamed
o no_such_table using a DROP TABLE IF
7. Attempt to removeb
ro type e EXISTS
statement.
c i (What c e nofsmessage do you receive?
8. UseR li SHOW statement to view a description of the message.
icthe appropriate
be9.rtoExecute SHOW ERRORS. Explain the result.
Ro 10. Exit the mysql client program and leave the Linux terminal window open for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 5
Solution 5-2: Identifying Errors and Warnings with the mysql
Command Line Client
Solution Steps
1. Find the pages in the MySQL Reference Manual that list the MySQL server, and mysql
client error codes and messages.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Browse to the http://dev.mysql.com/doc/mysql/en/error-handling.html page and look at the


linked pages: “Server Error Codes and Messages”, and “Client Error Codes and
Messages”.
2. Use the perror utility to determine what operating system error the error code 130
represents.
In a Linux terminal window, enter the following command and receive the results shown:
# perror 130
ble
OS error code 130: Owner died
fe r a
MySQL error code 130: Incorrect file format
ans
3. Change the current database to sakila and attempt to display all the rows in a non-
n - t r
no
existent table called no_such_table. Do you receive an error or a warning?
a
a. Log in to the mysql client:
h a s
# mysql –u root –p
ฺ b r) deฺ
Enter password: oracle
o m u i
Welcome to the MySQL monitor. Commands
a c
rฺ ent G
end with ; or \g.
...
p
ne Stud
b. Change the current database to o
mysql> USE sakila ci@
s sakila:
is
t h
ฺ ric use
Reading table information
t o
...
Database b e r to
rofollowing
(the
changed e
nsstatement at the mysql prompt and receive the results shown:
c
c. Enter
c i li c e
R imysql>
erto ERROR 1146 (42S02): Table 'sakila.no_such_table' doesn't exist
SELECT * FROM no_such_table;
b
Ro The message is an error with number 1146.
4. Look up the code generated by the preceding statement in the MySQL Reference Manual.
Browse to the page "Server Error Codes and Messages" and find the entry for error 1146.
Alternatively, browse directly to the page using the URL
http://dev.mysql.com/doc/mysql/en/error-messages-server.html#error_er_no_such_table
5. Display the current SQL mode setting.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER
ROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (#.## sec)
6. Change the SQL mode to ANSI. Confirm the change.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SET sql_mode=ANSI;
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 6
Query OK, 0 rows affected, 1 warning (#.## sec)

mysql> SHOW WARNINGS\G


*************************** 1. row ***************************
Level: Warning
Code: 3090
Message: Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

will be removed in a future release.


1 row in set (#.## sec)

mysql> SELECT @@sql_mode\G


*************************** 1. row ***************************
@@sql_mode:
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP
_BY,ANSI
1 row in set (#.## sec)
− Setting the sql_mode to ANSI results in a warning about the ble
NO_AUTO_CREATE_USER setting being deprecated. fe r a
ans
− ANSI mode makes MySQL behave more like standard SQL.
n - t r
7. Attempt to remove the table named no_such_table using a DROP TABLE IF EXISTS
statement. What type of message do you receive? a no
h a s
ฺ b r) deฺ
Enter the following statement at the mysql prompt and receive the results shown:
mysql> DROP TABLE IF EXISTS no_such_table;
Query OK, 0 rows affected, 1 warningฺc(#.## o m sec) G ui
p a r ent
The statement generates a warning. e tud
otonview
8. Use the appropriate SHOW statement s aS
description of the message.
i @ h i s
t prompt and receive the results shown:
Enter the following statement
ฺ r i ccat thesmysql
e
to to u
mysql> SHOW rWARNINGS;
e
i
| Level( ro|bCode e
e
|s Message
+-------+------+-------------------------------+
n |
c c l i c
i| Note | 1051 | Unknown table 'no_such_table' |
+-------+------+-------------------------------+
o R
b e rt +-------+------+-------------------------------+
R o 1 row in set (#,## sec)
9. Execute SHOW ERRORS. Explain the result.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW ERRORS;
Empty set (#.## sec)
With the sql_mode set to ANSI, attempting to drop a non-existent table with the IF
EXISTS clause generates a warning, but not an error.
10. Exit the mysql client program and leave the Linux terminal window open for the next
practice.
Enter the following at the mysql prompt and receive the message shown:
mysql> EXIT
Bye
#

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 7
Practice 5-3: Handling Errors and Warnings When Coding with
PHP/PDO
Overview
In this practice, you generate and handle MySQL errors and warnings using PHP/PDO.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You are logged in to a Linux terminal window as the root user (password: oracle).

Duration
This practice should take you approximately 20 minutes to complete.

Tasks e
1. Change the current working directory to /labs/php/cli/activity5-3 and display the r a bl
contents of the directory. s fe
2. Copy the ExceptionExample_start.php file to ExceptionExample.php. - t r an
on
3.
an
Inspect the contents of the ExceptionExample.php file in a text editor.
s
4.
r ) ha ฺ
Under the comment labelled “A. Wrap connection attempt in a try/catch block”, write code
that attempts to connect to the database using the DSN provided. If the connection attempt
m ฺb uide
fails, display the MySQL error code and details, and a suitable message to the user before
terminating the script.
a r ฺco nt G
5. ep tude
Under the comment labelled “B. Define PDO error handling mode”, set the PDO attribute
o n
s is S
which forces PDO to throw an exception when an error occurs.
@
c i th
Note: This is the preferred method for error handling in PHP/PDO because it enables you
c
r i e
6. e toฺ to us
to pinpoint application errors and handle them gracefully.
r
Under the comment labelled “C. Wrap query attempt in a try/catch block”, write code that
( rob ense
attempts to query the database using the SQL provided. If the query attempt fails, display
i
c lic
Ric
the MySQL error code and details, and a suitable message to the user.

e
7.
r to Save your work and execute the ExceptionExample.php script.

R ob 8. Modify the ExceptionExample.php script to use the SQL statement string defined in the
variable $sql2.
9. Save and execute the ExceptionExample.php script. What happens?
10. Change the PDO attribute to raise warnings instead of errors when an exception occurs.
Note: This method of dealing with errors can be useful if you want to test or debug without
disrupting the flow of the application.
11. Save and execute the ExceptionExample.php script. What happens?
12. Change the PDO attribute to ignore errors and warnings when they occur.
Note: This is the default error handling mode and is not recommended.
13. Save your work and execute the ExceptionExample.php script again. What happens?
14. Close all open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 8
Solution 5-3: Handling Errors and Warnings When Coding with
PHP/PDO
Solution Steps

Tasks
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

1. Change the current working directory to /labs/php/cli/activity5-3 and display the


contents of the directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/php/cli/activity5-3/
# ls
ExceptionExample_soln.php ExceptionExample_start.php
2. Copy the ExceptionExample_start.php file to ExceptionExample.php. e
Enter the following commands at the Linux terminal prompt and receive the results shown: r a bl
s fe
# cp ExceptionExample_start.php ExceptionExample.php
# ls
- t r an
ExceptionExample.php ExceptionExample_soln.php
no n
ExceptionExample_start.php a
seditor.
3. Inspect the contents of the ExceptionExample.php file in a h a
text
The contents of the ExceptionExample.php file are as ฺ b r)
follows:ide

<?php
r ฺ c om t Gu
e p a den
s o s Stu
# A. Wrap connection attemptnin a try/catch block

i@ i
$dsn = "mysql:host=localhost;dbname=world";
c "root",th
$dbh = new PDO ($dsn,
ฺr i c e "oracle");

r t o
print ("Connected\n");
t o us
e
rob ePDOnserror
# B. Define
i ( e handling mode
R icc lic
e r to # C. Wrap query attempt in a try/catch block
R ob $sql1 = "SELECT Name, Population FROM Country ORDER BY Population DESC
LIMIT 10";
// $sql2 = "SELECT WrongColumn FROM WrongTable";
$sth = $dbh->query($sql1);
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
printf("Name: %s, Population: %s\n", $row['Name'],
$row['Population']);
}

$dbh = NULL;
print ("Disconnected\n");

?>
4. Under the comment labelled “A. Wrap connection attempt in a try/catch block”, write code
that attempts to connect to the database using the DSN provided. If the connection attempt
fails, display the MySQL error code and details, and a suitable message to the user before
terminating the script.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 9
Add the following code under the comment labelled “A. Wrap connection attempt in a
try/catch block”:
<?php

# A. Wrap connection attempt in a try/catch block


try {
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$dsn = "mysql:host=localhost;dbname=world";
$dbh = new PDO ($dsn, "root", "oracle");
print ("Connected\n");
# B. Define PDO error handling mode

} catch (PDOException $ex) {


echo "Connection error: \n";
echo "Error code: " . $ex->getCode() . "\n";
echo "Error message: " . $ex->getMessage() . "\n";
exit ("Terminating.\n\n");
ble
}
fe r a
...
ans
5. Under the comment labelled “B. Define PDO error handling mode”, set the PDO attribute
n - t r
which forces PDO to throw an exception when an error occurs.
a no
Note: This is the preferred method for error handling in PHP/PDO because it enables you
to pinpoint application errors and handle them gracefully.h a s
ฺ b r) deฺ
Add the following line of code under the comment labelled “B. Define PDO error handling
mode”: c o m Gui
p a rฺ ent
ne Stud
<?php

s
# A. Wrap connection attempt in s
o
c i @ thi a try/catch block
ric use
try {
o ฺ
$dsn = "mysql:host=localhost;dbname=world";
$dbh = r t
b e e o "root", "oracle");
new PDO t($dsn,

c i (#roB. Define
print
c e nsPDO error handling mode
("Connected\n");

li
Ric $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

e r to } catch (PDOException $ex) {

ob
echo "Connection error: \n";
R echo "Error code: " . $ex->getCode() . "\n";
echo "Error message: " . $ex->getMessage() . "\n";
exit ("Terminating.\n\n");
}
6. Under the comment labelled “C. Wrap query attempt in a try/catch block”, write code that
attempts to query the database using the SQL provided. If the query attempt fails, display
the MySQL error code and details, and a suitable message to the user.
Add the following code under the comment labelled “C. Wrap query attempt in a try/catch
block”:
...
# C. Wrap query attempt in a try/catch block
try {
$sql1 = "SELECT Name, Population FROM Country ORDER BY
Population DESC LIMIT 10";
// $sql2 = "SELECT WrongColumn FROM WrongTable";
$sth = $dbh->query($sql1);
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 10
printf("Name: %s, Population: %s\n", $row['Name'],
$row['Population']);
}
} catch (PDOException $ex) {
echo "Error processing query:\n";
echo "Error code: " . $ex->getCode() . "\n";
echo "Error message: " . $ex->getMessage() . "\n";
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$dbh = NULL;
print ("Disconnected\n");

?>
7. Save your work and execute the ExceptionExample.php script.
Enter the following command at the Linux terminal prompt. The script runs without any
errors and displays the results shown: ble
fe r a
# php ExceptionExample.php
ans
Connected
Name: China, Population: 1277558000 n - t r
Name: India, Population: 1013662000
a no
Name: United States, Population: 278357000
Name: Indonesia, Population: 212107000 h a s
Name: Brazil, Population: 170115000
ฺ b r) deฺ
Name: Pakistan, Population: 156483000
c o m Gui
p a rฺ ent
Name: Russian Federation, Population: 146934000

one s Stud
Name: Bangladesh, Population: 129155000
Name: Japan, Population: 126714000
s
Disconnected
c c i@ thi
Name: Nigeria, Population: 111506000

#
o ฺ r i u se
e r t to
b e
8. Modify the ExceptionExample.php
ro ens
script to use the SQL statement string defined in the
(
variable i$sql2.
c following
R
Makeicthe lic change to the ExceptionExample.php script:
berto ...
Ro # C. Wrap query attempt in a try/catch block
try {
$sql1 = "SELECT Name, Population FROM Country ORDER BY
Population DESC LIMIT 10";
$sql2 = "SELECT WrongColumn FROM WrongTable";
$sth = $dbh->query($sql2);
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
printf("Name: %s, Population: %s\n", $row['Name'],
$row['Population']);
}
}
...
9. Save and execute the ExceptionExample.php script. What happens?
When you execute the script, the query generates a PDOException error, which is caught
by the catch block you implemented in step 6:
# php ExceptionExample.php
Connected
Error processing query:
Error code: 42S02
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 11
Error message: SQLSTATE[42S02]: Base table or view not found: 1146 T
able 'world.WrongTable' doesn't exist
Disconnected
#
10. Change the PDO attribute to raise warnings instead of errors when an exception occurs.
Note: This method of dealing with errors can be useful if you want to test or debug without
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

disrupting the flow of the application.


Make the following change to the ExceptionExample.php script:
<?php

# A. Wrap connection attempt in a try/catch block


try {
$dsn = "mysql:host=localhost;dbname=world";
$dbh = new PDO ($dsn, "root", "oracle");
print ("Connected\n"); ble
# B. Define PDO error handling mode
fe r a
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
ans
}
n - t r
...
n o
11. Save and execute the ExceptionExample.php script. What happens? s a
Enter the following command at the Linux terminal prompt and ) h a
receive the results shown:
ฺ b r e ฺ
# php ExceptionExample.php
c o m Guid
Connected
PHP Warning: PDO::query(): SQLSTATE[42S02]:
p a rฺ ent Base table or view not
found: 1146 Table 'world.WrongTable'
one sonStline d exist in /labs/php/cli/
udoesn't
activity5-3/ExceptionExample.php
@ s i 21
PHP Fatal error: Call
c c i to a t h
member function fetch() on a non-object
ฺ r i u s e
in /labs/php/cli/activity5-3/ExceptionExample.php
o on line 22
r t t o
be the script,
#
r o
When you(execute s e
n and fails it generates a warning for the failed query. It then proceeds to
c i li c e
R ic a PDOStatement
the fetch()
contain
operation
object.
with a fatal error because the $sth variable does not

bertoNote: The line numbers referred to in the output might be different on your machine.
Ro 12. Change the PDO attribute to ignore errors and warnings when they occur.
Note: This is the default error handling mode and is not recommended.
Change the following line of code in the ExceptionExample.php script:
<?php

# A. Wrap connection attempt in a try/catch block


try {
$dsn = "mysql:host=localhost;dbname=world";
$dbh = new PDO ($dsn, "root", "oracle");
print ("Connected\n");
# B. Define PDO error handling mode
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
}
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 12
13. Save your work and execute the ExceptionExample.php script again. What happens?
Enter the following command at the Linux terminal prompt and receive the results shown:
# php ExceptionExample.php
Connected
PHP Fatal error: Call to a member function fetch() on a non-object
in /labs/php/cli/activity5-3/ExceptionExample.php on line 22
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

#
When you execute the script, it ignores the failed query. It then proceeds to the fetch()
operation and ultimately fails with a fatal error because the $sth variable does not contain
a PDOStatement object.
Note: The line numbers referred to in the output might be different on your machine.
14. Close all open terminal windows.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 13
Practice 5-4: Handling Errors and Warnings When Coding with
Connector/J
Overview
In this practice, you generate and handle MySQL errors and warnings using Connector/J.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You are logged in to a Linux terminal window as the root user (password: oracle).

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
ble
1. Change the current working directory to /labs/java/cli/activity5-4 and display the
fe r a
contents of the directory.
ans
2. Copy the ExceptionExample_start.java file to ExceptionExample.java.
n - t r
3. Inspect the contents of the ExceptionExample.java file in a text editor.
a no
4. Compile the ExceptionExample.java program. What is the result?
h a s
5. r) deฺ
Under the comment labelled “A. Wrap connection attempt in a try/catch block”, write code
ฺ b
c o m Gui
that attempts to connect to the database using the JDBC connection details provided.

p a rฺ ent
If the connection attempt fails for any reason, catch the Exception object that is thrown

onecall
and determine if the error is related to MySQL: d
tushowError()
• If the error is of type SQLException, s i s S
the method provided,
i @ h
t that was caught.
passing in the SQLException
ฺ r i cc sobject
e
r to exception,
• If the error is a general
t o u display the error details to the user.
e
6. Under c i robexit the
In either case,
(comment e n se program.
running

i c the
l i c labelled “B. Wrap query attempt in a try/catch block”, write code that

t o R to query the database using the SQL statement string provided in variable sql1. If
attempts

be r the query attempt fails, call the showError() method provided, passing in the
Ro 7.
SQLException object that was caught.
Under the comment labelled “C. Close the database connection in a finally block”, write
code that closes the database connection regardless of the success or failure of the query.
8. Compile and execute the ExceptionExample.java file.
9. Change the program so that it attempts to query the database using the SQL statement
string provided in variable sql2 instead of sql1.
10. Compile and execute the ExceptionExample.java file. What happens?
11. Under the comment labelled “D. Write code to display SQLException errors”, modify the
showErrors() method of the ExceptionExample class so that it displays the following
error details:
• Error message
• SQLSTATE
• MySQL error code
12. Compile and execute the ExceptionExample.java file. What happens?
13. Close any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 14
Solution 5-4: Handling Errors and Warnings When Coding with
Connector/J
Solution Steps
1. Change the current working directory to /labs/java/cli/activity5-4 and display the
contents of the directory.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/java/cli/activity5-4/
# ls
ExceptionExample_start.java ExceptionExample_soln.java
2. Copy the ExceptionExample_start.java file to ExceptionExample.java.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp ExceptionExample_start.java ExceptionExample.java
ble
# ls
fe r a
ExceptionExample.java ExceptionExample_start.java
an s
ExceptionExample_soln.java
n - t r
3. no
Inspect the contents of the ExceptionExample.java file in a text editor.
a
The contents of the ExceptionExample.java file are as follows:
h a s
import java.sql.*;
ฺ b r) deฺ
c o m Gui
public class ExceptionExample {
p a rฺ ent
d
one s Stuargs){
public static void main(String[]
s
new ExceptionExample().showTop10Populations();
}
c c i@ thi
o i se
ฺr showTop10Populations()
u
privatertvoid o
e t {

i ( rob Connection
e n se conn = null;
c lic//
to Ric A. Wrap connection attempt in a try/catch block
Class.forName ("com.mysql.jdbc.Driver").newInstance ();
e r conn = DriverManager.getConnection(
R ob "jdbc:mysql://localhost/world",
"root", "oracle");
System.out.println("Connected.");

// B. Wrap query attempt in a try/catch block


String name, output;
int population;
String sql1 = "SELECT Name, Population "
+ "FROM Country "
+ "ORDER BY Population DESC LIMIT 10";
String sql2 = "SELECT WrongColumn FROM WrongTable";
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery(sql1);

if(rs.first()) {
do {
name = rs.getString("Name");
population = rs.getInt("Population");
output = String.format("Name: %s,Population: %d",
name, population);

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 15
System.out.println(output);
} while(rs.next());
} else {
System.out.println("No rows returned.");
}
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

s.close();

// C. Close the database connection in a finally block

if (conn != null) {
conn.close ();
System.out.println ("Disconnected");
}

} ble
fe r a
// D. Write code to display SQLException errors
ans
private void showErrors(SQLException se) {
n - t r
}
System.out.println("There has been an error.");
a no
}
h a s
4. Compile the ExceptionExample.java program. What b
ฺ ) result?
is rthe e ฺ
om tand
Enter the following command at the Linux terminal prompt i d
u the results shown:
receive
# javac ExceptionExample.java pa r ฺ c n G
e d e
ExceptionExample.java:13: error:
xception; must be caught s ondeclared tuto be thrown
unreported
S
exception ClassNotFoundE

c i
or
is
@ th("com.mysql.jdbc.Driver").newInstance
ric use
Class.forName
();
r t o ฺ
...
b e e to error: unreported exception SQLException;
(berocaught s declared to be thrown
ExceptionExample.java:14:
c
must i c e nor
R ic li conn = DriverManager.getConnection(

erto ExceptionExample.java:26: error: unreported exception SQLException;


^
b
Ro must be caught or declared to be thrown
Statement s = conn.createStatement();
^
ExceptionExample.java:27: error: unreported exception SQLException;
must be caught or declared to be thrown
ResultSet rs = s.executeQuery(sql);
^
...
12 errors
− The program does not compile because JDBC expects you to implement error
handling code for its main operations.
5. Under the comment labelled “A. Wrap connection attempt in a try/catch block”, write code
that attempts to connect to the database using the JDBC connection details provided.
If the connection attempt fails for any reason, catch the Exception object that is thrown
and determine if the error is related to MySQL:
• If the error is of type SQLException, call the showError() method provided,
passing in the SQLException object that was caught.
• If the error is a general exception, display the error details to the user.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 16
In either case, exit the running program.
Enter the following code in the ExceptionExample.java file under the comment labelled
“A. Wrap connection attempt in a try/catch block”:
...
private void showTop10Populations() {
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Connection conn = null;


try {
// A. Wrap connection attempt in a try/catch block
Class.forName ("com.mysql.jdbc.Driver").newInstance ();
conn = DriverManager.getConnection(
"jdbc:mysql://localhost/world",
"root", "oracle");
System.out.println("Connected.");
}
catch (Exception e) {
ble
System.out.println("Cannot connect to server." );
fe r a
if (e instanceof SQLException) {
ans
showErrors((SQLException) e);
n - t r
no
} else {
System.out.println(e);
s a
}
h a
System.exit(0);
ฺ b r) deฺ
}
o ma try/catch
u i block”, write code that
6. Under the comment labelled “B. Wrap query attempt
a c
rฺ enstring
in G
t provided in variable sql1. If
attempts to query the database using the SQL p statement
o ne Smethod
the query attempt fails, call the showError()
s tud provided, passing in the
SQLException object that was
c i @caught.this
Enter the following codeฺrinicthe ExceptionExample.java
s e file under the comment labelled
r t
“B. Wrap query attempt o o u
in a ttry/catch block”:
... (ro
be se
i Wraplicquery
//cB. e n attempt in a try/catch block
R c
itry {
ert o String name, output;
b
Ro
int population
String sql = "SELECT Name, Population "
+ "FROM Country "
+ "ORDER BY Population DESC LIMIT 10";
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery(sql);

if(rs.first()) {
do {
name = rs.getString("Name");
population = rs.getInt("Population");
output = String.format("Name: %s, Population: %d",
name, population);
System.out.println(output);
} while(rs.next());
} else {
System.out.println("No rows returned.");
}

s.close();
}
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 17
catch (SQLException se) {
showErrors(se);
}
...
7. Under the comment labelled “C. Close the database connection in a finally block”, write
code that closes the database connection regardless of the success or failure of the query.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following code in the ExceptionExample.java file under the comment labelled
“C. Close the database connection in a finally block”:
...
s.close();
}
catch (SQLException se) {
showErrors(se);
}
// C. Close the database connection in a finally block
ble
finally {
fe r a
if (conn != null) {
ans
try {
n - t r
no
conn.close ();
System.out.println ("Disconnected");
} s a
h a
r) deฺ
catch (SQLException se) {
showErrors(se);
ฺ b
m Gui
}
}
c o
rฺ ent
p a
one s Stud
}
}
s
// D. Write code
i c c i@
e t hi SQLException errors
to display

r t
private void
o ฺr showErrors(SQLException
u s se) {
e t o
System.out.println("There has been an error.");
}rob e
} ci (
c e ns
8. Ric li
Compile and execute the ExceptionExample.java file.
e r toEnter the following commands at the Linux terminal prompt and receive the results shown:
R ob # javac ExceptionExample.java
# java ExceptionExample
Thu May 12 10:18:36 UTC 2016 WARN: Establishing SSL connection
...
Connected.
Name: China, Population: 1277558000
Name: India, Population: 1013662000
Name: United States, Population: 278357000
Name: Indonesia, Population: 212107000
Name: Brazil, Population: 170115000
Name: Pakistan, Population: 156483000
Name: Russian Federation, Population: 146934000
Name: Bangladesh, Population: 129155000
Name: Japan, Population: 126714000
Name: Nigeria, Population: 111506000
Disconnected
#
− Ignore the SSL warning.
− The program compiles and executes without any errors.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 18
9. Change the program so that it attempts to query the database using the SQL statement
string provided in variable sql2 instead of sql1.
Modify the following line of code in the ExceptionExample.java file:
...
// B. Wrap query attempt in a try/catch block
try {
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

String name, output;


int population;
String sql1 = "SELECT Name, Population "
+ "FROM Country "
+ "ORDER BY Population DESC LIMIT 10";
String sql2 = "SELECT WrongColumn FROM WrongTable";
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery(sql2);

if(rs.first()) { ble
do {
fe r a
...
ans
10. Compile and execute the ExceptionExample.java file. What happens? n - t r
a no
Enter the following commands at the Linux terminal prompt and receive the results shown:
# javac ExceptionExample.java h a s
# java ExceptionExample
ฺ b r) deฺ
Thu May 12 10:18:36 UTC 2016 WARN: Establishing
o m GuSSL i connection
...
a c
rฺ ent
p
one s Stud
Connected.
There has been an error.
s
i@ withthani error. There are no details about the error,
Disconnected

i c c
The program compiles and
t o ฺ
making this issue difficult
executes
r to debug.
u se
b e r o Write code to display SQLException errors”, modify the
t“D.
(ro method
11. Under the comment e
nsof the ExceptionExample class so that it displays the following
labelled
c i c e
icdetails: li
showErrors()
R
error

berto• Error message


Ro • SQLSTATE
• MySQL error code
Add the following code to the ExceptionExample.showErrors() method:
...
// D. Write code to display SQLException errors
private void showErrors(SQLException se) {
System.out.println("There has been an error.");
System.err.println ("SQLException: " + se.getMessage ());
System.err.println ("SQLState: " + se.getSQLState ());
System.err.println ("MySQL Error code: " + se.getErrorCode ());
}
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 19
12. Compile and execute the ExceptionExample.java file. What happens?
Enter the following commands at the Linux terminal prompt and receive the results shown:
# javac ExceptionExample.java
# java ExceptionExample
Thu May 12 10:18:36 UTC 2016 WARN: Establishing SSL connection
...
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Connected.
There has been an error.
SQLException: Table 'world.WrongTable' doesn't exist
SQLState: 42S02
MySQL Error code: 1146
Disconnected
#
The program compiles and executes with an error as before, but this time provides more
helpful error information.
ble
13. Close any open terminal windows.
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 20
Practice 5-5: Handling Errors and Warnings When Coding with
Connector/Python
Overview
In this practice, you generate and handle MySQL errors and warnings using Connector/Python.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You are logged in to a Linux terminal window as the root user (password: oracle).

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
ble
1. Change the current working directory to /labs/python/cli/activity5-5 and display
fe r a
the contents of the directory.
ans
2. Copy the ExceptionExample_start.py file to ExceptionExample.py.
n - t r
o
an
3. Inspect the contents of the ExceptionExample.py file in a text editor.
4. Make the ExceptionExample.py file executable. s
ha ฺ
5. Execute the ExceptionExample.py program. r )
ฺb uide
m
6. Change the ExceptionExample.py program so that it attempts to query the database
r ฺco nt G
using the SQL statement string provided in variable sql2 instead of sql1.
a
o n ep tude
7. Save and execute the ExceptionExample.py program.
s is S
8. Under the comment labelled “A. Wrap connection attempt in a try/except block”, write code
@
c i th
that attempts to connect to the database using the connection parameters provided. If the
c
r i e
e r toฺ to us
connection attempt fails, catch the mysql.connector.Error object and use it to display
the error code and error message before exiting the program.
i ( rob ense
9. Under the comment labelled “B. Wrap query attempt in a try/except block”, write code that
c lic
to Ric
attempts to query the database using the SQL statement string provided in variable sql1. If
the query attempt fails, catch the mysql.connector.Error object and use it to display
e r
R ob the error code and error message.
10. Execute the ExceptionExample.py script again. What happens?
11. Close any open terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 21
Solution 5-5: Handling Errors and Warnings When Coding with
Connector/Python
Solution Steps
1. Change the current working directory to /labs/python/cli/activity5-5 and display
the contents of the directory.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/python/cli/activity5-5/
# ls
ExceptionExample_soln.py ExceptionExample_start.py
2. Copy the ExceptionExample_start.py file to ExceptionExample.py.
# cp ExceptionExample_start.py ExceptionExample.py
# ls
ble
ExceptionExample.py ExceptionExample_start.py
fe r a
ExceptionExample_soln.py
ans
3. Inspect the contents of the ExceptionExample.py file in a text editor.
n - t r
The contents of the ExceptionExample.py file are as follows:
a no
#!/usr/bin/python
h a s
ฺ b r) deฺ
m Gui
import sys
import mysql.connector
c o
rฺ ent
p a
conn = None
conn_params = {
s o ne Stud
"database": "world",@
c i t h is
"host": "localhost",
"user": "root",
t o ฺ ric use
b e r "oracle"to
}
"password":
(=ro"SELECT s e
nName,
c c
sql1 i l i c e Population FROM Country ORDER BY Population DESC
R i LIMIT 10"

e r to sql2 = "SELECT WrongColumn FROM WrongTable"

R ob # A. Wrap connection attempt in try/except block


conn = mysql.connector.connect(**conn_params)
print("Connected to the database server")

# B. Wrap query attempt in a try/except block


cursor = conn.cursor()
cursor.execute(sql1)
rows = cursor.fetchall()
for row in rows:
print("Name %s, Population: %d" % (row[0], row[1]))
cursor.close()

conn.close()
print("Disconnected from the database server")

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 22
4. Make the ExceptionExample.py file executable.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# chmod +x ExceptionExample.py
# ls -al
total 20
drwxr-xr-x 2 root root 4096 May 12 2016 .
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

drwxr-xr-x 4 root root 4096 May 12 09:38 ..


-rwxr-xr-x 1 root root 727 May 12 10:39 ExceptionExample.py
-rw-r--r-- 1 root root 1112 May 12 2016 ExceptionExample_soln.py
-rw-r--r-- 1 root root 727 May 12 2016 ExceptionExample_start.py
5. Execute the ExceptionExample.py program.
Enter the following command at the Linux terminal prompt and receive the results shown:
# python ExceptionExample.py
Connected to the database server
ble
Name China, Population: 1277558000
fe r a
Name India, Population: 1013662000
ans
Name United States, Population: 278357000
Name Indonesia, Population: 212107000
n - t r
Name Brazil, Population: 170115000
a no
Name Pakistan, Population: 156483000
Name Russian Federation, Population: 146934000
h a s
Name Bangladesh, Population: 129155000
ฺ b r) deฺ
Name Japan, Population: 126714000
c o m Gui
Name Nigeria, Population: 111506000
Disconnected from the database server
p a rฺ ent
− The program executes without
s neerrors.
oany S tud
6. Change the ExceptionExample.py
c i @ program
t h is so that it attempts to query the database
using the SQL statement ฺ c provided
ristring se in variable sql2 instead of sql1.
r t o u
to program as follows:
b e
Modify the ExecutionExample.py
e
ro query
# B. (Wrap
i e nsattempt in a try/except block
c c
icursor li c
= conn.cursor()
R
erto rows = cursor.fetchall()
cursor.execute(sql2)

b
Ro 7. Save and execute the ExceptionExample.py program.
Enter the following command at the Linux terminal prompt and receive the results shown:
# python ExceptionExample.py
Connected to the database server
Traceback (most recent call last):
File "ExceptionExample.py", line 22, in <module>
cursor.execute(sql2)
File "/usr/lib/python2.6/site-packages/mysql/connector/cursor.py",
line 515, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/usr/lib/python2.6/site-
packages/mysql/connector/connection.py", line 488, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY,
query))
File "/usr/lib/python2.6/site-
packages/mysql/connector/connection.py", line 395, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1146 (42S02): Table
'world.WrongTable' doesn't exist
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 23
− The program executes with a difficult-to-read error message, which you would not
want to display to users.
8. Under the comment labelled “A. Wrap connection attempt in a try/except block”, write code
that attempts to connect to the database using the connection parameters provided. If the
connection attempt fails, catch the mysql.connector.Error object and use it to display
the error code and error message before exiting the program.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Make the following changes to the code in the ExceptionExample.py file under the
comment labelled “A. Wrap connection attempt in a try/except block”:
...
# A. Wrap connection attempt in try/except block
try:
conn = mysql.connector.connect(**conn_params)
print("Connected to the database server")

except mysql.connector.Error as e:
ble
print("Cannot connect to server")
fe r a
print("Error code: %s" % e.errno)
ans
print("Error message: %s" % e.msg)
n - t r
no
print("Terminating.")
sys.exit(1)
s a
...
h a
9. Under the comment labelled “B. Wrap query attempt in a b
ฺ r) dblock”,
try/except e ฺ write code that
attempts to query the database using the SQL statement
om string i
uprovided in variable sql1. If
r ฺ
the query attempt fails, catch the mysql.connector.Error
a den c t G object and use it to display
the error code and error message. e p
Make the following changes to the s onin the
code S tu
ExceptionExample.py file under the
comment labelled “B. Wrap query c i@attempt
t s
hini a try/except block”:
ฺr i c e
...
r t o t o us
# B. Wrapbe
try: (ro n s e
query attempt in a try/except block

c c i l i c e
R i cursor.execute(sql1)
cursor = conn.cursor()

ert o rows = cursor.fetchall()


b
Ro
for row in rows:
print("Name %s, Population: %d" % (row[0], row[1]))
cursor.close()
except mysql.connector.Error as e:
print("The query failed:")
print("Error code: %s" % e.errno)
print("Error message: %s" % e.msg)

conn.close()
print("Disconnected from the database server")

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 24
10. Execute the ExceptionExample.py script again. What happens?
Enter the following command at the Linux terminal prompt and receive the results shown:
# python ExceptionExample.py
Connected to the database server
The query failed:
Error code: 1146
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Error message: Table 'world.WrongTable' doesn't exist


Disconnected from the database server
− The ExceptionExample.py script generates an error when attempting to execute
the query. The error is caught by the exception handler and displays useful error
information before resuming processing.
11. Close any open terminal windows.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 25
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 5: Handling Errors and Warnings


Chapter 5 - Page 26
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 6:
Building u i
om Database-Driven
r ฺ c n
a Applicationst G
Web
p d e
e
on Chaptertu6
s s S
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 1
Practices for Lesson 6: Building Database-Driven Web Applications
Practices Overview
These practices test your knowledge of writing MySQL Connector code to create database-
driven web applications. They assume that you are using the Linux operating system
environment provided in Oracle classrooms. For non-Oracle classrooms, you might need to
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

make some adjustments to the file locations.


Important: The coding practices in this lesson are available in PHP, Java, and Python. Perform
all the practices for this and all future coding activities in only one language, choosing the
language you are most familiar with. If in doubt, perform the PHP activities. Ensure that you
complete all practices that are not language-specific
For this lesson, perform the following practices:
• If your chosen programming language is PHP:
ble
− Practice 6-1: Displaying Query Results in a Table Using PHP/PDO
fe r a
− Practice 6-4: Paging Query Results Using PHP/PDO ans
− Practice 6-7: Enabling Sorting of Query Results Using PHP/PDO n - t r
o
• If your chosen programming language is Java:
s an
r ) ha ฺ
− Practice 6-2: Displaying Query Results in a Table Using Java/JSP
ฺb uide
− Practice 6-5: Paging Query Results Using Java/JSP
m
r ฺco nt G
− Practice 6-8: Enabling Sorting of Query Results Using Java/JSP
a
o n ep tude
• If your chosen programming language is Python:
s is S
− Practice 6-3: Displaying Query Results in a Table Using Python
@
c c i th
i e
− Practice 6-6: Paging Query Results Using Python
r
r toฺ to us
− Practice 6-9: Enabling Sorting of Query Results Using Python
e
Assumptions i ( rob ense
c are completing
cyou
•RiIf
lic the coding practices in PHP:
r t o
obe
− The Apache web server is installed and running on port 80
R • If you are completing the coding practices in Java:
− The Tomcat application server is installed and running on port 8080
• If you are completing the coding practices in Python:
− The Apache web server is installed and running on port 80.
• The world sample database is installed.
• The /labs directory contains the course practice files and scripts.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 2
Practice 6-1: Displaying Query Results in a Table Using PHP/PDO
Overview
In this practice, you display the results of a query in a tabular format on a web page using
PHP/PDO.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a terminal window open and are logged in as the Linux root user.

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
1. In a Linux terminal window, list the contents of the /labs/php/web/activity6-1 ble
directory. fe r a
2. Copy the layout_start.php file to create a new file called layout.php. ans
n - t r
3. Examine the contents of the conn.php script. What is the purpose of this script? o
an
4. Examine the contents of the index.php script. What is the purpose of this script?
s
r ) ha ฺ
5. Open the layout.php script in a text editor. This script contains the beginnings of the
ฺb uide
show_in_table() function. The following steps tell you how to complete the function,
m
using the comments as a guide.
a r ฺco nt G
n ep tude
6. Under the comment labelled “A. Get table headers from the result set”, write PHP code to
retrieve the first row in the $items array. Use the use PHP’s current() function to return
o
s is S
the first array element and store it in a variable called $fields.
@
c c i th
i e
7. Under the comment labelled “B. Print table headers”, process each key/value pair in the
r
e r toฺ to us
$fields array and use the key as the heading for each column in the HTML table. Append

i ( rob ense
the appropriate markup to the $result variable.
Note: You can use <th></th> table header tags to make the column names appear in
c lic
to Ric
bold format. Ensure that you close the enclosing table row (<tr>) tag for the header row.
e r
8. Locate the loop in the page that iterates through the rows in the $items result set array.
R ob Within this loop is a nested loop, which iterates through each column value in the row.
Under the comment labelled “C. Get each column value from the row”, write PHP code that
populates each column in the HTML table with the column value from the result set. Ensure
that each column value is properly encoded to display any accented characters correctly.
9. Under the comment labelled “D. Close tag for current row”, write PHP code that creates the
appropriate markup to close the current row tag.
10. Under the comment labelled “E. Close table tag”, write PHP code that creates the
appropriate markup to close the table tag.
11. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost/php/activity6-1/index.php.
12. Leave the Linux terminal window and Firefox browser open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 3
Solution 6-1: Displaying Query Results in a Table Using PHP/PDO
Solution Steps
1. In a Linux terminal window, list the contents of the /labs/php/web/activity6-1
directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/php/web/activity6-1
# ls
conn.php index.php layout_soln.php layout_start.php
2. Copy the layout_start.php file to create a new file called layout.php.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp layout_start.php layout.php
[root@edddr9p1 activity6-1]# ls
ble
conn.php layout_soln.php index.php
fe r a
layout.php layout_start.php
ans
3. Examine the contents of the conn.php script. What is the purpose of this script?
n - t r
no
Enter the following command at the Linux terminal prompt and receive the results shown:
a
# cat conn.php
h a s
<?php
ฺ b r) deฺ
# conn.php: utility library for connecting
c o m to Gtheui MySQL Server
p a rฺ ent
ne Stud
try {
# Create the DSN
s o
i @ this
$dsn = "mysql:host=localhost;dbname=world";
c
# Connect toothe
t ฺ ricdatabase
u se server
ber PDOse($dsn,
$dbh = new
echoro
toto "root", "oracle");

} ci ( c e n
"<p>Connected the database server</p>";
c l i
Ricatch (PDOException $e) {
e r to die ("<p>Cannot connect to the database server</p>");

R ob }

?>
− Answer: The conn.php script tries to connect to the world database on the
MySQL server and fails gracefully if the connection is unsuccessful.
4. Examine the contents of the index.php script. What is the purpose of this script?
# cat index.php
<!doctype html>
<html>
<head>
<title>Activity 6-1 (PHP)</title>
</head>
<body>
<h1>Activity 6-1 (PHP)</h1>

<?php
require_once "conn.php";
require_once "layout.php";

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 4
$sql = "SELECT * FROM City ORDER BY Population DESC LIMIT 5";
$sth = $dbh->query ($sql);
$items = $sth->fetchAll (PDO::FETCH_ASSOC);

# generate table
print (show_in_table ($items));
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$dbh = NULL;
echo("<p>Disconnected from the database server</p>");

?>
</p>
</body>
</html>
− Answer: The index.php script queries the City table for the five most populated
cities and returns the results in descending order of population. The script then
ble
passes the results of the query (an associative array) to the show_in_table()
fe r a
function in layout.php and prints the return value.
ans
5. Open the layout.php script in a text editor. This script contains the beginnings of the
n - t r
show_in_table() function. The following steps tell you how to complete the function, o
using the comments as a guide.
s an
The contents of the layout.php script are as follows:
r ) ha ฺ
<?php
m ฺb uide
function show_in_table ($items) {
a r ฺco nt G
$result = "";
o n ep tude
S result set
s fromisthe
i @ h
cc se t
// A. Get table headers

$result =to ฺ r i u
// B.be
r "<table t o border='1'>\n<tr>\n";

ro ense
Print table headers

c i (
Ric lic
e r to // Retrieve each row from the resultset

R ob foreach ($items as $row) {


// C. Generate output for new row

foreach ($row as $val) {


// D. Get each column value from the row

}
}
// E. Close tag for current row

// F. Close table tag

return $result;
}
?>
6. Under the comment labelled “A. Get table headers from the result set”, write PHP code to
retrieve the first row in the $items array. Use the use PHP’s current() function to return
the first array element and store it in a variable called $fields.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 5
Note: Every array has an internal pointer to its "current" element, which is initialized to the
first element that was inserted into the array.
Enter the following code in the layout.php script under the comment labelled “A. Get
table headers from the result set”:
...
// A. Get table headers from the result set
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$fields = current($items);
...
7. Under the comment labelled “B. Print table headers”, process each key/value pair in the
$fields array and use the key as the heading for each column in the HTML table. Append
the appropriate markup to the $result variable.
Note: You can use <th></th> table header tags to make the column names appear in
bold format. Ensure that you close the enclosing table row (<tr>) tag for the header row.
Enter the following code in the layout.php script under the comment labelled “B. Print
ble
table headers”:
fe r a
...
ans
$result = "<table border='1'>\n<tr>\n";
n - t r
// B. Print table headers
foreach ($fields as $key => $value) { a no
$result .= "<th>$key</th>\n";
h a s
}
ฺ b r) deฺ
$result .= "</tr>\n";
c o m Gui
...
8. Locate the loop in the page that iterates through p a rฺthe rows
e n t the $items result set array.
in
Within this loop is a nested loop, which
s S tud each column value in the row.
e through
oniterates
Under the comment labelled “C.
c i @Get each
t h is value from the row”, write PHP code that
column
populates each column in
ฺ cthe HTMLsetable with the column value from the result set. Ensure
riproperly
that each column valuer t o is
t o u encoded to display any accented characters correctly.
e
b codesinethe layout.php script under the comment labelled “C. Get
i ( rovalue
Enter the following
e n the row”:
c c
each column
i... l i c from

o R
bert // Retrieve each row from the resultset

Ro
foreach ($items as $row) {
// Generate output for new row
$result .= "<tr>\n";
foreach ($row as $val) {
// C. Get each column value from the row
$val_html = htmlentities($val);
$result .= "<td>$val_html</td>\n";
}
}
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 6
9. Under the comment labelled “D. Close tag for current row”, write PHP code that creates the
appropriate markup to close the current row tag.
Enter the following code in the layout.php script under the comment labelled “D. Close
tag for current row”:
...
// D. Close tag for current row
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$result .= "</tr>\n";
...
10. Under the comment labelled “E. Close table tag”, write PHP code that creates the
appropriate markup to close the table tag.
Enter the following code in the layout.php script under the comment labelled “D. Close
table tag”:
...
// E. Close table tag
ble
$result .= "</table>\n";
fe r a
ans
}
return $result;
n - t r
o
an
11. Save your work and launch the index.php page in the Firefox browser by visiting the
s
r ) ha ฺ
following URL: http://localhost/php/activity6-1/index.php.
The page displays the following:
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

12. Leave the Linux terminal window and Firefox browser open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 7
Practice 6-2: Displaying Query Results in a Table Using Java/JSP
Overview
In this practice, you display the results of a query in a tabular format on a web page using
Java/JSP.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a terminal window open and are logged in as the Linux root user.

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
1. In a Linux terminal window, list the contents of the /labs/java/web/activity6-2 ble
directory. fe r a
2. Copy the index_start.jsp file to create a new file called index.jsp. ans
n - t r
3. Examine the contents of the WEB-INF/conn.inc file. What is the purpose of the JSTL o
markup in this file?
s an
r ) ha ฺ
4. Open the index.jsp page in a text editor. The code in this page connects to the world
ฺb uide
database and then creates an HTML table. The following steps tell you how to complete
m
ฺco nt G
and populate the table, using the comments as a guide.
a r
5. Under the comment labelled “A. Get column names for header row”, use the result set’s
n ep tude
columnNames property to iterate through the column names and display each in a table
o
s is S
header tag (<th>) in the first row of the HTML table.
@
c c i th
6. Under the comment labelled “B. Iterate through each row”, create a <c:forEach> loop
r i e
e r toฺ to us
that iterates through each row in the result set.

i ( rob ense
7. Under the comment labelled “C. Create a row in the HTML table for each row in the result
set”, create the HTML row tag that will display the contents of each row.
c lic
Ric
8. Under the comment labelled “D. Create a column in the HTML table for each column in the
to
e r result set”, loop through each column value in the row and output it as an HTML table

R ob column entry using the <td> tag.


9. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost:8080/activity6-2/index.jsp.
10. Leave the Linux terminal window and Firefox browser open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 8
Solution 6-2: Displaying Query Results in a Table Using Java/JSP
Solution Steps
1. In a Linux terminal window, list the contents of the /labs/java/web/activity6-2
directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/java/web/activity6-2
# ls
index_soln.jsp index_start.jsp WEB-INF
2. Copy the index_start.jsp file to create a new file called index.jsp.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp index_start.jsp index.jsp
# ls
ble
index.jsp index_soln.jsp index_start.jsp WEB-INF
fe r a
3. Examine the contents of the WEB-INF/conn.inc file. What is the purpose of the JSTL
ans
markup in this file?
n - t r
no
Enter the following command at the Linux terminal prompt and receive the results shown:
a
# cat WEB-INF/conn.inc
h a s
<c:catch var="connexception">
ฺ b r) deฺ
<sql:setDataSource
var="conn"
c o m Gui
driver="com.mysql.jdbc.Driver" rฺ t
p a e n
user="root"
s o ne Stud
url="jdbc:mysql://localhost/world"

password="oracle" @
c i t h is
/>
t o ฺ ric use
</c:catch>
b e r toin WEB-INF/conn.inc tries to connect to the world
− Answer: The markup
(ro conethe e
nsMySQL server and raises an exception if the connection is
c i
database
li
Ric unsuccessful.
toOpen the index.jsp page in a text editor. The code in this page connects to the world
e r
4.

R ob database and then creates an HTML table. The following steps tell you how to complete
and populate the table, using the comments as a guide.
The contents of the index.jsp page are as follows:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ include file="/WEB-INF/conn.inc" %>

<!DOCTYPE html>
<html>
<head>
<title>Activity 6-2 (Java)</title>
</head>
<body>
<h1>Activity 6-2 (Java)</h1>
<c:choose>
<c:when test="${not empty connexception}">
<p>Error connecting to the database</p>
</c:when>
<c:otherwise>
<p>Connected to the database</p>
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 9
</c:otherwise>
</c:choose>

<sql:query dataSource="${conn}" var="rs">


SELECT * FROM City ORDER BY Population DESC LIMIT 5
</sql:query>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<table border="1">
<%-- A. Get column names for header row --%>

<%-- B. Iterate through each row --%>

<%-- C. Create a row in the HTML table for each row in the
resultset --%>

<%-- D. Create a column in the HTML table for each column


in the result row --%> ble
fe r a
</table>
ans
</body>
n - t r
</html>
n o
5. Under the comment labelled “A. Get column names for header row”, a
suse the result set’s
columnNames property to iterate through the column names and h adisplay each in a table
header tag (<th>) in the first row of the HTML table. ฺ b r) deฺ
o m u i labelled “A. Get column
names for header row”: a c
Enter the following code in the index.jsp file under
rฺ ent G
the comment
p
ne Stud
...
s o
<table border="1">
c i @ this
<tr>
ric column
<%-- A. ฺGet
t o u senames for header row --%>
e r
<c:forEach
b tovalue="${columnName}" /></th>
items="${rs.columnNames}" var="columnName">
(ro</c:forEach>
ns e
<th><c:out
c i li c e
R ic </tr>
erto
...
b
Ro 6. Under the comment labelled “B. Iterate through each row”, create a <c:forEach> loop
that iterates through each row in the result set.
Enter the following code in the index.jsp file under the comment labelled “B. Iterate
through each row”:
...
<%-- B. Iterate through each row --%>
<c:forEach items="${rs.rowsByIndex}" var="row">
<%-- C. Create a row in the HTML table for each row in the
resultset --%>

<%-- D. Create a column in the HTML table for each column


in the result row --%>

</c:forEach>
...
7. Under the comment labelled “C. Create a row in the HTML table for each row in the result
set”, create the HTML row tag that will display the contents of each row.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 10
Enter the following code in the index.jsp file under the comment labelled “C. Create a
row in the HTML table for each row in the result set”:
...
<%-- B. Iterate through each row --%>
<c:forEach items="${rs.rowsByIndex}" var="row">
<%-- C. Create a row in the HTML table for each row in the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

resultset --%>
<tr>
<%-- D. Create a column in the HTML table for each column
in the result row --%>

</tr>
</c:forEach>
...
8. Under the comment labelled “D. Create a column in the HTML table for each column in the
result set”, loop through each column value in the row and output it as an HTML table ble
column entry using the <td> tag. fe r a
Enter the following code in the index.jsp file under the comment labelled “D. Create a ans
column in the HTML table for each column in the result set”: n - t r
... a no
<%-- B. Iterate through each row --%>
h a s
<c:forEach items="${rs.rowsByIndex}" var="row">
ฺ b r) fordeach
e ฺ row in the
<%-- C. Create a row in the HTML table
u i
om t Gresultset
a r ฺ c n
--%>

ep intuthedeHTML table for each column


<tr>

o n
<%-- D. Create a column
s is Svar="column">in the result row --%>
@
<c:forEach iitems="${row}"
th
c value="${column}"/></td>
r i c e
oฺ to us
<td><c:out
r t
</c:forEach>
e
r o b
</tr>
se
c i ( e
</c:forEach>n
Ric
... lic
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 11
9. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost:8080/activity6-2/index.jsp.
The page displays the following:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
o mopen for u i next practice.
10. c
Leave the Linux terminal window and Firefox browser
a rฺ ent G the
p
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 12
Practice 6-3: Displaying Query Results in a Table Using Python
Overview
In this practice, you display the results of a query in a tabular format on a web page using
Python.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a terminal window open and are logged in as the Linux root user.

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
1. In the Linux terminal window, list the contents of the ble
/labs/python/web/activity6-3 directory. fe r a
2. Copy the layout_start.py file to create a new file called layout.py. ans
n - t r
3. Examine the contents of the conn.py file. What is the purpose of this Python code? o
4. an
Examine the contents of the index.py file. What is the purpose of the Python code in this
s
file?
r ) ha ฺ
5. ฺb uide
Open the layout.py program in a text editor. This program contains the beginnings of the
m
using the comments as a guide. a r ฺco nt G
show_in_table() function. The following steps tell you how to complete the function,

6. n ep tude
Under the comment labelled “A. Get column names”, write code that uses the
o
s is S
column_names property of the cursor object to retrieve a list of column names. Store the
@
c c i th
results in a variable called colnames.
r i e
7. toฺ to us
Under the comment labelled “B. Create header row for table from column names”, write
e r
i ( rob ense
code that creates the header row, looping through each column name in the colnames
variable and enclosing it within table header tags (<th></th>). Append the generated
c lic
to Ric
markup to the results variable.

e r
8. Under the comment labelled “C. Loop through the rows in the result set”, write code to

R ob create a for loop that iterates through each row in the result set.
9. Under the comment labelled “D. Create a new row in the HTML table for each row in the
result set”, write code that appends a new row to the table using <tr></tr> tags. Create a
variable called count to keep track of the row numbers and initialize it to zero.
10. Under the comment labelled “E. Populate the HTML table columns with the column values
in the result set”, write code that iterates through each column in the current row and
outputs its value in column tags (<td></td>).
11. Save your work.
12. Make the scripts in the labs/python/web/activity6-3 directory executable.
13. Open the index.py page in the Firefox browser by visiting the following URL:
http://localhost/cgi-bin/activity6-3/index.py.
14. Leave the Linux terminal window and Firefox browser open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 13
Solution 6-3: Displaying Query Results in a Table Using Python
Solution Steps
1. In the Linux terminal window, list the contents of the
/labs/python/web/activity6-3 directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/python/web/activity6-3
# ls
conn.py index.py layout_soln.py layout_start.py
2. Copy the layout_start.py file to create a new file called layout.py.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp layout_start.py layout.py
# ls
conn.py index.py layout.py layout_soln.py layout_start.py ble
3. Examine the contents of the conn.py file. What is the purpose of this Python code? fe r a
ans
The contents of the conn.py file are as follows:
n - t r
o
an
# cat conn.py
# conn.py: library file for connecting to MySQL using the
Connector/Python s
ha ฺ
# module r )
ฺb uide
m
r
# A. Add a reference to the Connector/Python
a ฺco nt module
G
import mysql.connector
o n ep tude
conn = None
@ s is S
c i th
c connection
ฺ r i
# B. Provide appropriate
u s e parameters
conn_params r=to o
be "world",
{
e t
r o
"database":
n s
i ( li"localhost",
c c
"host":
c e
to Ri "user": "root",
"password": "oracle"
e r
ob
}
R def dbconnect():
try:
global conn

# C. Connect to the database and return the connection object


conn = mysql.connector.connect(**conn_params)
print('''<p>Connected to the database</p>''')
return conn
except:
print('''<p>Could not connect to the database</p>''')

def dbclose():
if conn is None:
print('''</p>Can't disconnect: there is no connection</p>''')
else:
# D. Close the connection

print('''<p>Disconnected from the database</p>''')

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 14
− Answer: The code in the conn.py file provides functions that connect and
disconnect to the world database on the MySQL server.
4. Examine the contents of the index.py file. What is the purpose of the Python code in this
file?
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cat index.py
#!/usr/bin/python

import conn
import sys
reload(sys) # Reload does the trick!
from layout import *

print('''Content-Type: text/html

ble
<html>
fe r a
<head><title>Activity 6-3 (Python)</title></head>
ans
<body>
''')
n - t r
o
print("<h1>Activity 6-3 (Python)</h1>")
s an
r ) ha ฺ
# Set the default encoding
sys.setdefaultencoding('UTF8') m ฺb uide
a r ฺco nt G
# Connect to the database
dbconn = conn.dbconnect()
o n ep tude
s is S
# Define the query ci@ th
r i c e
sql = '''
r us BY Population DESC LIMIT 5
toฺCitytoORDER
e
SELECT * FROM
'''
i ( rob ense
c c
to Ri#c Executelithe query
cursor = dbconn.cursor(buffered=True)
e r
ob
cursor.execute(sql)
R print(show_in_table(cursor))

cursor.close()

print("<p>Disconnecting from the database server</p>")


dbconn.close()

print('''
</body>
</html>
''')
− Answer: The index.py script queries the City table for the five most populated
cities and returns the results in descending order of population. The script then passes
the results of the query (as a cursor object) to the show_in_table() function in
layout.py and prints the return value.
5. Open the layout.py program in a text editor. This program contains the beginnings of the
show_in_table() function. The following steps tell you how to complete the function,
using the comments as a guide.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 15
The contents of the layout.py script are as follows:
import cgi

def show_in_table(cursor):
# A. Get column names

results = ""
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

results += '''<table border=1>'''

# B. Create header row for table from column names

# C. Loop through the rows in the resultset

# D. Create a new row in the HTML table for each row in the
resultset

ble
# E. Populate the HTML table columns with the column values in
fe r a
the resultset
ans
results += '''</table>'''
n - t r
return results
a no
6. Under the comment labelled “A. Get column names”, write code that
h a suses the
ฺ b )
column_names property of the cursor object to retrieve arlist of column
e ฺ names. Store the
results in a variable called colnames.
o m the u id
a r ฺ
Enter the following code in the layout.py programc under
n t G comment labelled “A. Get
column names”:
o n ep tude
...
@ s is S
c
def show_in_table(cursor):
# A. Get columnic
i th
r
oฺ to us
names e
colnames = tcursor.column_names
e r
i ( rob= e""nse
results

R ccresultsli+=c '''<table border=1>'''


i...
be7.rtoUnder the comment labelled “B. Create header row for table from column names”, write
Ro code that creates the header row, looping through each column name in the colnames
variable and enclosing it within table header tags (<th></th>). Append the generated
markup to the results variable.
Enter the following code in the layout.py program under the comment labelled “B. Create
header row for table from column names”:
...
# B. Create header row for table from column names
results += '''<tr>'''
for i in range(len(colnames)):
results += '''<th>''' + colnames[i] + '''</th>'''
results += '''</tr>'''
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 16
8. Under the comment labelled “C. Loop through the rows in the result set”, write code to
create a for loop that iterates through each row in the result set.
Enter the following code in the layout.py program under the comment labelled “C. Loop
through the rows in the result set”:
...
# C. Loop through the rows in the resultset
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

for j in range(cursor.rowcount):
row = cursor.fetchone()
...
9. Under the comment labelled “D. Create a new row in the HTML table for each row in the
result set”, write code that appends a new row to the table using <tr></tr> tags. Create a
variable called count to keep track of the row numbers and initialize it to zero.
Enter the following code in the layout.py program under the comment labelled “D.
Create a new row in the HTML table for each row in the result set”: e
r a bl
...
s fe
an
# D. Create a new row in the HTML table for each row in the
resultset
n - t r
no
results += '''<tr>'''
count = 0
s a
# E. Populate the HTML table columns with the column values in
h a
ฺ b r) deฺ
the resultset

results += '''</tr>'''
c o m Gui
...
p a rฺ ent
10. Under the comment labelled “E. Populate
in the result set”, write code that iterates s onethrough
the HTML
S udtable
teach columns with the column values
column in the current row and
outputs its value in column tags c i @ t h i
(<td></td>).
s
ฺ r i cthe s e
Enter the following code
e r t o to u
in layout.py program under the comment labelled “E.
Populate the HTML
r o b tablesecolumns with the column values in the result set”:
... i
c ( c e n
R c # C. l
Loopi
i for j in range(cursor.rowcount):
through the rows in the resultset

berto row = cursor.fetchone()


Ro # D. Create a new row in the HTML table for each row in the
resultset
results += '''<tr>'''
count = 0
# E. Populate the HTML table columns with the column values in
the resultset
for k in range(len(row)):
col = row[count]
results += "<td>" + str(col) + "</td>"
count += 1

results += '''</tr>'''

results += '''</table>'''
return results
11. Save your work.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 17
12. Make the scripts in the labs/python/web/activity6-3 directory executable.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# chmod +x *
# ls -al
...
drwxr-xr-x 2 root root 4096 Aug 24 13:45 .
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

drwxr-xr-x. 9 root root 4096 Aug 17 09:47 ..


-rwxr-xr-x 1 root root 820 Aug 21 08:44 conn.py
-rwxr-xr-x 1 root root 728 Aug 24 13:45 index.py
-rwxr-xr-x 1 root root 853 Aug 24 13:43 layout.py
-rwxr-xr-x 1 root root 853 Aug 14 16:06 layout_soln.py
-rwxr-xr-x 1 root root 434 Aug 14 16:05 layout_start.py
13. Open the index.py page in the Firefox browser by visiting the following URL:
http://localhost/cgi-bin/activity6-3/index.py.
The page displays the following:
ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
14. Leave the Linux terminal window and Firefox browser open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 18
Practice 6-4: Paging Query Results Using PHP/PDO
Overview
In this practice, you execute a query that returns over 200 rows, and enable users to view the
results ten rows at a time.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a terminal window open and are logged in as the Linux root user.
• You have the Firefox web browser open from the previous practice.

Duration
This practice should take you approximately 30 minutes to complete.

Tasks ble
1. In a Linux terminal window, list the contents of the /labs/php/web/activity6-4 fe r a
directory. ans
2. Copy the results_start.php file to create a new file called results.php. n - t r
o
3. an
Examine the index.php file. What is the purpose of this script?
s
4. ha ฺ
Open results.php in a text editor. This file contains the beginnings of a script that
r )
ฺb uide
displays Country table data in a tabular format on the page ten rows at a time. Users can
m
r ฺco nt G
navigate different “pages” of data by using the “Prev” and “Next” links. The following steps
tell you how to complete the script, using the comments as a guide.
a
5. n ep tude
Under the comment labelled “A. Get total number of rows”, retrieve the value of the
o
s is S
numrows query parameter in the URL for the page and store it in a variable called
@
$numrows.
c c i th
r i e
6. toฺ to us
Under the comment labelled “B. Determine which page of results to display”, use the PHP
e r
rob ense
isset() method to determine if the pagenum query parameter is present in the URL used

c i (
to access the page. If it is present, store the parameter value in a variable called
Ric lic
$pagenum. If it is not present, the page will display the first page of query results, so set

e r to $pagenum to 1.

R ob 7. Under the comment labelled “C. Page number of the last page”, calculate the number of
pages of results based on the number of rows in the Country table ($numrows) and the
number of rows per page ($page_rows). Store the page number of the last page in a
variable called $last_page.
8. Under the comment labelled “D. Ensure that current page number is within a valid range”,
test the value of $pagenum and adjust it if necessary so that it is neither less than one, or
greater than the value of $last_page.
9. Under the comment labelled “E. Set the LIMIT clause for the query”, create a string variable
called $sql_limit that uses the values of the $pagenum and the $page_rows variables
to create a SQL LIMIT clause in the following format:
LIMIT <offset>, <number of rows>
10. Under the comment labelled “F. Output result navigation links”, create the anchor tags for
the “Prev” and “Next” links. Set the links’ href attributes to the results.php page, with
suitable values for the pagenum query parameter depending on which direction the user is
navigating through the query results. Also set the numrows query parameter, which
specifies the total number of rows in the result set.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 19
11. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost/php/activity6-4/index.php.
12. Click the “View results” link and examine the URL to ensure that the number of rows in the
Country table is passed as a query parameter.
13. Navigate through the results by clicking the “Prev” and “Next” links and verify that the query
results display ten rows at a time.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

14. Leave the Linux terminal window and Firefox browser open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 20
Solution 6-4: Paging Query Results Using PHP/PDO
Solution Steps
1. In a Linux terminal window, list the contents of the /labs/php/web/activity6-4
directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/php/web/activity6-4
# ls
conn.php layout.php results_soln.php
index.php results_start.php
2. Copy the results_start.php file to create a new file called results.php.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp results_start.php results.php
ble
# ls
fe r a
conn.php layout.php
index.php results_soln.php
results.php results_start.php
ans
3. Examine the index.php file. What is the purpose of this script? n - t r
o
an
Enter the following command at the Linux terminal prompt and receive the results shown:
s
# cat index.php
r ) ha ฺ
<!doctype html>
m ฺb uide
ฺco nt G
<html>
<head>
a r
<title>Activity 6-4 (PHP)</title>
o n ep tude
</head>
@ s is S
<body>
c c i th
i
<h1>Activity 6-4 (PHP)</h1>
r e
e r toฺ to us
rob e"conn.php";
<?php
(
require_once
i n se
ccCount the
Ri// lic rows in the resultset
e r to $sql="SELECT COUNT(*) FROM Country";

R ob $result = $dbh->query($sql);
$row = $result->fetch(PDO::FETCH_NUM);
$rows = $row[0];

echo "<p>There are " . $rows . " rows in the Country table.</p>";
echo "<a href='results.php?numrows=" . $rows . "'>View results</a>";
?>

</body>
</html>
− Answer: The index.php script queries the Country table in the world database
to retrieve a count of the number of rows. It displays a link to the results.php
page, passing the number of rows as a query parameter.
4. Open results.php in a text editor. This file contains the beginnings of a script that
displays Country table data in a tabular format on the page, ten rows at a time. Users can
navigate different “pages” of data by using the “Prev” and “Next” links. The following steps
tell you how to complete the script, using the comments as a guide.
The contents of the results.php script are as follows:
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 21
<!doctype html>
<html>
<head>
<title>Activity 6-4 (PHP)</title>
</head>
<body>
<h1>Activity 6-4 (PHP)</h1>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<?php

require_once "conn.php";
require_once "layout.php";

// A. Get total number of rows

// B. Determine which page of results to display ble


fe r a
ans
// Number of rows per page
n - t r
$page_rows = 10;
a no
// C. Page number of the last page
h a s
ฺ b r) deฺ
// D. Ensure that current page number o ismwithin ua i valid range
a c
rฺ ent G
p
// E. Set the LIMIT clauseofor
s tud
netheSquery
c i @ this
t o ฺ ric use
// Execute the
b e r Code,toName, Continent, Population FROM Country
query

se
$sql = "SELECT " .
( r o
$sql_limit;
i n
cc "<p>" e
lic. $sql . "</p>";
Ri$sth
echo
= $dbh->query ($sql);
e r to $items = $sth->fetchAll (PDO::FETCH_ASSOC);

R ob // Output query results


print (show_in_table ($items));

// F. Output result navigation links

?>
5. Under the comment labelled “A. Get total number of rows”, retrieve the value of the
numrows query parameter in the URL for the page and store it in a variable called
$numrows.
Enter the following code under the comment labelled “A. Get total number of rows”:
...
<?php

require_once "conn.php";
require_once "layout.php";

// A. Get total number of rows


Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 22
$numrows = $_GET['numrows'];
...
6. Under the comment labelled “B. Determine which page of results to display”, use the PHP
isset() method to determine if the pagenum query parameter is present in the URL used
to access the page. If it is present, store the parameter value in a variable called
$pagenum. If it is not present, the page will display the first page of query results, so set
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$pagenum to 1.
Enter the following code under the comment labelled “B. Determine which page of results to
display”:
...
// B. Determine which page of results to display
if (isset($_GET['pagenum'])) {
$pagenum = $_GET['pagenum'];
} else {
$pagenum = 1;
ble
}
fe r a
...
t r a ns
7. Under the comment labelled “C. Page number of the last page”, calculate then
o - of
number
pages of results based on the number of rows in the Country table ($numrows) n
a last and the
number of rows per page ($page_rows). Store the page number ofsthe page in a
variable called $last_page.
r ) ha ฺ
Enter the following code under the comment labelled “C.ฺPage
m b number ide of the last page”:
o
ฺc nt G u
...
a r
// C. Page number of the last page
o n ep tude
s is S
$last_page = ceil($numrows/$page_rows);
@
...
c i
c“D. Ensure h current page number is within a valid range”,
tthat
8. Under the comment labelled r i e
s it if necessary so that it is neither less than one, or
r toฺ and
test the value of $pagenum
e t o uadjust
greater than o
r bvalue ofs$last_page.
the e
i ( e n
isR icc afollowing
Enter the
within
liccode under the comment labelled “D. Ensure that current page number
valid range”:
e r to ...
R ob // D. Ensure that current page number is within a valid range
if ($pagenum < 1) {
$pagenum = 1;
} elseif ($pagenum > $last_page) {
$pagenum = $last_page;
}
...
9. Under the comment labelled “E. Set the LIMIT clause for the query”, create a string variable
called $sql_limit that uses the values of the $pagenum and the $page_rows variables
to create a SQL LIMIT clause in the following format:
LIMIT <offset>, <number of rows>
Enter the following code under the comment labelled “E. Set the LIMIT clause for the
query”:
...
// E. Set the LIMIT clause for the query
$sql_limit = 'LIMIT ' . ($pagenum - 1) * $page_rows . ',' .
$page_rows;
...
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 23
10. Under the comment labelled “F. Output result navigation links”, create the anchor tags for
the “Prev” and “Next” links. Set the links’ href attributes to the results.php page, with
suitable values for the pagenum query parameter depending on which direction the user is
navigating through the query results. Also set the numrows query parameter, which
specifies the total number of rows in the result set.
Enter the following code under the comment labelled “F. Output result navigation links”:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

...
// F. Output result navigation links
echo "<a href='results.php?pagenum=" . ($pagenum - 1) . "&numrows=" .
$numrows . "'>Prev</a>&nbsp;";
echo "<a href='results.php?pagenum=" . ($pagenum + 1) . "&numrows=" .
$numrows . "'>Next</a>";
...
11. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost/php/activity6-4/index.php. ble
The page displays the following: fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 24
12. Click the “View results” link and examine the URL to ensure that the number of rows in the
Country table is passed as a query parameter.
The page displays the following:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
(ro ctheenresults
13. Navigatei through
c
s by clicking the “Prev” and “Next” links and verify that the query
results
R li rows at a time.
ic display ten
b rtoLeave the Linux terminal window and Firefox browser open for the next practice.
e14.
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 25
Practice 6-5: Paging Query Results Using Java/JSP
Overview
In this practice, you execute a query that returns over 200 rows, and enable users to view the
results ten rows at a time.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a terminal window open and are logged in as the Linux root user.
• You have the Firefox web browser open from the previous practice.

Duration
This practice should take you approximately 30 minutes to complete.

Tasks ble
1. In a Linux terminal window, list the contents of the /labs/java/web/activity6-5 fe r a
directory. ans
2. Copy the results_start.jsp files to create a new file called results.jsp. n - t r
o
3. an
Examine the index.jsp file. What is the purpose of this page?
s
4. ha ฺ
Open results.jsp in a text editor. This file contains the beginnings of a script that
r )
ฺb uide
displays Country table data in a tabular format on the page ten rows at a time. Users can
m
r ฺco nt G
navigate different “pages” of data by using the “Prev” and “Next” links. The following steps
tell you how to complete the script, using the comments as a guide.
a
5. n ep tude
Under the comment labelled “A. Get total number of rows”, use the built-in page param
o
s is S
object to retrieve the value of the numRows query parameter in the URL for the page and
@
c i th
store it in a variable called numRows.
c
r i e
6. toฺ to us
Under the comment labelled “B. Determine which page of results to display”, retrieve the
e r
rob ense
URL pageNumber parameter and use the <fmt:parseNumber> tag to convert it to a

c i (
numeric value.
7.
Ric lic
Under the comment labelled “C. Page number of the last page”, complete the variable

e r to assignment for the lastPageCalc variable by calculating the number of pages of results

R ob based on the number of rows in the Country table (numRows) and the number of rows per
page (rowsPerPage). Note how the code provided for you calculates the actual value of
lastPage based on the value of lastPageCalc.
8. Under the comment labelled “D. Ensure that current page number is within a valid range”,
test the value of pageNumber and adjust it, if necessary, so that it is neither less than zero
nor greater than the value of lastpage.
9. Under the comment labelled “E. Set the limit clause for the query”, create a variable called
limit that uses the values of the pageNumber and rowsPerPage variable to create a
SQL LIMIT clause in the following format:
LIMIT <offset>, <number of rows>
10. Under the comment labelled “F. Output result navigation links”, create the anchor tags for
the “Prev” and “Next” links. Set the links’ href attributes to the results.jsp page, with
suitable values for the pageNumber query parameter depending on which direction the
user is navigating through the query results. Also set the numrows query parameter that
specifies the total number of rows in the result set.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 26
11. Save your work and launch the index.jsp page in the Firefox browser by visiting the
following URL: http://localhost:8080/java/activity6-5/index.jsp. Navigate through the results
by clicking the “Prev” and “Next” links and verify that the query results display ten rows at a
time.
12. Leave the Linux terminal window and Firefox browser open for the next practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 27
Solution 6-5: Paging Query Results Using Java/JSP
Solution Steps

Tasks
1. In a Linux terminal window, list the contents of the /labs/java/web/activity6-5
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/java/web/activity6-5
# ls
index.jsp results_soln.jsp results_start.jsp WEB-INF
2. Copy the results_start.jsp files to create a new file called results.jsp.
Enter the following commands at the Linux terminal prompt and receive the results shown:
ble
# cp results_start.jsp results.jsp
fe r a
cp: overwrite `results.jsp'? y
ans
# ls
index.jsp results.jsp results_start.jsp n - t r
results_soln.jsp WEB-INF
a no
3. Examine the index.jsp file. What is the purpose of this page? as
r
Enter the following command at the Linux terminal promptband) hreceiveฺthe results shown:
m ฺ uide
# cat index.jsp
r o
ฺc nt G prefix="c" %>
a
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"
ep tu%>de
o n
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql"
s is S
<%@ include file="/WEB-INF/conn.inc"
prefix="sql" %>

i @
call rows h define max number of pages --%>
tto
r i c e
us
<%-- Get a count of
r to*ฺ FROM o
<sql:query dataSource="${conn}"
e t
var="countRs" scope="session">

rob ense
SELECT Country
i (
</sql:query>

R cc Passlinumber
i<%-- c of rows to results page --%>
e r t o <c:import url="results.jsp?numRows=${countRs.rowCount}" />
b
Ro − Answer: The index.jsp page queries the Country table in the world database
to retrieve a count of the number of rows. It then redirects to the results.jsp
page, passing the number of rows as a query parameter.
4. Open results.jsp in a text editor. This file contains the beginnings of a script that
displays Country table data in a tabular format on the page ten rows at a time. Users can
navigate different “pages” of data by using the “Prev” and “Next” links. The following steps
tell you how to complete the script, using the comments as a guide.
The contents of the results.jsp page are as follows:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ include file="/WEB-INF/conn.inc" %>

<!DOCTYPE html>
<html>
<head>
<title>Activity 6-5 (Java)</title>
</head>
<body>
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 28
<h1>Activity 6-5 (Java)</h1>
<c:choose>
<c:when test="${not empty connexception}">
<p>Error connecting to the
database</p>
</c:when>
<c:otherwise>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<p>Connected to the database</p>


</c:otherwise>
</c:choose>

<!-- A. Get total number of rows -->

<!-- B. Determine which page of results to display -->

ble
<!-- Number of rows in a page -->
fe r a
<c:set var="rowsPerPage" value="10" />
ans
n - t r
<!-- C. Page number of the last page -->
<c:set var="lastPageCalc">
a no
h a s
</c:set>
ฺ b r) duseeฺCeiling(N) ->
<!-- There is no 'round up' function in
${(N+(1-(N%1))%1)-1} -->
c o m Gui
JSTL,

(lastPageCalc % 1)) % 1) - 1} e
arฺ devalue="${(lastPageCalc
<fmt:formatNumber var="lastPageCeil" nt
"p maxFractionDigits="0"
+ (1 -

s
<fmt:parseNumber var="lastPage" u
on s Stvalue="${lastPageCeil}"
/>
/>
@
ci currenti
th page number is within a valid range --
r i c e
toฺ to us
<!-- D. Ensure that
>
e r
i ( robE. eSetnsthe
<!-- e limit clause for the query -->
c lic
to Ric <!-- Execute the query -->
e r <c:set var="query" value="SELECT Code, Name, Continent, Population

R ob FROM Country ${limit}" />


<sql:query dataSource="${conn}" var="rs">
${query}
</sql:query>

<!-- Output query results -->


<c:out value="${query}" /><br />

<table border="1">
<tr>
<%-- Get column names for header row --%>
<c:forEach items="${rs.columnNames}" var="columnName">
<th><c:out value="${columnName}" /></th>
</c:forEach>
</tr>
<%-- Iterate through each row --%>
<c:forEach items="${rs.rowsByIndex}" var="row">
<%-- Create a row in the HTML table for each row in the
resultset --%>
<tr>

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 29
<%-- Create a column in the HTML table for each column in the
result row --%>
<c:forEach items="${row}" var="column">
<td><c:out value="${column}"/></td>
</c:forEach>
</tr>
</c:forEach>
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

</table>

<!-- F. Output result navigation links -->

</body>
</html>
5. Under the comment labelled “A. Get total number of rows”, use the built-in page param
object to retrieve the value of the numRows query parameter in the URL for the page and
ble
store it in a variable called numRows.
fe r a
Enter the following code under the comment labelled “A. Get total number of rows”:
ans
... n - t r
<!-- A. Get total number of rows -->
a no
<c:set var="numRows" value="${param.numRows}" />
h a s
r) ddisplay”,
...
6. Under the comment labelled “B. Determine which page of ฺ b
results ito e ฺ retrieve the
c om t Gu tag to convert it to a
URL pageNumber parameter and use the <fmt:parseNumber>
r ฺ
numeric value.
e p a den
Enter the following code under the comment
s S tu “B. Determine which page of results to
on slabelled
display”:
c c i@ thi
...
o i
ฺr which u se page of results to display -->
e t
<!-- B. rDetermine
tovar="pageNumber" value="${param.pageNumber}" />
o b e
ns
<fmt:parseNumber
... i (r
c c e
li labelled “C. Page number of the last page”, complete the variable
ic the comment
R
7. Under
toassignment for the lastPageCalc variable by calculating the number of pages of results
e r
R ob based on the number of rows in the Country table (numRows) and the number of rows per
page (rowsPerPage). Note how the code provided for you calculates the actual value of
lastPage based on the value of lastPageCalc.
Enter the following code under the comment labelled “C. Page number of the last page”:
...
<!-- C. Page number of the last page -->
<c:set var="lastPageCalc">
${numRows/rowsPerPage}
</c:set>
<!-- There is no 'round up' function in JSTL, use Ceiling(N) ->
${(N+(1-(N%1))%1)-1} -->
<fmt:formatNumber var="lastPageCeil" value="${(lastPageCalc + (1
- (lastPageCalc % 1)) % 1) - 1} " maxFractionDigits="0" />
<fmt:parseNumber var="lastPage" value="${lastPageCeil}" />
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 30
8. Under the comment labelled “D. Ensure that current page number is within a valid range”,
test the value of pageNumber and adjust it, if necessary, so that it is neither less than zero
nor greater than the value of lastpage.
Enter the following code under the comment labelled “D. Ensure that current page number
is within a valid range”:
...
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<!-- D. Ensure that current page number is within a


valid range -->
<c:if test="${pageNumber < 1}" >
<fmt:parseNumber var="pageNumber" value="0" />
</c:if>
<c:if test="${pageNumber > lastPage}" >
<fmt:parseNumber var="pageNumber" value="${lastPage}" />
</c:if>
...
ble
9. Under the comment labelled “E. Set the limit clause for the query”, create a variable called
fe r a
limit that uses the values of the pageNumber and rowsPerPage variable to create a
ans
SQL LIMIT clause in the following format:
n - t r
LIMIT <offset>, <number of rows>
a no
Enter the following code under the comment labelled “E. Set the limit
h a s clause for the query”:
...
ฺ b r) -->deฺ
<!-- E. Set the limit clause for the query
c o m Gui * rowsPerPage)},
p a rฺ ent ${rowsPerPage}" />
<c:set var="limit" value="LIMIT ${(pageNumber

...
s o ne Stud
10. Under the comment labelled “F.
c i @ t h is navigation links”, create the anchor tags for
Output result

suitable values for r t


theo ฺricSet the
the “Prev” and “Next” links.
u equeryhref
slinks’ attributes to the results.jsp page, with
parameter depending on which direction the
b
user is navigating e toquery results. Also set the numrows query parameter that
pageNumber
throughethe
(rototalcnumber
specifiesi the
c e ns of rows in the result set.
Enter
R li code under the comment labelled “F. Output result navigation links”:
icthe following
berto ...
Ro <!-- F. Output result navigation links -->
<a href="results.jsp?numRows=${numRows}&pageNumber=
${pageNumber-1}">Prev</a>&nbsp;
<a href="results.jsp?numRows=${numRows}&pageNumber=
${pageNumber+1}">Next</a>
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 31
11. Save your work and launch the index.jsp page in the Firefox browser by visiting the
following URL: http://localhost:8080/java/activity6-5/index.jsp. Navigate through the results
by clicking the “Prev” and “Next” links and verify that the query results display ten rows at a
time.
The page displays the following:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
Ric
toLeave the Linux terminal window and Firefox browser open for the next practice.
e r
12.

R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 32
Practice 6-6: Paging Query Results Using Python
Overview
In this practice, you execute a query that returns over 200 rows, and enable users to view the
results ten rows at a time.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a terminal window open and are logged in as the Linux root user.
• You have the Firefox web browser open from the previous practice.

Duration
This practice should take you approximately 30 minutes to complete.

Tasks ble
1. In a Linux terminal window, list the contents of the /labs/python/web/activity6-6 directory. fe r a
2. Copy the results_start.py file to create a new file called results.py.
t r a ns
3. Examine the index.py file. What is the purpose of this program? o n -
4. Open results.py in a text editor. This file contains the beginnings
n
ofaa script that displays
s
Country table data in a tabular format on the page ten rows athaatime. Users can navigate
different “pages” of data by using the “Prev” and “Next” links. ฺ b r)The following
d e ฺ steps tell you
how to complete the script, using the comments as o amguide. u i
5. Under the comment labelled “A. Get total number r ฺ c
a ofdrows”, t G
n use the cgi.FieldStorage()
e p e
method to retrieve the URL query parameters
s n its value
ostore and
S tuin a variable
store them in a variable called params.
Inspect the numrows parameter and
i @ h i s called numrows.
t which page of results to display”, use the
6. Under the comment labelled
ฺ r i cc“B.toDetermine
s e
params.has_key()
e r t o to u
function determine if the pagenum query parameter is present in
the URL used to
r o b $pagenum.
access the
s e page. If it is present, store the parameter value as an integer in
a variable (called
i set $pagenum
cso n
ce to 1.
If it is not present, the page will display the first page of query
i c
results,
R l i
7.toUnder the comment labelled “C. Page number of the last page”, calculate the number of
be r pages of results based on the number of rows in the Country table (numrows) and the
Ro number of rows per page (pagerows). Store the page number of the last page in a variable
called lastpage.
Note: Convert the value of pagerows to a floating point value before performing the
calculation by using the float() method.
8. Under the comment labelled “D. Ensure that current page is within a valid range”, test the
value of pagenum and adjust it, if necessary, so that it is neither less than one nor greater
than the value of lastpage.
9. Under the comment labelled “E. Set the LIMIT clause for the query”, create a string variable
called sqllimit that uses the values of the pagenum and the pagerows variables to
create a SQL LIMIT clause in the following format:
LIMIT <offset>, <number of rows>
10. Under the comment labelled “F. Output result navigation links”, create the anchor tags for
the “Prev” and “Next” links. Set the links’ href attributes to the results.py page, with
suitable values for the pagenum query parameter depending on which direction the user is
navigating through the query results. Also set the numrows query parameter that specifies
the total number of rows in the result set.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 33
11. Save your work.
12. Ensure that the all the scripts in the /labs/python/web/activity6-6 directory are
executable.
13. Launch the index.py page in the Firefox browser by visiting the following URL:
http://localhost/cgi-bin/activity6-6/index.py.
14. Click the “Display results” link and examine the URL to ensure that the number of rows in
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

the Country table is passed as a query parameter.


15. Navigate through the results by clicking the “Prev” and “Next” links and verify that the query
results display ten rows at a time.
16. Leave the Linux terminal window and Firefox browser open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 34
Solution 6-6: Paging Query Results Using Python
Solution Steps
1. In a Linux terminal window, list the contents of the /labs/python/web/activity6-6
directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/python/web/activity6-6
# ls
conn.py index.py layout.py results_soln.py results_start.py
2. Copy the results_start.py file to create a new file called results.py.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp results_start.py results.py
# ls
ble
conn.py layout.py results.py results_start.py
fe r a
index.py results_soln.py
ans
3. Examine the index.py file. What is the purpose of this program?
n - t r
o
an
Enter the following command at the Linux terminal prompt and receive the results shown:
# cat index.py s
ha ฺ
#!/usr/bin/python
r )
ฺb uide
m
ฺco nt G
import conn
import sys
a r
o n ep tude
s is S
print('''Content-Type: text/html
@
c c i th
<html>
r i us e
e r toฺ to 6-6</title></head>
<head><title>Activity

''') rob
<body>

i ( e n se
cc lic
Riprint("<h1>Activity 6-6 (Python)</h1>")

e r to
R ob # Connect to the database
dbconn = conn.dbconnect()

sql = '''
SELECT COUNT(*) FROM Country
'''

# B. Execute the query


cursor = dbconn.cursor()
cursor.execute(sql)
row = cursor.fetchone()

print("<a href='results.py?numrows=%s'>Display results</a>" % row[0])

print('''
</body>
</html>
''')

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 35
− Answer: The index.py program queries the Country table in the world
database to retrieve a count of the number of rows. It displays a link to the
results.py page, passing the number of rows as a query parameter.
4. Open results.py in a text editor. This file contains the beginnings of a script that displays
Country table data in a tabular format on the page ten rows at a time. Users can navigate
different “pages” of data by using the “Prev” and “Next” links. The following steps tell you
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

how to complete the script, using the comments as a guide.


The contents of the results.py script are as follows:
#!/usr/bin/python

import conn
import sys
import math
reload(sys) # Reload does the trick!
import cgi
ble
from layout import *
fe r a
ans
print('''Content-Type: text/html
n - t r
o
<html>
s an
ha ฺ
<head><title>Activity 6-6 (Python)</title></head>
<body>
''') r )
ฺb uide
m
a r
print("<h1>Activity 6-6 (Python)</h1>") ฺco nt G
# Set the default encodingon
ep tude
@ s is S
i
sys.setdefaultencoding('UTF8')
c c th
r i e
e r t ฺ to ofusrows
# A. Get totalonumber

#c i rob enwhich
(Determine se page of results to display
Ric
B.
lic
e r to
R ob # Number of rows per page
pagerows = 10

# C. Page number of the last page

# D. Ensure that current page is within a valid range

# E. Set the LIMIT clause for the query

# Connect to the database


dbconn = conn.dbconnect()

sql = "SELECT Code, Name, Continent, Population FROM Country " +


sqllimit
print("<p>" + sql + "</p>")

# Execute the query


cursor = dbconn.cursor(buffered=True)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 36
cursor.execute(sql)

# Output query results


print(show_in_table(cursor))
cursor.close()

# F. Output result navigation links


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

print('''
</body>
</html>
''')
5. Under the comment labelled “A. Get total number of rows”, use the cgi.FieldStorage()
method to retrieve the URL query parameters and store them in a variable called params.
Inspect the numrows parameter and store its value in a variable called numrows.
ble
Enter the following code under the comment labelled “A. Get total number of rows”: fe r a
ans
...
# A. Get total number of rows n - t r
params = cgi.FieldStorage()
a no
numrows = int(params['numrows'].value)
h a s
r) ddisplay”,
...
6. Under the comment labelled “B. Determine which page of ฺ b
results ito e ฺ use the
params.has_key() function to determine if theฺc
r om t query
pagenum G u parameter is present in
the URL used to access the page. If it is present,
e p a store
d e n parameter value as an integer in
the
a variable called $pagenum. If it is not n
s o present,S tupage will display the first page of query
the
results, so set $pagenum to 1.
c i@ t s
hi labelled “B. Determine which page of results to
i
Enter the following code under
ฺr c e
the comment
display”: r t o t o us
e
...
i ( rob enwhich se page of results to display
ccparams.has_key('pagenum'):
lic
# B. Determine
R iif
e r to else: pagenum = int(params['pagenum'].value)

R ob pagenum = 1
...
7. Under the comment labelled “C. Page number of the last page”, calculate the number of
pages of results based on the number of rows in the Country table (numrows) and the
number of rows per page (pagerows). Store the page number of the last page in a variable
called lastpage.
Note: Convert the value of pagerows to a floating point value before performing the
calculation by using the float() method.
Enter the following code under the comment labelled “C. Page number of the last page”:
...
# C. Page number of the last page
lastpage = int(math.ceil(numrows/float(pagerows)))
...
8. Under the comment labelled “D. Ensure that current page is within a valid range”, test the
value of pagenum and adjust it, if necessary, so that it is neither less than one nor greater
than the value of lastpage.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 37
Enter the following code under the comment labelled “D. Ensure that current page is within
a valid range”:
...
# D. Ensure that current page is within a valid range
if pagenum < 1:
pagenum = 1
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

elif pagenum > lastpage:


pagenum = lastpage
...
9. Under the comment labelled “E. Set the LIMIT clause for the query”, create a string variable
called sqllimit that uses the values of the pagenum and the pagerows variables to
create a SQL LIMIT clause in the following format:
LIMIT <offset>, <number of rows>
Enter the following code under the comment labelled “E. Set the LIMIT clause for the
ble
query”:
fe r a
...
ans
# E. Set the LIMIT clause for the query
n - t r
no
sqllimit = "LIMIT " + str((pagenum-1) * pagerows) + "," +
str(pagerows)
s a
...
h a
10. Under the comment labelled “F. Output result navigation links”,
ฺ b r) create
d e ฺthe anchor tags for
the “Prev” and “Next” links. Set the links’ href attributes
o to the i
m Gonuwhich directionpage,
results.py with
suitable values for the pagenum query parameter
a r ฺ c t
depending
n the user is
navigating through the query results. Also set
the total number of rows in the resulto n
set.
ep tude
the numrows query parameter that specifies
S
s islabelled
Enter the following code underi@ h
the comment
t “F. Output result navigation links”:
i c c e
...
r t o ฺr us links
# F. Output e result t o
navigation
( robhref='results.py?pagenum=%d&numrows=%d'>Prev</a>"
print("<a
i e n se %

R cc
iprint("<a c
lihref='results.py?pagenum=%d&numrows=%d'>Next</a>"
((pagenum-1), numrows))
%

ert o ((pagenum+1), numrows))


b ...
Ro 11. Save your work.
12. Ensure that all the scripts in the /labs/python/web/activity6-6 directory are
executable.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# chmod +x *
# ls -al
total 36
drwxr-xr-x 2 root root 4096 Aug 26 12:08 .
drwxr-xr-x. 9 root root 4096 Aug 17 09:47 ..
-rwxr-xr-x 1 root root 820 Aug 21 08:44 conn.py
-rwxr-xr-x 1 root root 473 Aug 21 16:44 index.py
-rwxr-xr-x 1 root root 853 Aug 21 08:14 layout.py
-rwxr-xr-x 1 root root 1011 Aug 26 12:08 results.py
-rwxr-xr-x 1 root root 1534 Aug 21 17:11 results_soln.py
-rwxr-xr-x 1 root root 1011 Aug 21 17:12 results_start.py

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 38
13. Launch the index.py page in the Firefox browser by visiting the following URL:
http://localhost/cgi-bin/activity6-6/index.py.
The page displays the following:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
14. Click the “Display results” link and examine the URL to ensure that the number of rows in
ans
the Country table is passed as a query parameter.
n - t r
o
The page displays the following:
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

15. Navigate through the results by clicking the “Prev” and “Next” links and verify that the query
results display ten rows at a time.
16. Leave the Linux terminal window and Firefox browser open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 39
Practice 6-7: Enabling Sorting of Query Results Using PHP/PDO
Overview
In this practice, you make the column headings of the HTML table clickable so that users can
order query results.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a terminal window open and are logged in as the Linux root user.
• You have the Firefox web browser open from the previous practice.

Duration
This practice should take you approximately 20 minutes to complete.

Tasks ble
1. In a Linux terminal window, list the contents of the /labs/php/web/activity6-7 fe r a
directory. ans
2. Copy the index_start.php file to create a new file called index.php. n - t r
o
3. an
Open index.php in a text editor. This file contains the beginnings of a script that displays
s
script, using the comments as a guide. r ) ha ฺ
the results of a query in tabular format. The following steps tell you how to complete the

m ฺb uide
4.
r ฺco nt G
Under the comment labelled “A. Get column to order by”, use the PHP isset() method to
check if the orderby query parameter is present in the page request URL. If orderby is
a
o n ep tude
present, use the value to create a string variable called $orderby that contains a SQL
s is S
LIMIT clause using the value of the orderby query parameter as the name of the column
@
c i th
to order by. If not, set $orderby to be an empty string.
c
r i e
5.
e r toฺ to us
Under the comment labelled “B. Execute the query”, create a string variable called $sql
that queries the Country table of the world database and returns the Code, Name,
( rob ense
Continent, and Population columns of the first 15 rows, applying any column ordering
i
c lic
Ric
specified in the orderby query parameter.

e
6.
r to Under the comment labelled “C. Create table headers as hyperlinks”, and within the
foreach loop that examines each of the columns in the first row of the result set, create
R ob hyperlinked column headers for the table using <th></th> and <a href=""> tags. The
href attribute for each hyperlinked column must reload the existing page with an orderby
query parameter that specifies the name of the column to sort results by.
7. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost/php/activity6-7/index.php.
8. Click on each of the columns in turn and verify that the results are ordered by the column
you clicked.
9. Close the Linux terminal window and Firefox web browser.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 40
Solution 6-7: Enabling Sorting of Query Results Using PHP/PDO
Solution Steps
1. In a Linux terminal window, list the contents of the /labs/php/web/activity6-7
directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/php/web/activity6-7
# ls
conn.php index_soln.php index_start.php
2. Copy the index_start.php file to create a new file called index.php.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp index_start.php index.php
# ls
ble
conn.php index.php index_soln.php index_start.php
fe r a
3. Open index.php in a text editor. This file contains the beginnings of a script that displays
ans
the results of a query in tabular format. The following steps tell you how to complete the
n - t r
script, using the comments as a guide. o
The contents of the index.php file are as follows: s an
<!doctype html>
r ) ha ฺ
<html>
m ฺb uide
<title>Activity 6-7 (PHP)</title> rฺc
<head> o tG
e p a d e n
</head>
<body>
s o n Stu
i
<h1>Activity 6-7 (PHP)</h1>
c @ this
t o ฺ ric use
<?php
b e r to
require_once ns e
(ro ce"conn.php";
c i
c A. Getlicolumn to order by
to Ri//
e r
R ob // B. Execute the query

echo "<p>" . $sql . "</p>";

$sth = $dbh->query ($sql);


$items = $sth->fetchAll (PDO::FETCH_ASSOC);

// Output query results


$result = "";

// Get table headers from the result set


$fields = current($items);

$result = "<table border='1'>\n<tr>\n";

foreach ($fields as $key => $value) {


// C. Create table headers as hyperlinks

}
$result .= "</tr>\n";

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 41
// Retrieve each row from the resultset
foreach ($items as $row) {
// Generate output for new row
$result .= "<tr>\n";
foreach ($row as $val) {
// Get each column value from the row
$val_html = htmlentities($val);
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

$result .= "<td>$val_html</td>\n";
}
}
// Close tag for current row
$result .= "</tr>\n";
// Close table tag
$result .= "</table>\n";

print $result;
ble
?>
fe r a
4. Under the comment labelled “A. Get column to order by”, use the PHP isset() method to ans
check if the orderby query parameter is present in the page request URL. If orderby is n - t r
no
present, use the value to create a string variable called $orderby that contains a SQL
a
h a s
LIMIT clause using the value of the orderby query parameter as the name of the column
to order by. If not, set $orderby to be an empty string.
ฺ b r) deฺ
c o m Gui
Enter the following code under the comment labelled “A. Get column to order by”:
...
// A. Get column to order by ep
arฺ dent
if (isset($_GET['orderby']))
s { tu
o. n$_GET['orderby'];
S
$orderby = " ORDER BY
c i@ thi
" s
} else {
ฺ r i c se
r t
$orderby = ""; o to u
}
b e e
...
c i (ro cens
5. Under li labelled “B. Execute the query”, create a string variable called $sql
Ric the comment
e r toContinent, and Population columns of the first 15 rows, applying any column ordering
that queries the Country table of the world database and returns the Code, Name,

R ob specified in the orderby query parameter.


Enter the following code under the comment labelled “B. Execute the query”:
...
// B . Execute the query
$sql = "SELECT Code, Name, Continent, Population FROM Country " .
$orderby . " LIMIT 15";
echo "<p>" . $sql . "</p>";

$sth = $dbh->query ($sql);


$items = $sth->fetchAll (PDO::FETCH_ASSOC);
...
6. Under the comment labelled “C. Create table headers as hyperlinks” and within the
foreach loop that examines each of the columns in the first row of the result set, create
hyperlinked column headers for the table using the <th></th> and <a href=""> tags.
The href attribute for each hyperlinked column must reload the existing page with an
orderby query parameter that specifies the name of the column to sort results by.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 42
Enter the following code under the comment labelled “C. Create table headers as
hyperlinks”:
...
foreach ($fields as $key => $value) {
// C. Create table headers as hyperlinks
$result .= "<th><a href='?orderby=" . $key . "'>" . $key .
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

"</th></a>";
}
...
7. Save your work and launch the index.php page in the Firefox browser by visiting the
following URL: http://localhost/php/activity6-7/index.php.
The page displays as follows:

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 43
8. Click on each of the columns in turn and verify that the results are ordered by the column
you clicked.
For example, the following page displays when you click on the Population column:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 44
Practice 6-8: Enabling Sorting of Query Results Using Java/JSP
Overview
In this practice, you make the column headings of the HTML table clickable so that users can
order query results.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a terminal window open and are logged in as the Linux root user.
• You have the Firefox web browser open from the previous practice.

Duration
This practice should take you approximately 20 minutes to complete.

Tasks ble
1. In a Linux terminal window, list the contents of the /labs/java/web/activity6-8 fe r a
directory. ans
2. Copy the index_start.jsp file to create a new file called index.jsp n - t r
o
3. an
Open index.jsp in a text editor. This file contains the beginnings of a page that displays
s
page, using the comments as a guide. r ) ha ฺ
the results of a query in tabular format. The following steps tell you how to complete the

m ฺb uide
4.
r ฺco nt G
Under the comment labelled “A. Get column to order by”, use the built-in param object to
check if the orderby query parameter is present in the page request URL. If orderby is
a
o n ep tude
present, use the value to create a string variable called orderby that contains a SQL
s is S
LIMIT clause using the value of the orderby query parameter as the name of the column
@
c i th
to order by. If not, set orderby to be an empty string.
c
r i e
5.
e r toฺ to us
Under the comment labelled “B. Execute the query”, create a string variable called query
that queries the Country table of the world database and returns the Code, Name,
( rob ense
Continent, and Population columns of the first 15 rows, applying any column ordering
i
c lic
Ric
specified in the orderby query parameter.

e
6.
r to Under the comment labelled “C. Create table headers as hyperlinks” and within the
<c:forEach> loop that examines each of the columns in the first row of the result set,
R ob create hyperlinked column headers for the table using <th></th> and <a href="">
tags. The href attribute for each hyperlinked column must reload the existing page with an
orderby query parameter that specifies the name of the column to sort results by.
7. Save your work and launch the index.jsp page in the Firefox browser by visiting the
following URL: http://localhost:8080/activity6-8/index.jsp.
8. Click on each of the columns in turn and verify that the results are ordered by the column
you clicked.
9. Close the Linux terminal window and Firefox web browser.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 45
Solution 6-8: Enabling Sorting of Query Results Using Java/JSP
Solution Steps

Tasks
1. In a Linux terminal window, list the contents of the /labs/java/web/activity6-8
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cd /labs/java/web/activity6-8
# ls
index_soln.jsp index_start.jsp WEB-INF
2. Copy the index_start.jsp file to create a new file called index.jsp
Enter the following commands at the Linux terminal prompt and receive the results shown:
ble
# cp index_start.jsp index.jsp
fe r a
# ls
ans
index.jsp index_soln.jsp index_start.jsp WEB-INF
n - t r
3.
no
Open index.jsp in a text editor. This file contains the beginnings of a page that displays
a
the results of a query in tabular format. The following steps tell you how to complete the
page, using the comments as a guide. h a s
ฺ b
The contents of the index.jsp page are as follows:r) deฺ
c o m Gui prefix="c" %>
p rฺ ent
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"
a
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
e
on s Stu%> d
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
s
<%@ include file="/WEB-INF/conn.inc"

<!DOCTYPE html> ric


ci@ e thi
<html>
e r t oฺ to us
<head>b
i ( ro ense 6-8 (Java)</title>
<title>Activity
c </head>
lic
to Ric <body>
e r <h1>Activity 6-8 (Java)</h1>

R ob <c:choose>
<c:when test="${not empty connexception}">
<p>Error connecting to the database</p>
</c:when>
<c:otherwise>
<p>Connected to the database</p>
</c:otherwise>
</c:choose>

<!-- A. Get column to order by -->

<!-- B. Execute the query -->

<!-- Output query results -->


<table border="1">
<tr>
<%-- Get column names for header row --%>
<c:forEach items="${rs.columnNames}" var="columnName">

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 46
<!-- C. Create table headers as hyperlinks -->

</c:forEach>
</tr>
<%-- Iterate through each row --%>
<c:forEach items="${rs.rowsByIndex}" var="row">
<%-- Create a row in the HTML table for each row in the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

resultset --%>
<tr>
<%-- Create a column in the HTML table for each column in
the result row --%>
<c:forEach items="${row}" var="column">
<td><c:out value="${column}"/></td>
</c:forEach>
</tr>
</c:forEach>
</table> ble
fe r a
</body>
an s
</html>
n - t r
4. no
Under the comment labelled “A. Get column to order by”, use the built-in param object to
a
h a s
check if the orderby query parameter is present in the page request URL. If orderby is
present, use the value to create a string variable called orderby that contains a SQL
ฺ b r) deฺ
LIMIT clause using the value of the orderby query parameter as the name of the column
o m Gui
to order by. If not, set orderby to be an empty string.
c
a rฺ ent
Enter the following code under the comment labelled “A. Get column to order by”:
p
...
s o ne Stud
<!-- A. Get column@ to orderis
c i t h by -->
<c:choose>
<c:when o
t ฺ ric useempty param.orderby}" >
test="${not
b e
<c:setr var="orderby"
to value=" ORDER BY ${param.orderby}" />
r o n s e
i ( <c:otherwise>
</c:when>
c c l i c e
to Ri <c:set var="orderby" value="" />

e r </c:otherwise>

R ob ...
</c:choose>

5. Under the comment labelled “B. Execute the query”, create a string variable called query
that queries the Country table of the world database and returns the Code, Name,
Continent, and Population columns of the first 15 rows, applying any column ordering
specified in the orderby query parameter.
Enter the following code under the comment labelled “B. Execute the query”:
...
<!-- B. Execute the query -->
<c:set var="query" value="SELECT Code, Name, Continent,
Population FROM Country ${orderby} LIMIT 15" />
<sql:query dataSource="${conn}" var="rs">
${query}
</sql:query>
<c:out value="${query}" /><br />
...
6. Under the comment labelled “C. Create table headers as hyperlinks” and within the
<c:forEach> loop that examines each of the columns in the first row of the result set,

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 47
create hyperlinked column headers for the table using the <th></th> and <a href="">
tags. The href attribute for each hyperlinked column must reload the existing page with an
orderby query parameter that specifies the name of the column to sort results by.
Enter the following code under the comment labelled “C. Create table headers as
hyperlinks”:
...
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<%-- Get column names for header row --%>


<c:forEach items="${rs.columnNames}" var="columnName">
<!-- C. Create table headers as hyperlinks -->
<th><a href="?orderby=${columnName}"><c:out
value="${columnName}" /></a></th>
</c:forEach>
...
7. Save your work and launch the index.jsp page in the Firefox browser by visiting the
following URL: http://localhost:8080/activity6-8/index.jsp.
ble
The page displays as follows: fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 48
8. Click on each of the columns in turn and verify that the results are ordered by the column
you clicked.
For example, the following page displays when you click on the Population column:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob
9. Close the Linux terminal window and Firefox web browser.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 49
Practice 6-9: Enabling Sorting of Query Results Using Python
Overview
In this practice, you make the column headings of the HTML table clickable so that users can
order query results.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a terminal window open and are logged in as the Linux root user.
• You have the Firefox web browser open from the previous practice.

Duration
This practice should take you approximately 20 minutes to complete.

Tasks ble
1. In a Linux terminal window, list the contents of the /labs/python/web/activity6-9fe r a
directory.
t r a ns
2. Copy the index_start.py file to create a new file called index.py.
o n -
3. Open index.py in a text editor. This file contains the beginnings of aa n that displays
page
the results of a query in tabular format. The following steps tell h you s
a how to complete the
page, using the comments as a guide.
ฺ b r ) e ฺ
4. Under the comment labelled “A. Get column to order om by”, use the i d
u cgi.FieldStorage()
method to retrieve the URL query parametersaand r ฺcstore n t
them G in a variable called params.
Use the params.has_key object to check
n p
e tud
if the e
orderby query parameter is present in
o
the page request URL. If orderbysis present, S
s use the value to create a string variable
i @ h i
t order by. If using
called orderby that contains
parameter as the nameฺof r i cthec column
a SQL
s
LIMIT
eto
clause
not,
the value of the orderby query
set orderby to be an empty
string. r t o t o u
r o be labelleds e
5. Under the (comment
c i c e ntable of“B.theExecute the query”, create a string variable called sql that

R ic
queries the li
Country world database and returns the Code, Name,
and Population columns of the first 15 rows, applying any column ordering
ertospecified in the orderby query parameter.
Continent,
b
Ro 6. Under the comment labelled “C. Create table headers as hyperlinks” and within the for
loop that examines each of the columns in the first row of the result set, create hyperlinked
column headers for the table using the <th></th> and <a href=""> tags. The href
attribute for each hyperlinked column must reload the existing page with an orderby query
parameter that specifies the name of the column to sort results by.
7. Save your work.
8. Make the files in the /labs/python/web/activity6-9 directory executable.
9. Open the index.jsp page in the Firefox browser by visiting the following URL:
http://localhost/cgi-bin/activity6-9/index.py.
10. Click on each of the columns in turn and verify that the results are ordered by the column
you clicked.
11. Close the Linux terminal window and Firefox web browser.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 50
Solution 6-9: Enabling Sorting of Query Results Using Python
Solution Steps
1. In a Linux terminal window, list the contents of the /labs/python/web/activity6-9
directory.
Enter the following commands at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# cd /labs/python/web/activity6-9
# ls
conn.py index_soln.py index_start.py results.py
2. Copy the index_start.py file to create a new file called index.py.
Enter the following commands at the Linux terminal prompt and receive the results shown:
# cp index_start.py index.py
# ls
ble
conn.py index.py index_soln.py index_start.py results.py
fe r a
3. Open index.py in a text editor. This file contains the beginnings of a page that displays
ans
the results of a query in tabular format. The following steps tell you how to complete the
n - t r
page, using the comments as a guide. o
The contents of the index.py file are as follows: s an
#!/usr/bin/python
r ) ha ฺ
m ฺb uide
import conn
import sys
a r ฺco nt G
import math
reload(sys) # Reload doesothe n ep t u de
@ s is S trick!
import cgi
c c i th
r i s e
r toฺ to utext/html
print('''Content-Type:
e
<html>
i ( r ob nse
i c c l i c e
<head><title>Activity 6-9 (Python)</title></head>

to R <body>
e r ''')

R ob print("<h1>Activity 6-9 (Python)</h1>")

# set default encoding


sys.setdefaultencoding('UTF8')

# A. Get column to order by

# B. Execute the query

dbconn = conn.dbconnect()
cursor = dbconn.cursor(buffered=True)
cursor.execute(sql)

print("<p>" + sql + "</p>")

def show_in_table(cursor):
# Get column names
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 51
colnames = cursor.column_names

results = ""
results += "<table border=1>"

# Create header row for table from column names


results += "<tr>"
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

for i in range(len(colnames)):
# C. Create table headers as hyperlinks

results += "</tr>"

# Loop through the rows in the resultset


for j in range(cursor.rowcount):
row = cursor.fetchone()

# Create a new row in the HTML table for each row in the resultset ble
results += "<tr>"
fe r a
count = 0
ans
# Populate the HTML table columns with the column values in the
n - t r
resultset o
for k in range(len(row)):
s an
col = row[count]
results += "<td>" + str(col) + "</td>"
r ) ha ฺ
count += 1
m ฺb uide
results += "</tr>"
a r ฺco nt G
results += "</table>"
o n ep tude
return results
@ s is S
c c i th
r i e
toฺ to us
# Output query results
r
print(show_in_table(cursor))
e
ob nse
cursor.close()
i ( r e
i c c
print('''
l i c
to R </body>
e r </html>

R ob ''')
4. Under the comment labelled “A. Get column to order by”, use the cgi.FieldStorage()
method to retrieve the URL query parameters and store them in a variable called params.
Use the params.has_key object to check if the orderby query parameter is present in
the page request URL. If orderby is present, use the value to create a string variable
called orderby that contains a SQL LIMIT clause using the value of the orderby query
parameter as the name of the column to order by. If not, set orderby to be an empty
string.
Enter the following code under the comment labelled “A. Get column to order by”:
...
# A. Get column to order by
params = cgi.FieldStorage()
if params.has_key('orderby'):
orderby = " ORDER BY " + params['orderby'].value
else:
orderby= ""
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 52
5. Under the comment labelled “B. Execute the query”, create a string variable called sql that
queries the Country table of the world database and returns the Code, Name,
Continent, and Population columns of the first 15 rows, applying any column ordering
specified in the orderby query parameter.
Enter the following code under the comment labelled “B. Execute the query”:
...
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# B. Execute the query


sql = "SELECT Code, Name, Continent, Population FROM Country " +
orderby + " LIMIT 15"
dbconn = conn.dbconnect()
cursor = dbconn.cursor(buffered=True)
cursor.execute(sql)

print("<p>" + sql + "</p>")


...
ble
6. Under the comment labelled “C. Create table headers as hyperlinks” and within the for
fe r a
loop that examines each of the columns in the first row of the result set, create hyperlinked
ans
column headers for the table using <th></th> and <a href=""> tags. The href
n - t r
parameter that specifies the name of the column to sort results by.a no
attribute for each hyperlinked column must reload the existing page with an orderby query

h a s
Enter the following code under the comment labelled “C. Create table headers as
hyperlinks”:
ฺ b r) deฺ
c o m Gui
rฺ column
...
# Create header row for table from
p a e n tnames
one s Stud
results += "<tr>"
for i in range(len(colnames)): s
# C. Create tablei@
i c c t hi hyperlinks
headers as
e
t o ฺ r
results += "<th><a
s colnames[i] ++ colnames[i]
href='?orderby="
u
+ "'>" +

+=r "</tr>"to
"</th>"
resultsbe
... (ro
i e n se
7. Save
c work.lic
icyour
R
be8.rtoMake the files in the /labs/python/web/activity6-9 directory executable.
Ro Enter the following commands at the Linux terminal prompt and receive the results shown:
# chmod +x *
# ls -al
...
drwxr-xr-x 2 root root 4096 Aug 26 16:39 .
drwxr-xr-x. 9 root root 4096 Aug 17 09:47 ..
-rwxr-xr-x 1 root root 820 Aug 21 17:12 conn.py
-rwxr-xr-x 1 root root 1448 Aug 26 16:39 index.py
-rwxr-xr-x 1 root root 1742 Aug 21 17:26 index_soln.py
-rwxr-xr-x 1 root root 1448 Aug 21 17:27 index_start.py
-rwxr-xr-x 1 root root 1761 Aug 21 17:24 results.py

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 53
9. Open the index.jsp page in the Firefox browser by visiting the following URL:
http://localhost/cgi-bin/activity6-9/index.py.
The page displays as follows:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 54
10. Click on each of the columns in turn and verify that the results are ordered by the column
you clicked.
For example, the following page displays when you click on the Population column:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

11. Close the Linux terminal window and Firefox web browser.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 55
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 6: Building Database-Driven Web Applications


Chapter 6 - Page 56
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 7:
Tables om
and G i
Views
u
r ฺ c
a 7 den t
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 1
Practices for Lesson 7: Tables and Views
Practices Overview
These practices test your knowledge of working with tables and views. They assume that you
are using the Linux operating system environment provided in Oracle classrooms. For non-
Oracle classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have a Linux terminal window open and are logged in as the Linux root user
(password: oracle).
• You have a mysql command-line session open and are logged in as the MySQL root
user (password: oracle).

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 2
Practice 7-1: Creating New Tables from Existing Tables
Overview
In this practice, you create new tables from existing tables by using the CREATE TABLE
statement.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 10 minutes to complete.

Tasks
1. Log into the mysql command-line client and change the current database to world.
2. Use the CREATE TABLE…AS syntax to create a new table called CitySelect based on a
query of all rows and columns in the City table.
ble
3. Compare the number of rows in the original City table and the new CitySelect table. Is
fe r a
there a difference?
ans
4. Compare the definition of the original City table to the definition of the new CitySelect
n - t r
table. Are there any differences between these table definitions? o
5. an
Create a new table called CityLike by issuing a CREATE TABLE…LIKE statement.
s
6. ) ha ฺ
Compare the number of rows in the original City table and the new CityLike table. Is
r
there a difference?
m ฺb uide
7. ฺco nt G
Compare the definition of the original City table to the definition of the new CityLike
a r
8. o ep tude
table. Are there any differences between these table definitions?
n
Leave the mysql command-line client open for the next practice.
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 3
Solution 7-1: Creating New Tables from Existing Tables
Solution Steps
1. Log into the mysql command-line client and change the current database to world.
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> USE world
Reading table information
...
Database changed
bl e
2. Use the CREATE TABLE…AS syntax to create a new table called CitySelect based on a
fe r a
query of all rows and columns in the City table. n s
n -
Enter the following statement at the mysql prompt and receive the results shown: tra
mysql> CREATE TABLE CitySelect a no
-> AS SELECT * FROM City;
h a s
Query OK, 4079 rows affected (#.## sec)
Records: 4079 Duplicates: 0 Warnings: 0 ฺb
r) deฺ
c o m Gui
3. Compare the number of rows in the original City
a r ฺ table t
and
n the new CitySelect table. Is
there a difference?
o n ep tude
S and receive the results shown:
s mysqlisprompt
Enter the following statements at the
i @ h
mysql> SELECT COUNT(*)
ฺ r i cc se t
FROM City;
+----------+
| COUNT(*)e|rt
o to u
rob
| i ( 4079 |en
+----------+ se
R cc lic
i+----------+
berto mysql> SELECT COUNT(*) FROM CitySelect;
Ro +----------+
| COUNT(*) |
+----------+
| 4079 |
+----------+
− Answer: The number of rows in both tables is identical.
4. Compare the definition of the original City table to the definition of the new CitySelect
table. Are there any differences between these table definitions?
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SHOW CREATE TABLE City\G
*************************** 1. row ***************************
Table: City
Create Table: CREATE TABLE `City` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0',

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 4
PRIMARY KEY (`ID`),
KEY `CountryCode` (`CountryCode`),
CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES
`country` (`Code`)
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1
1 row in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SHOW CREATE TABLE CitySelect\G


*************************** 1. row ***************************
Table: CitySelect
Create Table: CREATE TABLE `CitySelect` (
`ID` int(11) NOT NULL DEFAULT '0',
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ble
1 row in set (#.## sec)
fe r a
− Answer: The primary key, constraint and foreign key, and autoincrement
ans
designation are not included in the new CitySelect table. Depending on the n - t r
no
locale defaults and the script used to create the world database, the defaults for
a
h a s
character set, collation, and storage engine can also differ.
5. r) deฺ
Create a new table called CityLike by issuing a CREATE TABLE…LIKE statement.
ฺ b
c o m Gui
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE TABLE CityLike LIKEaCity;
p rฺ ent
Query OK, 0 rows affected (#.##
s o ne sec) S tud
6. Compare the number of rows in@ the originalis
City table and the new CityLike table. Is
c i t h
there a difference?
t o ฺric at the
Enter the following rstatement u e
smysql prompt and receive the results shown:
e
b COUNT(*) t o
mysql>ro
i ( SELECT
e n se FROM CityLike;
i|ccCOUNT(*)lic|
+----------+
R
erto
+----------+
b | 0 |
Ro +----------+
− Answer: The City table has 4,079 rows, but CityLike is empty.
7. Compare the definition of the original City table to the definition of the new CityLike
table. Are there any differences between these table definitions?
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW CREATE TABLE CityLike\G
*************************** 1. row ***************************
Table: CityLike
Create Table: CREATE TABLE ` CityLike` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `CountryCode` (`CountryCode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (#.## sec)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 5
− Answer: The foreign key constraint and AUTO_INCREMENT designation are not
included in the new CityLike table.
8. Leave the mysql command-line client open for the next practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 6
Practice 7-2: Creating a View
Overview
In this practice, you use the CREATE VIEW statement to create views.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately five minutes to complete.

Tasks
1. In the sakila database, create a new view called short_films with the film_id,
title, and language_id columns from the film table for all films of 60 minutes or less
duration.
2. Execute the SHOW TABLES command to verify the addition of the short_films view.
ble
3. Execute a query that displays the contents of the new view.
fe r a
4. Leave the mysql command-line client open for the next practice.
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 7
Solution 7-2: Creating a View
Solution Steps
1. In the sakila database, create a new view called short_films with the film_id,
title, and language_id columns from the film table for all films of 60 minutes or less
duration.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statements at the mysql prompt and receive the results shown:
mysql> USE sakila
Reading table information
...
Database changed

mysql> CREATE VIEW short_films AS


-> SELECT film_id, title, language_id
ble
-> FROM film WHERE length <= 60;
Query OK, 0 rows affected (#.## sec) fe r a
ans
2. Execute the SHOW TABLES command to verify the addition of the short_films view.
n - t r
Enter the following statement at the mysql prompt and receive the results shown: o
s an
ha ฺ
mysql> SHOW TABLES;
+----------------------------+
| Tables_in_sakila | r )
ฺb uide
m
ฺco nt G
+----------------------------+
| actor |
a r
| actor_info
o n e tude
| p
| address
@ s is S
|
...
c c i t|h
| short_films
r i e
| staff
e r toฺ to us ||
rob ense
| staff_list

i (
| store |
ccrows inlicset (#.## sec)
+----------------------------+
Ri27
e r to − The view short_films appears in the list of tables.
R ob 3. Execute a query that displays the contents of the new view.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM short_films;
+---------+-----------------------+-------------+
| film_id | title | language_id |
+---------+-----------------------+-------------+
| 2 | ACE GOLDFINGER | 1 |
| 3 | ADAPTATION HOLES | 1 |
| 8 | AIRPORT POLLOCK | 1 |
| 15 | ALIEN CENTER | 1 |
| 18 | ALTER VICTORY | 1 |
| 66 | BENEATH RUSH | 1 |
| 83 | BLUES INSTINCT | 1 |
| 97 | BRIDE INTRIGUE | 1 |
| 102 | BUBBLE GROSSE | 1 |
| 110 | CABIN FLASH | 1 |
...
| 972 | WHISPERER GIANT | 1 |
| 981 | WOLVES DESIRE | 1 |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 8
| 1000 | ZORRO ARK | 1 |
+---------+-----------------------+--------------+
104 rows in set (#.## sec)
4. Leave the mysql command-line client open for the next practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 9
Practice 7-3: Updating a View
Overview
In this practice, you modify the contents of an updatable view.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately five minutes to complete.

Tasks
1. In the short_films view, change the name of the film with an ID of 102 to ‘INCEPTION
ABYSS’. Verify the change with a suitable query.
2. Insert a new row into the short_films view with the following details, leaving the
film_id field blank:
ble
• Title: AVATAR VENDETTA
fe r a
• Language ID: 3
ans
3. Display the last AUTO_INCREMENT value MySQL used for the insertion. n - t r
4. no
Query the short_films view to see if the insertion appears. Does the new row appear in
a
a s
the view? Does it appear in the underlying film table? Explain this behavior.
h
5. Set the length of the newly added film to 45 minutes by updating
ฺ b r) the d e ฺ table. Verify the
film
update by issuing a suitable query against the short_films om t Gview.u i
6. Delete the row with film_id 1,001 from short_films, r ฺ c
a denand verify that the row is gone
e punderlying
both from the short_films view and n
s o the
S tu film table, with suitable queries.
7. Leave the mysql command-line
c i @client open
t h isfor the next practice.
t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 10
Solution 7-3: Updating a View
Solution Steps
1. In the short_films view, change the name of the film with an ID of 102 to ‘INCEPTION
ABYSS’. Verify the change with a suitable query.
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> UPDATE short_films


-> SET title='INCEPTION ABYSS'
-> WHERE film_id=102;
Query OK, 1 row affected (#.## sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> SELECT * FROM short_films WHERE film_id = 102;


+---------+-----------------+-------------+
ble
| film_id | title | language_id |
+---------+-----------------+-------------+
fe r a
| 102 | INCEPTION ABYSS | 1 |
ans
+---------+-----------------+-------------+
n - t r
1 row in set (#.## sec)
n o
a
s leaving the
2. Insert a new row into the short_films view with the following details,
film_id field blank: h a
ฺ b r) deฺ
• Title: AVATAR VENDETTA
c o m Gui
• Language ID: 3
p a rฺ ent
ne prompt
Enter the following statement at the mysql
o t d receive the results shown:
uand
s
mysql> INSERT INTO short_films i(title, S
s 3); language_id)
c i @VENDETTA',
t h
ric us(#.##
-> VALUES ('AVATAR
Query OK, 1 row ฺaffected
t o e sec)
e r to value MySQL used for the insertion.
3. Display the lastbAUTO_INCREMENT
(ro cestatement e
ns at the mysql prompt and receive the results shown:
c c
Enter thei following
li
R imysql>
erto +------------------+
SELECT LAST_INSERT_ID();

b
Ro | LAST_INSERT_ID() |
+------------------+
| 1001 |
+------------------+
1 row in set (#.## sec)
− The new row has an ID of 1001.
4. Query the short_films view to see if the insertion appears. Does the new row appear in
the view?
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM short_films;
+---------+-----------------------+-------------+
| film_id | title | language_id |
+---------+-----------------------+-------------+
| 2 | ACE GOLDFINGER | 1 |
| 3 | ADAPTATION HOLES | 1 |
| 8 | AIRPORT POLLOCK | 1 |
| 15 | ALIEN CENTER | 1 |
| 18 | ALTER VICTORY | 1 |
| 66 | BENEATH RUSH | 1 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 11
| 83 | BLUES INSTINCT | 1 |
| 97 | BRIDE INTRIGUE | 1 |
| 102 | INCEPTION ABYSS | 1 |
| 110 | CABIN FLASH | 1 |
...
| 972 | WHISPERER GIANT | 1 |
| 981 | WOLVES DESIRE | 1 |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| 1000 | ZORRO ARK | 1 |


+---------+-----------------------+--------------+
104 rows in set (#.## sec)
− Answer: Although the insertion succeeded, and the new row has an
AUTO_INCREMENT ID of 1001, the new film does not appear in this list.
Does it appear in the underlying film table?
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM film WHERE film_id > 1000\G
ble
*************************** 1. row ***************************
fe r a
film_id: 1001
ans
title: AVATAR VENDETTA
n - t r
no
description: NULL
release_year: NULL
s a
language_id: 3
h a
original_language_id: NULL
ฺ b r) deฺ
rental_duration: 3
rental_rate: 4.99
c o m Gui
length: NULL
p a rฺ ent
one s Stud
replacement_cost: 19.99
rating: G
s
special_features: NULL
c c i@ thi
r i se
last_update: 2012-07-18 20:15:26
o ฺ u
r t
1 row in set (#.## sec)
e to
b e
i (ro The
Explain this behavior.
− cAnswer: c e s
nshort_films
R ic table withli a length of up to andview was defined as including all records from the film
including 60 minutes. The length of the newly added
berto film is NULL, and therefore the film does not appear in the view.
Ro 5. Set the length of the newly added film to 45 minutes by updating the film table. Verify the
update by issuing a suitable query against the short_films view.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> UPDATE film SET length = 45 WHERE film_id = 1001;
Query OK, 1 row affected (#.## sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> SELECT * FROM short_films WHERE film_id > 1000;


+---------+-----------------+-------------+
| film_id | title | language_id |
+---------+-----------------+-------------+
| 1001 | AVATAR VENDETTA | 3 |
+---------+-----------------+-------------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 12
6. Delete the row with film_id 1,001 from short_films, and verify that the row is gone
both from the short_films view and the underlying film table, with suitable queries.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> DELETE FROM short_films WHERE film_id = 1001;
Query OK, 1 row affected (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT * FROM short_films WHERE film_id > 1000;


Empty set (#.## sec)

mysql> SELECT * FROM film WHERE film_id > 1000;


Empty set (#.## sec)
7. Leave the mysql command-line client open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 13
Practice 7-4: Checking a View
Overview
In this practice, you work with the CHECK TABLE statement and the WITH CHECK OPTION
setting.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately five minutes to complete.

Tasks
1. Check the short_films view with a suitable CHECK TABLE statement.
2. Add the WITH CHECK OPTION setting to the short_films view.
3. Re-execute the INSERT statement from Step 2 in the preceding practice, and note any
ble
difference in the results you get.
fe r a
4. Leave the mysql command-line client open for the next practice.
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 14
Solution 7-4: Checking a View
Solution Steps
1. Check the short_films view with a suitable CHECK TABLE statement.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> CHECK TABLE short_films;


+--------------------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+--------------------+-------+----------+----------+
| sakila.short_films | check | status | OK |
+--------------------+-------+----------+----------+
1 row in set (#.## sec)
2. Add the WITH CHECK OPTION setting to the short_films view.
Enter the following statement at the mysql prompt and receive the results shown: ble
fe r a
mysql> ALTER VIEW short_films AS
ans
-> SELECT film_id, title, language_id
-> FROM film WHERE length <= 60 n - t r
-> WITH CHECK OPTION;
a no
Query OK, 0 rows affected (#.## sec)
h a s
3. Re-execute the INSERT statement from Step 2 in the preceding
ฺ b r ) ฺ
practice,
e and note any
difference in the results you get.
c o m Guid
Enter the following statement at the mysql prompt
p a rฺ andereceive
n t the results shown:
mysql> INSERT INTO short_filmse(title,
-> VALUES ('AVATAR VENDETTA',s on s S 3);tudlanguage_id)
ERROR 1369 (HY000): CHECK
i c c i@ OPTION
e t hi failed 'sakila.short_films'
− Answer: The view
r t o ฺr only allows
u s inserts (or updates) if the row you are attempting to
insert (or e
b o
t the view’s WHERE condition.
update) satisfies
e
r o
4. Leave the (mysql command-line
i n s client open for the next practice.
i c c l i c e
o R
bert
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 15
Practice 7-5: Obtaining View Metadata
Overview
In this practice, you obtain metadata about a view using different techniques.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately five minutes to complete.

Tasks
1. Select all view information for the short_films view from the INFORMATION_SCHEMA
database.
2. Issue a suitable query to show the CREATE VIEW statement used to create short_films.
3. Show the table structure of the short_films view.
bl e
4. List all the tables and views in the sakila database, along with their table type (base table ra
or view). n s fe
5. Leave the mysql command-line client open for the next practice.
n - tra
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 16
Solution 7-5: Obtaining View Metadata
Solution Steps
1. Select all view information for the short_films view from the INFORMATION_SCHEMA
database.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT * FROM INFORMATION_SCHEMA.VIEWS


-> WHERE TABLE_NAME='short_films'\G
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: sakila
TABLE_NAME: short_films
VIEW_DEFINITION: SELECT `sakila`.`film`.`film_id` AS
`film_id`,`sakila`.`film`.`title` AS
ble
`title`,`sakila`.`film`.`language_id` AS `language_id` FROM
`sakila`.`film` WHERE (`sakila`.`film`.`length` <= 60)
fe r a
CHECK_OPTION: CASCADED
ans
IS_UPDATABLE: YES
n - t r
DEFINER: root@localhost
SECURITY_TYPE: DEFINER a no
CHARACTER_SET_CLIENT: utf8
h a s
COLLATION_CONNECTION: utf8_general_ci
ฺ b r) deฺ
1 row in set (#.## sec)
c o m Gui
2. Issue a suitable query to show the CREATE VIEW
p a rฺ statement
e n t used to create short_films.
Enter the following statement at the mysql
o ne prompt t d receive the results shown:
uand
s S
s ***************************
i @ 1.thirow
mysql> SHOW CREATE VIEW short_films\G
c
t o ric short_films
***************************
ฺView: u se
b e r View:
Create to CREATESQLALGORITHM=UNDEFINED
( n
DEFINER=`root`@`localhost`e
ro`film`.`film_id`
s SECURITY DEFINER VIEW `short_films` AS
c i
select
c l i c e AS `film_id`,`film`.`title` AS
i
R (`film`.`length` <= 60) WITH CASCADED CHECK OPTION
`title`,`film`.`language_id` AS `language_id` from `film` where

e r t o
b character_set_client: utf8
Ro collation_connection: utf8_general_ci
1 row in set (#.## sec)
3. Show the table structure of the short_films view.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> DESCRIBE short_films;
+-------------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------+------+-----+---------+-------+
| film_id | smallint(5) unsigned | NO | | 0 | |
| title | varchar(255) | NO | | NULL | |
| language_id | tinyint(3) unsigned | NO | | NULL | |
+-------------+----------------------+------+-----+---------+-------+
3 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 17
4. List all the tables and views in the sakila database, along with their table type (base table
or view).
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW FULL TABLES;
+----------------------------+------------+
| Tables_in_sakila | Table_type |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+----------------------------+------------+
| actor | BASE TABLE |
| actor_copy | BASE TABLE |
| actor_info | VIEW |
...
| sales_by_store | VIEW |
| short_films | VIEW |
| staff | BASE TABLE |
| staff_list | VIEW |
| store | BASE TABLE | ble
+----------------------------+------------+
fe r a
27 rows in set (#.## sec)
ans
5. Leave the mysql command-line client open for the next practice. n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 18
Practice 7-6: Additional Practice
Overview
In this practice, you create three new views and answer questions about them.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 15 minutes to complete.

Tasks
1. Create a view called districts, containing the city, district, and country for all cities in the
sakila database. You must join the address, city, and country tables to create the
view and each city must appear only once.
• Is the view updatable? Is it insertable?
ble
• If you allow duplicate cities in the view, is the view updatable and insertable?
fe r a
2. Create a view called customer_payments, containing the first name, last name, email
ans
address, and total amount paid for each customer (even customers who have not made any
n - t r
o
an
payments). Is this view updatable or insertable? Use the customer_payments view to
display information for the top 10 paying customers. s
3. ) ha ฺ
Create a view called actor_categories, containing the first name, last name, and film
r
ฺb uide
category name for all actors based on the categories of films they have acted in. You must
m
a r ฺco nt G
join five tables to get the view. You must also use the DISTINCT keyword, because some

n ep tude
actors have acted in several movies in each category. Use the new view to find the four
actors who have starred in the fewest categories of movies.
o
@ s is S
4. Exit the mysql client.
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 19
Solution 7-6: Additional Practice
Solution Steps
1. Create a view called districts, containing the city, district, and country for all cities in the
sakila database. You must join the address, city, and country tables to create the
view and each city must appear only once.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE VIEW districts AS
-> SELECT DISTINCT city, district, country
-> FROM address JOIN city USING(city_id)
-> JOIN country USING(country_id);
Query OK, 0 rows affected (#.## sec)
Is the view updatable? Is it insertable?
− Answer: The view is not updatable or insertable because of the aggregation ble
performed by the DISTINCT keyword. You must use DISTINCT because two cities
fe r a
(Lethbridge and Woodridge) each have two addresses associated with them, and
ans
therefore show up twice in the join result. If you do not use DISTINCT, these cities
n - t r
will appear in the view.
a no
h a s
If you allow duplicate cities in the view, is the view updatable and insertable?
− Answer: If you omit the DISTINCT keyword, the cities
ฺ b r) of Lethbridge
d e ฺ and Woodridge
appear twice in the view. The view is updatable,
o m Gu
but is i
insertable only for a single
base table at a time, and then only for the
a c
rฺ country n t column. The city and
district columns belong to base
n ptables that e
e tud constraints on fields not
have
present in the districts view. o
s is S
c i @
2. Create a view called customer_payments th that contains the first_name, last_name,
r i c e
s customer (even customers who have not made any
email, and total amount
payments). e r toฺ paidtoforueach
( rob estatement
Enter thei following n se at the mysql prompt and receive the results shown:
R cc CREATE
imysql> lic VIEW customer_payments AS
erto
-> SELECT first_name, last_name, email,
b -> SUM(amount) AS total
Ro -> FROM customer LEFT JOIN payment USING(customer_id)
-> GROUP BY customer_id;
Query OK, 0 rows affected (#.## sec)
Is this view updatable or insertable?
− Answer: The customer_payments view is not updatable because it contains
aggregated values in the total column. Because it is not updatable, it is not
insertable either.
Use the customer_payments view to display information for the top 10 paying customers.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM customer_payments
-> ORDER BY total DESC LIMIT 10;
+------------+-----------+----------------------------------+--------+
| first_name | last_name | email | total |
+------------+-----------+----------------------------------+--------+
| KARL | SEAL | KARL.SEAL@sakilacustomer.org | 221.55 |
| ELEANOR | HUNT | ELEANOR.HUNT@sakilacustomer.org | 216.54 |
| CLARA | SHAW | CLARA.SHAW@sakilacustomer.org | 195.58 |
| RHONDA | KENNEDY | RHONDA.KENNEDY@sakilacustomer.org| 194.61 |
| MARION | SNYDER | MARION.SNYDER@sakilacustomer.org | 194.61 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 20
| TOMMY | COLLAZO | TOMMY.COLLAZO@sakilacustomer.org | 186.62 |
| WESLEY | BULL | WESLEY.BULL@sakilacustomer.org | 177.60 |
| TIM | CARY | TIM.CARY@sakilacustomer.org | 175.61 |
| MARCIA | DEAN | MARCIA.DEAN@sakilacustomer.org | 175.58 |
| ANA | BRADLEY | ANA.BRADLEY@sakilacustomer.org | 174.66 |
+------------+-----------+----------------------------------+--------+
10 rows in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

3. Create a view called actor_categories that contains the first name, last name, and film
category name for all actors based on the categories of films they have acted in. You must
join five tables to get the view. You must also use the DISTINCT keyword, because several
actors have acted in several movies of each category.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> CREATE VIEW actor_categories AS
-> SELECT DISTINCT first_name, last_name, name AS `category`
-> FROM actor
ble
-> JOIN film_actor USING(actor_id)
fe r a
-> JOIN film USING(film_id)
-> JOIN film_category USING(film_id)
ans
-> JOIN category USING(category_id);
n - t r
Query OK, 0 rows affected (#.## sec)
a no
h a s categories of
Use the new view to find the four actors who have starred in the fewest

ฺ b )
movies. Enter the following statement at the mysql prompt rand receive
e ฺ the results shown:
mysql> SELECT first_name, last_name,
c o m Guid
-> COUNT(*) AS `different categories`
-> FROM actor_categories p a rฺ ent
-> GROUP BY 1, 2 ORDER BY
s one3 sLIMIT
S tu4;d
hi
+------------+-----------+----------------------+
| first_name | last_name
c c i@ | different
t categories |
ฺ r i us|e
t|oDEAN
+------------+-----------+----------------------+
| JUDY
| JULIAob
e r t o 8 |
r s e
| FAWCETT | 8 |
i ( e |nDEE
c c
| EMILY
l i c |
i+------------+-----------+----------------------+
9 |
R | KENNETH | PESCI | 9 |

berto 4 rows in set (#.## sec)


Ro 4. Exit the mysql client.
Enter the following at the mysql prompt and receive the message shown:
mysql> EXIT
Bye
#

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 21
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 7: Tables and Views


Chapter 7 - Page 22
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 8:
Working omwith i
uStrings
r ฺ c
a 8 den t G
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 1
Practices for Lesson 8: Working with Strings
Practices Overview
These practices test your knowledge of searching and manipulating strings. They assume that
you are using the Linux operating system environment provided in Oracle classrooms. For non-
Oracle classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The sakila sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 2
Practice 8-1: Manipulating String Data With MySQL Expressions
Overview
In this practice, you work with string data in the sakila database and use a range of functions
and expressions to display the data in various formats.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
1. Log into the mysql command line client and change the current database to sakila.
2. From the address table, use the CONCAT() function to list the address ID, address,
district, city ID, and postal code all on one line (separated by commas) for each address in
the district of Buenos Aires. ble
3. Execute a query that lists all rows in the address table that have a NULL value in the fe r a
address2 column. Make a note of the address_id for each row that the query returns. ans
n - t r
4. Execute a query that uses the CONCAT() function to list address_ID, address, o
an
address2, and district all on one line (separated by commas) for the addresses with
s
r ) ha ฺ
the IDs you discovered in the preceding step. What is the result, and why?
5. ฺb uide
Rewrite the query in the preceding step using an alternative concatenation function that
m
ฺco nt G
ignores null values and allows you to pass in a string to use as a column separator.
6. a r
Execute a query of the category table that displays the first three letters of the category
n ep tude
name using the column alias “short_category.” Use the UCASE() function to show the
o
names in upper case.
@ s is S
7. c c i th
Execute a query of the film_list table, to list the first actor in the comma-separated list
r i e
two steps: e r toฺ to us
of actors in the actors column using the column alias “starring.” Complete this query in

i ( rob ense
a. Use the INSTR() function to retrieve the position of the first comma.
c lic
to Ric
b. Use the value returned by INSTR() to calculate the end position as an argument to
e r SUBSTRING() to retrieve the portion of the string before the first comma.

R ob 8. Keep the Linux terminal window open and logged into the mysql client for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 3
Solution 8-1: Manipulating String Data With MySQL Expressions
Solution Steps
1. Log into the mysql command line client and change the current database to sakila.
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
Enter the following statement at the mysql prompt and receive the results shown:
mysql> USE sakila
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
ble
fe r a
Database changed
ans
mysql>
n - t r
2. no
From the address table, use the CONCAT() function to list the address ID, address,
a
the district of Buenos Aires. h a s
district, city ID, and postal code all on one line (separated by commas) for each address in

ฺ b r) deฺ
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT CONCAT(address_id, ', ฺ', c o m Gu',i ',
-> district, ', ', city_id,p', a e n t
r', postal_code)
address,

-> AS 'Addresses in Buenos


s oneAires' S tud
-> FROM address
c i @ t h isAires';
ric use
-> WHERE district = 'Buenos
o ฺ
+-----------------------------------------------------------------+
t
| Addresses rin Buenos
b e e to Aires |
o El nAlto
(r1926 s Avenue, Buenos Aires, 289, 75543
+-----------------------------------------------------------------+
i
i c c
| 93,
l i c e |

to R | 111, 1532 Dzerzinsk Way, Buenos Aires, 334, 9599 |

e r | 223, 1244 Allappuzha (Alleppey) Place, Buenos Aires, 567, 20657 |

ob
| 327, 1427 A Corua (La Corua) Place, Buenos Aires, 45, 85799 |
R | 364, 1623 Kingstown Drive, Buenos Aires, 20, 91299
| 410, 88 Nagaon Manor, Buenos Aires, 524, 86868
|
|
| 450, 203 Tambaram Street, Buenos Aires, 161, 73942 |
| 536, 166 Jinchang Street, Buenos Aires, 165, 86760 |
| 566, 1229 Varanasi (Benares) Manor, Buenos Aires, 43, 40195 |
| 591, 773 Dallas Manor, Buenos Aires, 424, 12664 |
+-----------------------------------------------------------------+
10 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 4
3. Execute a query that lists all rows in the address table that have a NULL value in the
address2 column. Make a note of the address_id for each row that the query returns.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT address_id, address2
-> FROM address
-> WHERE ISNULL(address2);
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+------------+----------+
| address_id | address2 |
+------------+----------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 4 | NULL |
+------------+----------+
4 rows in set (#.## sec)
− The addresses with IDs of 1, 2, 3, and 4 have a value of NULL in the address2 ble
column. fe r a
ans
4. Execute a query that uses the CONCAT() function to list address_ID, address,
address2, and district all on one line (separated by commas) for the addresses with n - t r
no
the IDs you discovered in the preceding step. What is the result, and why?
a
a s
Enter the following statement at the mysql prompt and receive the results shown:
h
mysql> SELECT CONCAT(address_id, ', ', address, ฺ b r) ',deฺ
-> ', address2, ', ', district)
c o m Gui
-> FROM address
p a rฺ ent
ne Stud
-> WHERE address_id IN(1,2,3,4);
s o
+-------------------------------------------------------------------+
i @ this ', ', address2, ', ', district) |
| CONCAT(address_id, ', ', address,
c
| NULL
t o ric use
+-------------------------------------------------------------------+
ฺ |
e r t o
| NULLrob
| NULL |
( cen s e |
|c
c i
NULL
l i |
R i+-------------------------------------------------------------------+

e r to 4 rows in set (#.## sec)

R ob − Answer: The resulting string for each address is NULL. This is because the
CONCAT() function, like many other MySQL functions, returns NULL if one or more
of its arguments is NULL.
5. Rewrite the query in the preceding step using an alternative concatenation function that
ignores null values and allows you to pass in a string to use as a column separator.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT CONCAT_WS(', ', address_id, address, address2,
district)
-> FROM address
-> WHERE address_id IN(1,2,3,4);
+----------------------------------------------------------+
| CONCAT_WS(', ', address_id, address, address2, district) |
+----------------------------------------------------------+
| 1, 47 MySakila Drive, Alberta |
| 2, 28 MySQL Boulevard, QLD |
| 3, 23 Workhaven Lane, Alberta |
| 4, 1411 Lillydale Drive, QLD |
+----------------------------------------------------------+
4 rows in set (#.## sec)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 5
− The CONCAT_WS() function ignores null values and allows you to specify the
column separator as the first argument.
6. Execute a query of the category table that displays the first three letters of the category
name using the column alias “short_category.” Use the UCASE() function to show the
names in upper case.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT UCASE(LEFT(name,3)) AS short_category FROM category;


+----------------+
| short_category |
+----------------+
| ACT |
| ANI |
| CHI |
| CLA |
| COM |
ble
| DOC |
fe r a
| DRA |
ans
| FAM
| FOR
|
|
n - t r
| GAM |
a no
| HOR
| MUS
|
| h a s
| NEW |
ฺ b r) deฺ
| SCI |
c o m Gui
| SPO |
p a rฺ ent
one s Stud
| TRA |
+----------------+
s
i@ table, htoi list the first actor in the comma-separated list
16 rows in set (#.## sec)
7. Execute a query of the film_list i c c e t
r
of actors in the actorst o ฺrcolumn using
us the column alias “starring.” Complete this query in
b e t o
two steps:
i ( roINSTR()
e n se to retrieve the position of the first comma.
i−ccEnter thelifollowing
c
a. Use the function

t o R statement at the mysql prompt and receive the results shown:


be r mysql> SELECT INSTR(actors, ',') AS comma_pos FROM film_list;
Ro +-----------+
| comma_pos |
+-----------+
| 17 |
| 12 |
| 14 |
| 16 |
| 13 |
| 16 |
...
| 9 |
| 12 |
| 10 |
+-----------+
997 rows in set (#.## sec)
b. Use the value returned by INSTR() to calculate the end position as an argument to
SUBSTRING() to retrieve the portion of the string before the first comma.
− Enter the following statement at the mysql prompt and receive the results shown:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 6
mysql> SELECT SUBSTRING(actors, 1, (INSTR(actors, ',')-1))
-> AS starring
-> FROM film_list;
+----------------------+
| starring |
+----------------------+
| PENELOPE GUINESS |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| BOB FAWCETT |
| NICK WAHLBERG |
| JODIE DEGENERES |
| GARY PHOENIX |
| KIRSTEN PALTROW |
...
| UMA WOOD |
| CARMEN HUNT |
| IAN TANDY |
+----------------------+ ble
997 rows in set (#.## sec)
fe r a
− Note: You need to subtract one from the comma position to avoid seeing the
ans
comma in the list of results.
n - t r
o
8.
an
Keep the Linux terminal window open and logged into the mysql client for the next
practice. s
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 7
Practice 8-2: Matching Patterns in Strings
Overview
In this practice, you execute queries that search for particular patterns within actors’ surnames
in the sakila database and analyze a complex regular expression provided for you.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a Linux terminal prompt open and are logged into the mysql client from the previous
practice. The current database is sakila.

Duration
This practice should take approximately 20 minutes to complete.

Tasks ble
1. Concatenate the first and last names of all actors in the actor table whose last names fe r a
start with ‘AL’. Use the LIKE clause with the appropriate “wild card” operator to identify ans
matching last names. n - t r
o
2.
an
Concatenate the first and last names of all actors in the actor table whose last names end
s
with ‘ING’. Use the LIKE clause with the appropriate “wild card” operator to identify
matching last names. r ) ha ฺ
3. m ฺb uide
Concatenate the first and last names of all actors in the actor table whose last names
r ฺco nt G
contain the string ‘AVI’. Use the LIKE clause with the appropriate “wild card” operator to
a
identify matching last names.
o n ep tude
4. s is S
Concatenate the first and last names of all actors in the actor table whose last names do
@
i th
not have an ‘A’ or an ‘E’ as the second letter. Use the NOT LIKE clause with the appropriate
c c
r i e
toฺ to us
“wild card” operator to identify matching last names.
5. e r
Rewrite the preceding query using the REGEXP (or RLIKE) operator with an appropriate

i ( rob ense
regular expression.
c lic
Ric
6. Concatenate the first and last names of all actors in the actor table whose last names end
with “SON.” Use the RLIKE or REGEXP operator with an appopriate regular expression to
e r to achieve this.
R ob 7. Concatenate the first and last names of all actors in the actor table whose last names
start with a vowel (‘a’, ‘e’, ‘i’, ‘o’, or ‘u’) or end with “IS.” Use the RLIKE or REGEXP operator
with an appopriate regular expression to achieve this.
8. Consider the following regular expression. What common string pattern does it match and
how does it work?
^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$
9. Keep the Linux terminal window open and logged into the mysql client for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 8
Solution 8-2: Matching Patterns in Strings
Solution Steps
1. Concatenate the first and last names of all actors in the actor table whose last names
start with ‘AL’. Use the LIKE clause with the appropriate “wild card” operator to identify
matching last names.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT CONCAT_WS(' ', first_name,last_name)
-> FROM actor
-> WHERE last_name LIKE 'AL%';
+--------------------------------------+
| CONCAT_WS(' ', first_name,last_name) |
+--------------------------------------+
| CUBA ALLEN |
ble
| KIM ALLEN
| MERYL ALLEN
|
|
fe r a
+--------------------------------------+
ans
3 rows in set (#.## sec)
n - t r
o
2.
an
Concatenate the first and last names of all actors in the actor table whose last names end
s
with ‘ING’. Use the LIKE clause with the appropriate “wild card” operator to identify
matching last names.
r ) ha ฺ
ฺb uide
Enter the following statement at the mysql prompt and receive the results shown:
m
r ฺco nt G
mysql> SELECT CONCAT_WS(' ', first_name,last_name)
a
-> FROM actor
o n ep tude
-> WHERE last_name LIKE
@ s is S
'%ING';

c c i
+--------------------------------------+
th
ฺ r i s e
| CONCAT_WS(' ', first_name,last_name) |

r
| SCARLETTeBENINGto to u
+--------------------------------------+
|
| EWANro b e
|c i ( BENING
GOODING
c e ns |

GREGORY liGOODING
MICHAEL |
R i|c |

e r to +--------------------------------------+

R ob 3.
4 rows in set (#.## sec)
Concatenate the first and last names of all actors in the actor table whose last names
contain the string ‘AVI’. Use the LIKE clause with the appropriate “wild card” operator to
identify matching last names.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT CONCAT_WS(' ', first_name,last_name)
-> FROM actor
-> WHERE last_name LIKE '%AVI%';
+--------------------------------------+
| CONCAT_WS(' ', first_name,last_name) |
+--------------------------------------+
| JENNIFER DAVIS |
| SUSAN DAVIS |
| SUSAN DAVIS |
+--------------------------------------+
3 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 9
4. Concatenate the first and last names of all actors in the actor table whose last names do
not have an ‘A’ or an ‘E’ as the second letter. Use the NOT LIKE clause with the appropriate
“wild card” operator to identify matching last names.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT CONCAT_WS(' ',first_name,last_name)
-> FROM actor
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

-> WHERE last_name NOT LIKE '_A%'


-> AND last_name NOT LIKE '_E%';
+-------------------------------------+
| CONCAT_WS(' ',first_name,last_name) |
+-------------------------------------+
| PENELOPE GUINESS |
| ED CHASE |
| JOHNNY LOLLOBRIGIDA |
| BETTE NICHOLSON |
| GRACE MOSTEL | ble
| MATTHEW JOHANSSON |
fe r a
...
ans
| CUBA BIRCH |
n - t r
| GREGORY GOODING
| JOHN SUVARI
|
|
a no
| MERYL ALLEN |
h a s
| JAYNE SILVERSTONE |
ฺ b r) deฺ
+-------------------------------------+
117 rows in set (#.## sec)
c o m Gui
5. Rewrite the preceding query using the REGEXP p a rฺ entoperator with an appropriate
(or RLIKE)
regular expression.
s one s Stud
Enter the following statement at
i c c i@
e t hi prompt and receive the results shown:
the mysql

t o ฺr
mysql> SELECT CONCAT_WS('
-> FROM ractor u s ',first_name,last_name)
-> o be last_namee o
t NOT RLIKE '^.[ae]';
r WHERE
s
i ( licen',first_name,last_name) |
c c
+-------------------------------------+
i+-------------------------------------+
o R | CONCAT_WS('

bert | PENELOPE GUINESS |


Ro | ED CHASE
| JOHNNY LOLLOBRIGIDA
|
|
| BETTE NICHOLSON |
| GRACE MOSTEL |
| MATTHEW JOHANSSON |
...
| CUBA BIRCH |
| GREGORY GOODING |
| JOHN SUVARI |
| MERYL ALLEN |
| JAYNE SILVERSTONE |
+-------------------------------------+
117 rows in set (#.## sec)
− RLIKE and REGEXP are synonymous in MySQL.
− The ^ symbol in the regular expression “anchors” the search to the start of the
string.
− The . symbol matches any character.
− The [ae] character class matches either a or e in the second position.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 10
− Negating RLIKE with NOT returns all last names that do not have an ‘A’ or an ‘E’ in
the second character position.
6. Concatenate the first and last names of all actors in the actor table whose last names end
with “SON.” Use the RLIKE or REGEXP operator with an appopriate regular expression to
achieve this.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT CONCAT_WS(' ', first_name,last_name)


-> FROM actor
-> WHERE last_name RLIKE 'son$';
+--------------------------------------+
| CONCAT_WS(' ', first_name,last_name) |
+--------------------------------------+
| BETTE NICHOLSON |
| MATTHEW JOHANSSON |
| CHRISTIAN NEESON |
ble
| JAYNE NEESON |
fe r a
| RAY JOHANSSON |
ans
| ANGELA HUDSON
| ALBERT JOHANSSON
|
|
n - t r
| MERYL GIBSON |
a no
| WILL WILSON |
+--------------------------------------+ h a s
9 rows in set (#.## sec)
ฺ b r) deฺ
− The son characters in the regular expression o m u
is the pattern i you are trying to match.
− The $ symbol “anchors” the search p toathe
c G
rฺ end ofenthet string.
e
7. Concatenate the first and last namesoofnall actorstin
s S udthe actor table whose last names
start with a vowel (‘a’, ‘e’, ‘i’, ‘o’,@
c i t h is with “IS.” Use the RLIKE or REGEXP operator
or ‘u’) or end
with an appopriate regularic eto achieve this.
t o ฺr expression
Enter the following rstatement u smysql
e
b CONCAT_WS(' t o
at the prompt and receive the results shown:
mysql>ro
i ( SELECT
e n se ',first_name,last_name)

icc -> WHERElic last_name RLIKE '^[aeiou]|is$';


-> FROM actor
R
erto
+-------------------------------------+
b
Ro
| CONCAT_WS(' ',first_name,last_name) |
+-------------------------------------+
| JENNIFER DAVIS |
| CUBA OLIVIER |
| AUDREY OLIVIER |
| BURT DUKAKIS |
| FRANCES DAY-LEWIS |
| DAN HARRIS |
| CHRISTIAN AKROYD |
| ANGELINA ASTAIRE |
| BEN WILLIS |
| KIRSTEN AKROYD |
| GENE WILLIS |
| SUSAN DAVIS |
| SUSAN DAVIS |
| CUBA ALLEN |
| CATE HARRIS |
| KIM ALLEN |
| BEN HARRIS |
| HUMPHREY WILLIS |
| DEBBIE AKROYD |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 11
| ROCK DUKAKIS |
| MERYL ALLEN |
+-------------------------------------+
21 rows in set (#.## sec)
− The ^ symbol in the regular expression “anchors” the first search expression to the
start of the string.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

− The [aeiou] character class matches any vowel in the first position.
− The | symbol is the “alternation” character, allowing you to match one character
from a list of alternatives.
− The is characters are the alternative characters you are trying to match against.
− The $ symbol anchors the second search expression to the end of the string.
8. Consider the following regular expression. What common string pattern does it match and
how does it work?
ble
^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$
fe r a
Answer: This regular expression matches email addresses.
ans
− The ^ symbol “anchors” the search to the start of the string.
n - t r
o
s an
− The ([a-z0-9_\.-]+) searches for a valid username portion of the email
address, matching one or more lower case letters, numbers, underscores, periods,
) ha ฺ
or hyphens. Note how the period is preceded by a backslash (\). This is because a
r
ฺb uide
period on its own in regular expression syntax matches any character. The
m
a r ฺco nt G
backslash acts as an “escape” character.

address. o n ep tude
− The @ sign is required between the username and domain portion of the email

@ s is S
i th
− The ([\da-z\.-]+) searches for a valid domain name which must match one of
c c
r i e
toฺ to us
more lower case letters, numbers, underscores, or hyphens.
e r
− The \. characters specify that a period must exist between the domain name and
( rob ense
the country-specific Top-level Domain (TLD).
i
c lic
to Ric
− The ([a-z\.]{2,6})$ searches for a valid TLD at the end of the string, which
must contain 2 to 6 letters or periods.
e r
R ob 9. Keep the Linux terminal window open and logged into the mysql client for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 12
Practice 8-3: Using Full-Text Searches
Overview
In this practice, you add a FULLTEXT index to an existing text column in the sakila database
film_text table and use it to perform a variety of full-text searches.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a Linux terminal prompt open and are logged into the mysql client from the previous
practice. The current database is sakila.

Duration
This practice should take you approximately 15 minutes to complete

Tasks ble
1. Execute a DESCRIBE command to display the structure of the film_text table. fe r a
2. Add a FULLTEXT index to the description column of the film_text table and verify that ans
the new index exists by issuing a SHOW CREATE TABLE statement. n - t r
o
3. an
Test the new full-text search capability on the description column of the film_text table
s
default search mode (IN NATURAL LANGUAGE MODE.) r ) ha ฺ
by executing a query that matches all films with the word “Explorer” in the title using the

4. m ฺb uide
Modify the preceding query to use “Epic Drama” as the text to search against. Why don’t
r ฺco nt G
the query results contain only films with the text “Epic Drama” in their description?
a
5. ep tude
Rewrite the query from the preceding step to use IN BOOLEAN MODE and ensure that it
o n
s is S
matches only film descriptions that contain the exact string “Epic Drama”.
@
6. c c i th
Execute a query that matches all films with a description that contains the word “Robot” but
r i e
e r toฺ to us
not the word “Challenge.”
7.
8. i ( rob ense
Remove the FULLTEXT index from the description column in the film_text table.
Exit the mysql client and close the Linux terminal window.
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 13
Solution 8-3: Using Full-Text Searches
Solution Steps
1. Execute a DESCRIBE command to display the structure of the film_text table.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> DESCRIBE film_text;


+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| film_id | smallint(6) | NO | PRI | NULL | |
| title | varchar(255) | NO | MUL | NULL | |
| description | text | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+-------+
3 rows in set (#.## sec)
− The column that needs to be searchable via full-text querying is the description ble
column, which is of type TEXT. FULLTEXT indexes can be added to either TEXT, fe r a
CHAR, or VARCHAR columns. ans
2. Add a FULLTEXT index to the description column of the film_text table and verify that n - t r
the new index exists by issuing a SHOW CREATE TABLE statement. a no
a s
Enter the following statements at the mysql prompt and receive the results shown:
h
ฺ b r) deฺ
mysql> ALTER TABLE film_text ADD FULLTEXT(description);
Query OK, 1000 rows affected (#.## sec)
c o m Gui
Records: 1000 Duplicates: 0 Warnings:
p a rฺ 0ent
s o
mysql> SHOW CREATE TABLE film_text\Gne Stud
c i @ th s ***************************
*************************** 1. irow

Create Table: o
t ric TABLE
Table: film_text

CREATE u se`film_text` (
`film_id`
b e rsmallint(6)
to NOT
NOT NULL,
( r
`title` o n s e
varchar(255) NULL,
c i c e
Ric PRIMARYliKEY (`film_id`),
`description` text,

e r to FULLTEXT KEY `idx_title_description` (`title`,`description`),

R ob FULLTEXT KEY `description` (`description`)


) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (#.## sec)
3. Test the new full-text search capability on the description column of the film_text table
by executing a query that matches all films with the word “Explorer” in the title using the
default search mode (IN NATURAL LANGUAGE MODE.)
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM film_text
-> WHERE MATCH(description) AGAINST('Explorer');
+---------+------------------------+-----------------------------+
| film_id | title | description |
+---------+------------------------+-----------------------------+
| 369 | GOODFELLAS SALUTE | ...Dog And a Explorer... |
| 482 | JEOPARDY ENCINO | ...must Face an Explorer... |
| 742 | ROOF CHAMPION | ...Car And a Explorer... |
| 830 | SPIRIT FLINTSTONES | ...Confront a Explorer... |
...
| 198 | CRYSTAL BREAKING |...Feminist And a Explorer...|
| 226 | DESTINY SATURDAY |...Conquer a Explorer... |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 14
| 347 | GAMES BOWFINGER |...Butler And a Explorer... |
+---------+------------------------+-----------------------------+
82 rows in set (#.## sec)
4. Modify the preceding query to use “Epic Drama” as the text to search against. Why don’t
the query results contain only films with the text “Epic Drama” in their description?
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT * FROM film_text


-> WHERE MATCH(description) AGAINST('Epic Drama');
+---------+-------------------------+---------------------------+
| film_id | title | description |
+---------+-------------------------+---------------------------+
| 384 | GROSSE WONDERFUL | A Epic Drama of a Cat... |
| 597 | MOONWALKER FOOL | A Epic Drama of a Fem... |
| 802 | SKY MIRACLE | A Epic Drama of a Mad... |
| 1 | ACADEMY DINOSAUR | A Epic Drama of a Fem... |
ble
| 53 | BANG KWAI | A Epic Drama of a Mad... |
fe r a
| 864 | SUNDANCE INVASION | A Epic Drama of a Lum... |
ans
|
|
489 | JUGGLER HARDLY
670 | PELICAN COMFORTS
| A Epic Story of a Mad... |
| A Epic Documentary of... |
n - t r
| 97 | BRIDE INTRIGUE | A Epic Tale of a Robo... |
a no
...
| 296 | EXPRESS LONELY h
| A Boring Drama of a A... | a s
| 570 | MERMAID INSECTS
ฺ b r) deฺ
| A Lacklusture Drama o... |
| 496 | KICK SAVANNAH m Gui
| A Emotional Drama of ... |
c o
|
|
744 | ROOTS REMEMBER
797 | SILENCE KANE p a rฺ ent
| A Brilliant Drama of ... |
| A Emotional Drama of ... |
one s Stud
+---------+-------------------------+---------------------------+
s
hi mode (IN NATURAL LANGUAGE MODE_,
142 rows in set (#.## sec)
c @ search
ifull-text t
− Answer: In the default i c e
ฺrby defaultuswhen matching words, so it returns any row that
MySQL usestOR
e r o to
matchesb “Epic” ore“Drama.”
o fromnsthe preceding step to use IN BOOLEAN MODE and ensure that it
5. Rewrite ithe
c (rquery e
cdescriptions
i c
matches
R l
only film i that contain the exact string “Epic Drama”.

ert oEnter the following statement at the mysql prompt and receive the results shown:
b
Ro mysql> SELECT * FROM film_text
-> WHERE MATCH(description)
-> AGAINST ('"Epic Drama"' IN BOOLEAN MODE);
+---------+-------------------+-------------------------+
| film_id | title | description |
+---------+-------------------+-------------------------+
| 1 | ACADEMY DINOSAUR | A Epic Drama of a Fem...|
| 53 | BANG KWAI | A Epic Drama of a Mad...|
| 384 | GROSSE WONDERFUL | A Epic Drama of a Cat...|
| 597 | MOONWALKER FOOL | A Epic Drama of a Fem...|
| 802 | SKY MIRACLE | A Epic Drama of a Mad...|
| 864 | SUNDANCE INVASION | A Epic Drama of a Lum...|
+---------+-------------------+-------------------------+
6 rows in set (#.## sec)
− The presence of the IN BOOLEAN MODE clause and the double quotes("")
around the search term signifies that the match must be exact.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 15
6. Execute a query that matches all films with a description that contains the word “Robot” but
not the word “Challenge.”
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT title, description FROM film_text
-> WHERE MATCH(description)
-> AGAINST ('Robot -Challenge' IN BOOLEAN MODE);
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+-------------------+----------------------------------------------+
| title | description |
+-------------------+----------------------------------------------+
| AGENT TRUMAN | ...a Robot And a Boy who must Escape... |
| ALLEY EVOLUTION | ...a Robot And a Composer who must Battle... |
| ANGELS LIFE | ...Battle a Robot in Berlin |
| BEAUTY GREASE | ...Sink a Robot in An Abandoned Mine Shaft |
| BEDAZZLED MARRIED | ...a Robot who must Meet... |
| BLINDNESS GUN | ...a Robot And a Dentist who must Meet... |
| BONNIE HOLOCAUST | ...a Crocodile And a Robot who must Find... |
ble
| BRIDE INTRIGUE | ...a Robot And a Monkey who must Vanquish... |
fe r a
| CADDYSHACK JEDI | ...Fight a Robot in Soviet Georgia |
ans
| CALIFORNIA BIRDS | ...a Robot who must Battle... |
n - t r
no
...
+---------+------------------------+-------------------------------+
s a
73 rows in set (#.## sec)
) h a
− The - operator next to the word “Challenge” in the search
ฺ b r text
e ฺ
omits any results that
contain this word.
c o m Guid
7. Remove the FULLTEXT index from the description
a r ฺ column
n t in the film_text table.
Enter the following statements at the mysql
o n dereceive the results shown:
epprompttuand
mysql> SHOW CREATE TABLE s
i s S
c i @ film_text\G
t h
***************************
r i c e 1. row ***************************
ฺ TABLE
toCREATE
Table: film_text
r t o us `film_text` (
Create Table:
e
i ( robvarchar(255)
`film_id`
e n se NOT
smallint(6) NOT NULL,

i c c`description`
`title`
l i c text, NULL,

t o R PRIMARY KEY (`film_id`),


be r FULLTEXT KEY `idx_title_description` (`title`,`description`),
Ro FULLTEXT KEY `description` (`description`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (#.## sec)

mysql> ALTER TABLE film_text


-> DROP INDEX idx_title_description;
Query OK, 1000 rows affected (#.## sec)
Records: 1000 Duplicates: 0 Warnings: 0

mysql> ALTER TABLE film_text


-> DROP INDEX description;
Query OK, 1000 rows affected (#.## sec)
Records: 1000 Duplicates: 0 Warnings: 0

mysql> SHOW CREATE TABLE film_text\G


*************************** 1. row ***************************
Table: film_text
Create Table: CREATE TABLE `film_text` (
`film_id` smallint(6) NOT NULL,
`title` varchar(255) NOT NULL,
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 16
`description` text,
PRIMARY KEY (`film_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (#.## sec)

mysql>
8. Exit the mysql client and close the Linux terminal window.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following commands and receive the results shown:


mysql> EXIT
Bye
# exit

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 17
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 8: Working with Strings


Chapter 8 - Page 18
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 9:
Working omwith i
uNumeric and
r ฺ c
a denData t G
Temporal
p
e
on Chaptertu9
s s S
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 1
Practices for Lesson 9: Working with Numeric and Temporal Data
Practices Overview
These practices test your knowledge of working with tables and views. They assume that you
are using the Linux operating system environment provided in Oracle classrooms. For non-
Oracle classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The world sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 2
Practice 9-1: Using Numeric Data in SQL Expressions
Overview
In this practice, you use a variety of numerical data types in SQL expressions.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 15 minutes to complete.

Tasks
1. Log into the mysql command-line client and enter a SQL expression to add the following
together: 2, 3, and NULL.
2. Use a SQL expression to add the following together: 2, 3, and ‘6’ (in single quotation
marks).
3. Evaluate the following MySQL statement and explain the results: ble
fe r a
SELECT 1.1 + 2.2 = 3.3, 1.1E0 + 2.2E0 = 3.3E0;
ans
4. Issue a statement that finds the three countries with the largest gross national product (GNP
n - t r
o
an
column) in the Country table of the world database.
s
5. Use a numeric expression to find the average (mean) of the three gross national product
ha ฺ
value.
r )
values you found in the preceding step. Ensure that you include the decimal part of the
ฺb uide
m
a r ฺco nt G
6. Modify the statement in the previous step to exclude the decimal portion of the gross

o n ep tude
national product values in the query expression. Explain the difference in the result.
s is S
7. Use a suitable MySQL function to approximate the value of the average you calculated in
@
i th
the preceding step, to the nearest integer.
c c
r i e
toฺ to us
8. Calculate the FLOOR() and CEILING() values of the gross national product averages
r
from the preceding step.
e
( rob ense
9. Execute a query that lists the name and the difference between the current and old gross
i
c lic
Ric
national product values for the first 20 countries in the Country table. Exclude any
countries with NULL values in the GNP or GNPOld columns.
e r to
10. Modify the statement in the preceding step to display the absolute value of the difference
R ob between current and old gross national product values.
11. Modify the statement in the preceding step to remove the decimal part of the difference in
gross national product values, without affecting the integer part.
12. Keep the Linux terminal window open and logged into the mysql client for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 3
Solution 9-1: Using Numeric Data in SQL Expressions
Solution Steps
1. Log into the the mysql command-line client and enter a SQL expression to add the
following together: 2, 3, and NULL.
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT 2+3+NULL;
+----------+ ble
| 2+3+NULL |
fe r a
+----------+
ans
| NULL |
n - t r
+----------+
1 row in set (#.## sec)
a no
− Adding NULL to a value gives a NULL result. h a s
2. Use a SQL expression to add the following together: 2, 3, ฺ b r) ‘6’ (indesingle
and ฺ quotation
marks). om t Gu i
Enter the following statement at the mysql prompt r ฺ
a andc n the results shown:
receive
e p d e
mysql> SELECT 2+3+'6';
s on s Stu
+---------+
c c i@ thi
| 2+3+'6' |
o ฺ r i u se
+---------+
| r
11 e t to
|
b e
(rino setce(#.##
+---------+
1c i ns sec)
R
row
li
i−c MySQL converts the string ‘6’ into a number before performing the calculation.
r t o
e3. Evaluate the following MySQL statement and explain the results:
b
Ro SELECT 1.1 + 2.2 = 3.3, 1.1E0 + 2.2E0 = 3.3E0;
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT 1.1 + 2.2 = 3.3, 1.1E0 + 2.2E0 = 3.3E0;
+-----------------+-----------------------+
| 1.1 + 2.2 = 3.3 | 1.1E0 + 2.2E0 = 3.3E0 |
+-----------------+-----------------------+
| 1 | 0 |
+-----------------+-----------------------+
1 row in set (#.## sec)
− Answer: The first expression in the statement is true. The second expression in the
statement uses approximate values and therefore cannot be guaranteed to give an
exact-value result.
4. Issue a statement that finds the three countries with the largest gross national product (GNP
column) in the Country table of the world database.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT Name, GNP FROM world.Country ORDER BY GNP DESC LIMIT 3;
+---------------+------------+
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 4
| Name | GNP |
+---------------+------------+
| United States | 8510700.00 |
| Japan | 3787042.00 |
| Germany | 2133367.00 |
+---------------+------------+
3 rows in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

5. Use a numeric expression to find the average (mean) of the three gross national product
values you found in the preceding step. Ensure that you include the decimal part of the
value.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT (8510700.00 + 3787042.00 + 2133367.00)/3;
+------------------------------------------+
| (8510700.00 + 3787042.00 + 2133367.00)/3 |
+------------------------------------------+
ble
| 4810369.666667 |
fe r a
+------------------------------------------+
1 row in set (#.## sec)
t r a ns
6. Modify the statement in the previous step to exclude the decimal portion of o n
the
-
gross
national product values in the query expression. Explain the differenceain n the result.
Enter the following statement at the mysql prompt and receiveh a s
the results shown:
ฺ b r ) e ฺ
i d
comnt Gu
mysql> SELECT (8510700 + 3787042 + 2133367)/3;

| (8510700 + 3787042 + 2133367)/3a|rฺ


+---------------------------------+

+---------------------------------+
o n ep | tude
| s is S
4810369.6667
@
c i
+---------------------------------+
c th
1 row in set (#.##
ฺ r i sec) e
s input values leads to reduced accuracy in the result.
uthe
− Answer: Less
e r toaccuracy t o in
r
7. Use a suitable
i ( obMySQLnfunction
se to approximate the value of the average you calculated in
cc step,
the preceding
i e
lic to the nearest integer.
R
Enter the following statement at the mysql prompt and receive the results shown:
berto
Ro
mysql> SELECT ROUND((8510700 + 3787042 + 2133367)/3);
+---------------------------------------+
| ROUND((8510700 + 3787042 +2133367)/3) |
+---------------------------------------+
| 4810370 |
+---------------------------------------+
1 row in set (#.## sec)
8. Calculate the FLOOR() and CEILING() values of the gross national product averages
from the preceding step.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT FLOOR((8510700 + 3787042 + 2133367)/3);
+---------------------------------------+
| FLOOR((8510700 + 3787042 +2133367)/3) |
+---------------------------------------+
| 4810369 |
+---------------------------------------+
1 row in set (#.## sec)

mysql> SELECT CEILING((8510700 + 3787042 + 2133367)/3);

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 5
+-----------------------------------------+
| CEILING((8510700 + 3787042 +2133367)/3) |
+-----------------------------------------+
| 4810370 |
+-----------------------------------------+
1 row in set (#.## sec)
9. Execute a query that lists the name and the difference between the current and old gross
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

national product values for the first 20 countries in the Country table. Exclude any
countries with NULL values in the GNP or GNPOld columns.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT Name, (GNP - GNPOld) AS GNPdiff
-> FROM world.Country
-> WHERE GNP IS NOT NULL
-> AND GNPOld IS NOT NULL
-> LIMIT 20;
ble
+----------------------+-----------+
fe r a
| Name | GNPdiff |
ans
+----------------------+-----------+
| Aruba | 35.00 | n - t r
o
| Angola
| Albania
| -1336.00 |
| 705.00 | s an
| United Arab Emirates | 1120.00 |
r ) ha ฺ
| Argentina | 16928.00 |
m ฺb uide
ฺco nt G
| Armenia | 186.00 |
| Antigua and Barbuda | 28.00 |
a r
| Australia
| Austria |
o ep tude
| -41729.00 |
n
5835.00 |
| Azerbaijan |
@ s is S
27.00 |
c c i th
| Burundi
r i | -79.00 |
e
| Belgium
| Benin
e r toฺ to us|
|
5756.00 |
216.00 |

i ( rob ense
| Burkina Faso | 224.00 |
c lic
| Bangladesh | 886.00 |

to Ric| Bulgaria | 2009.00 |

e r | Bahrain | 269.00 |

ob
| Bahamas | 180.00 |
R | Belize
| Bermuda
|
|
14.00 |
138.00 |
+----------------------+-----------+
20 rows in set (#.## sec)
10. Modify the statement in the preceding step to display the absolute value of the difference
between current and old gross national product values.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT Name, ABS((GNP - GNPOld)) AS GNPdiff
-> FROM world.Country
-> WHERE GNP IS NOT NULL
-> AND GNPOld IS NOT NULL
-> LIMIT 20;
+----------------------+----------+
| Name | GNPdiff |
+----------------------+----------+
| Aruba | 35.00 |
| Angola | 1336.00 |
| Albania | 705.00 |
| United Arab Emirates | 1120.00 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 6
| Argentina | 16928.00 |
| Armenia | 186.00 |
| Antigua and Barbuda | 28.00 |
| Australia | 41729.00 |
| Austria | 5835.00 |
| Azerbaijan | 27.00 |
| Burundi | 79.00 |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Belgium | 5756.00 |
| Benin | 216.00 |
| Burkina Faso | 224.00 |
| Bangladesh | 886.00 |
| Bulgaria | 2009.00 |
| Bahrain | 269.00 |
| Bahamas | 180.00 |
| Belize | 14.00 |
| Bermuda | 138.00 |
+----------------------+----------+ ble
20 rows in set (#.## sec)
fe r a
11. Modify the statement in the preceding step to remove the decimal part of the difference in ans
gross national product values, without affecting the integer part. n - t r
a no
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT Name, TRUNCATE(ABS((GNP - GNPOld)),0) h a sAS GNPdiff
-> FROM world.Country
ฺ b r) deฺ
-> WHERE GNP IS NOT NULL
c o m Gui
-> AND GNPOld IS NOT NULL
-> LIMIT 20; p a rฺ ent
+----------------------+---------+
|s one s|Stud
i@ thi
| Name GNPdiff

r i c c
+----------------------+---------+
| se 35 |
| Aruba
r t o ฺ u
| Angola
b e e to || 1336 |
| Albania
i ( ro ArabenEmirates
s 705 |
c
| United
lic
| 1120 |

to Ri||c Argentina
Armenia
|
|
16928 |
186 |
e r
ob
| Antigua and Barbuda | 28 |
R | Australia
| Austria
|
|
41729 |
5835 |
| Azerbaijan | 27 |
| Burundi | 79 |
| Belgium | 5756 |
| Benin | 216 |
| Burkina Faso | 224 |
| Bangladesh | 886 |
| Bulgaria | 2009 |
| Bahrain | 269 |
| Bahamas | 180 |
| Belize | 14 |
| Bermuda | 138 |
+----------------------+---------+
20 rows in set (#.## sec)
12. Keep the Linux terminal window open and logged into the mysql client for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 7
Practice 9-2: Using Temporal Data in SQL Expressions
Overview
In this practice, you use temporal data in a variety of SQL expressions.
Note: The output of the SQL commands you execute in the step will vary according to the
date and time they are executed.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a Linux terminal prompt open and are logged into the mysql client from the previous
practice.

Duration
This practice should take you approximately ten minutes to complete.
ble
Tasks fe r a
1. Display the current date (default format) with the column title TODAY. ans
n - t r
2. Display the date that is 21 days from today. o
3. an
Show the current date/time, and the date/time in exactly five hours from now.
s
4. ha ฺ
Show the date and time in ten years from the current date and time. Use the default format
r )
to display the result.
m ฺb uide
5.
a r ฺco nt G
Display the current date and in the format “Today is {day} the {date} of {month}, {year}. For
example: “Today is Friday the 13th of November, 2015.”
6. o n ep tude
Exit the mysql client and close the Linux terminal window.
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 8
Solution 9-2: Using Temporal Data in SQL Expressions
Solution Steps
1. Display the current date (default format) with the column title TODAY.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT CURDATE() AS TODAY;


+------------+
| TODAY |
+------------+
| 2016-05-16 |
+------------+
1 row in set (#.## sec)
2. Display the date that is 21 days from today.
Enter the following statement at the mysql prompt and receive the results shown: ble
fe r a
mysql> SELECT CURDATE() + INTERVAL 21 DAY;
+-----------------------------+
ans
| CURDATE() + INTERVAL 21 DAY |
n - t r
+-----------------------------+
a no
| 2016-06-06 |
+-----------------------------+
h a s
1 row in set (#.## sec)
ฺ b r) deฺ
o
3. Show the current date/time, and the date/time in exactly m five G u i from now.
hours
Enter the following statement at the mysql prompta c
rฺ andereceive
n t the results shown:
mysql> SELECT NOW(), NOW()o+nINTERVAL
p
e tu5dHOUR AS 'In 5 hours';
s i s S
i @
+---------------------+---------------------+
h
| NOW()
ฺ r i cc | Inse5 thours |

| 2016-05-16 e r o to |u2016-05-16 19:32:45 |


t14:32:45
+---------------------+---------------------+
b
nse sec)
(rino setce(#.##
+---------------------+---------------------+
1c i
R
4. Show
row
li time in ten years from the current date and time. Use the default format
icthe date and
bertoto display the result.
Ro Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT NOW(), NOW() + INTERVAL 10 YEAR AS 'In 10 years';
+---------------------+---------------------+
| NOW() | In 10 years |
+---------------------+---------------------+
| 2016-05-16 14:33:28 | 2026-05-16 14:33:28 |
+---------------------+---------------------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 9
5. Display the current date and in the format “Today is {day} the {date} of {month}, {year}. For
example: “Today is Friday the 13th of November, 2015.”
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT NOW(), DATE_FORMAT(NOW(),
-> 'Today is %W the %d of %M, %Y')
-> AS Today;
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+---------------------+-------------------------------------+
| NOW() | Today |
+---------------------+-------------------------------------+
| 2016-05-16 14:34:21 | Today is Monday the 16 of May, 2016 |
+---------------------+-------------------------------------+
1 row in set (#.## sec)
6. Exit the mysql client and close the Linux terminal window.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 9: Working with Numeric and Temporal Data


Chapter 9 - Page 10
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 10:
Subqueriesom t Gu i
r ฺ c
a 10den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 1
Practices for Lesson 10: Subqueries
Practices Overview
These practices test your knowledge of working with subqueries. They assume that you are
using the Linux operating system environment provided in Oracle classrooms. For non-Oracle
classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The sakila sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 2
Practice 10-1: Quiz – Subqueries
Overview
In this practice, you answer questions about subqueries.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 10 minutes to complete.

Questions
1. Where in a SQL statement can you place a scalar subquery?
2. The following query selects those continents that have countries in which more than 50% of
the population speak English. Is this an example of using a correlated subquery? Why or
why not?
ble
SELECT DISTINCT Continent FROM Country
fe r a
WHERE Code IN (
ans
SELECT CountryCode FROM CountryLanguage
WHERE Language='English' AND Percentage > 50
n - t r
);
a no
3. The following statement uses a correlated subquery to find the names
h a s of customers who
have made a payment of more than 11 currency units.
ฺ b r) deฺ
SELECT first_name, last_name FROM customer
c o m Gui
WHERE EXISTS(
p a rฺ ent
one s Stud
SELECT * FROM payment
WHERE amount > 11
s
);
c c i@ thi
AND customer_id = customer.customer_id

o ฺ i se subquery becomes a noncorrelated subquery.


r that theucorrelated
Rewrite the statement
r t so
eoperator o this.
tachieve
b
Hint: Use theoIN e to
i (r You
4. True orcFalse? c e nsuse the equality comparison operator (=) in the WHERE clause to
R ic an operand
compare
li with any type of subquery result.
can

e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 3
Solution 10-1: Quiz–Subqueries
Answers
1. Where in a SQL statement can you place a scalar subquery?
Answer: You can place a scalar subquery wherever you can put a single value in a
statement—for example, as part of an expression in the WHERE clause, as a value or part of
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

an expression in the SELECT clause, or wherever a single value expression is allowed.


2. The following query selects those continents that have countries in which more than 50% of
the population speak English. Is this an example of using a correlated subquery? Why or
why not?
SELECT DISTINCT country FROM country
WHERE country_id IN (
SELECT country_id FROM city
WHERE city = 'London'
ble
);
fe r a
Answer: This is not an example of a correlated subquery because all the columns referred ans
to in the subquery come from tables in the subquery’s FROM clause. There is no n - t r
dependency on other tables referenced by the outer query.
a no
3. a s
The following statement uses a correlated subquery to find the names of customers who
h
have made a payment of more than 11 currency units.
ฺ b r) deฺ
SELECT first_name, last_name FROM customer
c o m Gui
WHERE EXISTS(
p a rฺ ent
ne Stud
SELECT * FROM payment
WHERE amount > 11
s o
i @ this
AND customer_id = customer.customer_id
c
);
ฺ c
rithat se subquery becomes a noncorrelated subquery.
r
Rewrite the statementt oso o u
the correlated
tachieve
b e e
i ( ro ens
Hint: Use the IN operator to this.

icc The following


Answer:
R
subquery:
lic is a version of the code in the question rewritten as a noncorrelated
berto SELECT first_name, last_name FROM customer
Ro WHERE customer_id IN(
SELECT customer_id FROM payment
WHERE amount > 11
);
4. True or False? You can use the equality comparison operator (=) in the WHERE clause to
compare an operand with any type of subquery result.
Answer: True, although if a subquery returns a table, you must quantify the equality with
ANY, ALL, or SOME.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 4
Practice 10-2: Using Subqueries in the SELECT and FROM Clauses

Overview
In this practice, you place subqueries in the SELECT column designation and in the FROM clause
of a statement.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 10 minutes to complete.

Tasks
1. Log in to the mysql command-line client in a Linux terminal window.
2. In the sakila database, create and execute a correlated subquery that displays the name
and the number of cities of all countries beginning with the letter “V”. e
Hint: Use the city and country tables in the sakila database to achieve this. r a bl
s fe
3. Create a noncorrelated subquery that calculates the average total payments per customer.
- t r an
Hint: This information is available in the payment table of the sakila database. The total
on
an
payment per customer is an aggregate, and its average is another aggregate.
s
4.
ha ฺ
Keep the mysql command-line client open for the next practice.
r )
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 5
Solution 10-2: Using Subqueries in the SELECT and FROM Clauses

Solution Steps
1. Log in to the mysql command-line client in a Linux terminal window.
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
2. In the sakila database, create and execute a correlated subquery that displays the name
and the number of cities of all countries beginning with the letter “V”.
Hint: Use the city and country tables in the sakila database to achieve this.
ble
Enter the following commands at the Linux terminal prompt and receive the results shown:
fe r a
mysql> USE sakila
ans
Reading table information ...
n - t r
o
an
Database changed

mysql> SELECT country, ( s


ha ฺ
-> SELECT COUNT(*) FROM city
r )
ฺb uide
->
m
WHERE country_id = country.country_id
-> ) AS `cities`
a r ฺco nt G
ep tude
-> FROM country
-> WHERE country LIKE 'v%';
+----------------------+--------+ o n
s is| S
| country
c i @ th
| cities
r i c e
| Venezuela toฺ u| s 7 |
+----------------------+--------+

| Vietnamb e r t o
( r o n s eU.S. || 6 |

c i
| Virgin
e
Islands,
c
1 |

Ri3c rows inliset (#.## sec)


+----------------------+--------+

e r toCreate a noncorrelated subquery that calculates the average total payments per customer.
R ob 3.
Hint: This information is available in the payment table of the sakila database. The total
payment per customer is an aggregate, and its average is another aggregate.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT AVG(totals) FROM (
-> SELECT SUM(amount) AS totals
-> FROM payment GROUP BY customer_id
-> ) AS temp;
+-------------+
| AVG(totals) |
+-------------+
| 112.548431 |
+-------------+
1 row in set (#.## sec)
4. Keep the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 6
Practice 10-3: Using Subqueries in the WHERE Clause

Overview
In this practice, you place subqueries in the WHERE clause.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 10 minutes to complete.

Tasks
1. Using the sakila database, perform a query by using a subquery that retrieves the
customer ID for all customers who have made a payment equal to the value of the largest
payment.
Hint: This information is available in the payment table. e
2. Perform a query by using a subquery that retrieves the first name and last name of all r a bl
customers who are marked as inactive, but have rented items. s fe
Hint: This information is available in the customer and rental tables. Inactive customers - t r an
on
an
have a zero value in the customer table’s active column.
3. Keep the mysql command-line client open for the next practice. as
r ) h ฺ
m b
ฺ uide
r o
ฺc nt G
a
ep tude
o n
s is S
c i @ th
r i c e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 7
Solution 10-3: Using Subqueries in the WHERE Clause

Solution Steps
1. Using the sakila database, perform a query by using a subquery that retrieves the
customer ID for all customers who have made a payment equal to the value of the largest
payment.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Hint: This information is available in the payment table.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT customer_id FROM payment
-> WHERE amount = (
-> SELECT MAX(amount) FROM payment
-> );
+-------------+
| customer_id |
ble
+-------------+
fe r a
| 13 |
ans
| 116 |
n - t r
no
| 195 |
| 196 |
s a
| 204 |
h a
| 237 |
ฺ b r) deฺ
m Gui
| 305 |
| 362 |
c o
rฺ ent
| 591 |
p a
one s Stud
| 592 |
+-------------+
s
10 rows in set (#.## sec)
c c i@ thi
2. Perform a query by using
o ฺ i
r a subquery
u s ethat retrieves the first name and last name of all
e t
customers who arermarked as toinactive, but have rented items.
b e
ro enissavailable in the customer and rental tables. Inactive customers
Hint: This (information
c i licin the customer table’s active column.
R ic value
have a zero

erto
Enter the following statement at the mysql prompt and receive the results shown:
b
Ro
mysql> SELECT first_name, last_name
-> FROM customer WHERE active=0
-> AND customer_id IN (
-> SELECT customer_id FROM rental
-> );
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| SANDRA | MARTIN |
| JUDITH | COX |
| SHEILA | WELLS |
| ERICA | MATTHEWS |
| HEIDI | LARSON |
| PENNY | NEAL |
| KENNETH | GOODEN |
| HARRY | ARCE |
| NATHAN | RUNYON |
| THEODORE | CULP |
| MAURICE | CRAWLEY |
| BEN | EASTER |
| CHRISTIAN | JUNG |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 8
| JIMMIE | EGGLESTON |
| TERRANCE | ROUSH |
+------------+-----------+
15 rows in set (#.## sec)
3. Keep the mysql command-line client open for the next practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 9
Practice 10-4: Additional Practice
Overview
In this practice, you use more in-depth queries to test your knowledge of subqueries.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately 15 minutes to complete.

Tasks
1. Perform a query by using a subquery that retrieves the ID of every customer who has
returned more than five rentals within 24 hours.
Hint: This information is available in the rental table.
2. Without using any table joins, create a multilevel subquery that shows the first name and e
last name of each actor in the shortest films in the database.
r a bl
Hint: First, find the shortest film in the film table. Then find all films of that length, before s fe
using the actor and film_actor tables to identify the actors who acted in those films. - t r an
on
an
3. Exit the MySQL server and close the Linux terminal prompt.
s
ha ฺ
r )
ฺb uide
m
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 10
Solution 10-4: Additional Practice
Solution Steps
1. Perform a query by using a subquery that retrieves the ID of every customer who has
returned more than five rentals within 24 hours.
Hint: This information is available in the rental table.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT customer_id, COUNT(*)
-> FROM (
-> SELECT customer_id, rental_date, return_date
-> FROM rental
-> WHERE return_date < rental_date + INTERVAL 24 HOUR
-> ) AS t
-> GROUP BY customer_id
ble
-> HAVING COUNT(*) >= 5;
fe r a
+-------------+----------+
ans
| customer_id | count(*) |
+-------------+----------+
n - t r
| 28 | 5 |
a no
|
|
84 |
87 |
6 |
5 | h a s
| 131 | 5 |
ฺ b r) deฺ
| 167 | 6 |
c o m Gui
| 196 | 5 |
p a rฺ ent
one s Stud
| 228 | 5 |
| 374 | 6 |
s
|
|
565 |
592 |
5 |
c
5 |c i@ thi
o ฺ r i
+-------------+----------+
u se
e r t
10 rows in set (#.## sec) to
b
roany table e
c i (
2. Without using
c e nsjoins, create a multilevel subquery that shows the first name and
c of each
last iname
R li actor in the shortest films in the database.
erto
Hint: First, find the shortest film in the film table. Then find all films of that length, before
b using the actor and film_actor tables to identify the actors who acted in those films.
Ro Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT first_name, last_name
-> FROM actor WHERE actor_id IN (
-> SELECT DISTINCT actor_id
-> FROM film_actor WHERE film_id IN (
-> SELECT film_id FROM film
-> WHERE length = (
-> SELECT MIN(length)
-> FROM film
-> )
-> )
-> );
+------------+--------------+
| first_name | last_name |
+------------+--------------+
| JOHNNY | LOLLOBRIGIDA |
| HELEN | VOIGHT |
| BURT | DUKAKIS |
| TOM | MIRANDA |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 11
| ANNE | CRONYN |
| NATALIE | HOPKINS |
| RAY | JOHANSSON |
| KENNETH | PALTROW |
| MICHELLE | MCCONAUGHEY |
| GROUCHO | SINATRA |
| SCARLETT | DAMON |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| KIRSTEN | AKROYD |
| SIDNEY | CROWE |
| GROUCHO | DUNST |
| RENEE | TRACY |
| JULIANNE | DENCH |
| FRANCES | TOMEI |
| WHOOPI | HURT |
| JADA | RYDER |
| ANGELA | WITHERSPOON |
| FAY | WOOD | ble
| CHRIS | DEPP |
fe r a
| HARVEY | HOPE |
ans
| HUMPHREY | WILLIS |
n - t r
| KENNETH | HOFFMAN | o
| MENA | HOPPER |
s an
| MICHAEL
| JULIA
| BOLGER
| FAWCETT
|
|
r ) ha ฺ
+------------+--------------+
m ฺb uide
28 rows in set (#.## sec)
a r ฺ co nt G
3. Exit the MySQL server and close the Linuxp
e
a. Enter the following at the mysqloclient: Stu
n de
terminal prompt.

@ s is
mysql> EXIT
c c i th
r i e
toฺ to us
Bye
#
b e r
rofollowing
b. Enter (the n e
scommand at the Linux terminal prompt
c i c e
R i#c exit li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 10: Subqueries


Chapter 10 - Page 12
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 11:
Modifying om tTablei
u Data
r ฺ c
a 11den G
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 1
Practices for Lesson 11: Modifying Table Data
Practices Overview
These practices test your knowledge of modifying table data. They assume that you are using
the Linux operating system environment provided in Oracle classrooms. For non-Oracle
classrooms, you might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The sakila sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 2
Practice 11-1: Adding New Data to Tables
Overview
In this practice, you create a new table in a new database and use the INSERT statement to
add data to it.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately five minutes to complete.

Solution Steps
1. Log in to the mysql command-line client and create a new database called dbtest.
2. In the dbtest database, create a table called numbers by issuing the following statement:
CREATE TABLE numbers (n SMALLINT UNSIGNED);
ble
3. Insert the value 5 into the numbers table, and then query the table to confirm the insertion. fe r a
n s
n - t ra
4. Insert the value 5 + 20 into the table, and then query the table to confirm the insertion.
o insertion.
5. Insert the value 1.23e4 into the table, and then query the table to confirm the
n
6. Insert the value POW(5,5) into the table, and then query the table to a
s confirm the insertion.
h a
ฺ b r) dcommand-line
7. Keep the Linux terminal window open and connected to the mysql
e ฺ client for
the next practice.
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 3
Solution 11-1: Adding New Data to Tables
Solution Steps
1. Log in to the mysql command-line client and create a new database called dbtest.
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE DATABASE dbtest;
Query OK, 1 row affected (#.## sec)
ble
2. In the dbtest database, create a table called numbers by issuing the following statement:
fe r a
CREATE TABLE numbers (n SMALLINT UNSIGNED);
ans
n - t r
no
Enter the following statements at the mysql prompt and receive the results shown:
a
mysql> USE dbtest;
h a s
Database changed
ฺ b r) deฺ
Query OK, 0 rows affected (#.## sec) om
mysql> CREATE TABLE numbers (n SMALLINT UNSIGNED);
u i
a ฺ c
rthen n G
tthe table to confirm the insertion.
p
3. Insert the value 5 into the numbers table, and e
query
s
Enter the following statements at the
ne prompt
omysql S tudand receive the results shown:
c i @ VALUES
t h is (5);
ric us(#.##e sec)
mysql> INSERT INTO numbers
Query OK, 1 row ฺaffected
t o
er * FROM tonumbers;
mysql> o b e
c i (r cens
SELECT

i|c n | li
+------+
R
erto | 5 |
+------+
b
Ro +------+
1 row in set (#.## sec)
4. Insert the value 5 + 20 into the table, and then query the table to confirm the insertion.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> INSERT INTO numbers VALUES (5+20);
Query OK, 1 row affected (#.## sec)

mysql> SELECT * FROM numbers;


+------+
| n |
+------+
| 5 |
| 25 |
+------+
2 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 4
5. Insert the value 1.23e4 into the table, and then query the table to confirm the insertion.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> INSERT INTO numbers VALUES (1.23e4);
Query OK, 1 row affected (#.## sec)

mysql> SELECT * FROM numbers;


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+-------+
| n |
+-------+
| 5 |
| 25 |
| 12300 |
+-------+
3 rows in set (#.## sec)
6. Insert the value POW(5,5) into the table, and then query the table to confirm the insertion.
ble
Enter the following statements at the mysql prompt and receive the results shown:
fe r a
ans
mysql> INSERT INTO numbers VALUES (POW(5,5));
Query OK, 1 row affected (#.## sec)
n - t r
a no
mysql> SELECT * FROM numbers;
+-------+ h a s
| n |
ฺ b r) deฺ
+-------+
c o m Gui
|
|
5 |
25 | p a rฺ ent
| 12300 |
s one s Stud
i@ thi
| 3125 |
+-------+
i c c
o ฺ r
4 rows in set (#.## sec)
t u se
e r window
7. Keep the Linuxbterminal to open and connected to the mysql command-line client for
(ro cens
the next ipractice.
e
ic c li
R
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 5
Practice 11-2: Deleting Data from Tables
Overview
In this practice, you use the DELETE statement to remove data from a copy of a table in the
sakila database.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately five minutes to complete.

Tasks
1. In the sakila database, create a copy of the actor table called actor_copy.
2. Delete the actor with ID 140 from the actor_copy table, and then issue a suitable query
to confirm the deletion. e
3. Delete all actors with the last name “Kilmer” from the actor_copy table. r a bl
s fe
4. Using a single query on the actor_copy table, sort the actors by first name in reverse
alphabetical order and display the full names of the five actors whose first names appear at - t r an
the end of the alphabet. no n
s a
Hint: The first name of the final actor sorted alphabetically is “Zero.”
h a
5. r) deฺ
Delete the row in the actor_copy table containing the actor named “Zero” without
ฺ b
c o m Gui
specifying Zero’s first name, last name, or ID in the statement. Reissue the query in the
preceding step to confirm the deletion.
p a rฺ ent
6. Keep the Linux terminal window opens oand S tudto the mysql command-line client for
neconnected
Enter the following statements at the mysql prompt and receive the results shown:

the next practice. c i @ this


t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 6
Solution 11-2: Deleting Data from Tables
Solution Steps
1. In the sakila database, create a copy of the actor table called actor_copy.
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> USE sakila


Reading table information ...
Database changed

mysql> CREATE TABLE actor_copy LIKE actor;


Query OK, 0 rows affected (#.## sec)

mysql> INSERT INTO actor_copy SELECT * FROM actor;


Query OK, 200 rows affected (#.## sec)
Records: 200 Duplicates: 0 Warnings: 0 ble
fe r a
2. Delete the actor with ID 140 from the actor_copy table, and then issue a suitable query
n s
to confirm the deletion.
n - tra
Enter the following statements at the mysql prompt and receive the resultso shown:
mysql> DELETE FROM actor_copy WHERE actor_id = 140;s a n
Query OK, 1 row affected (0.07 sec)
r ) ha ฺ
m ฺb =u140;ide
mysql> SELECT * FROM actor_copy WHERE actor_id
r o
ฺc nt G
Empty set (0.07 sec)
− The actor record with an ID of 140
a
eispno longer dein the table.
o n t u
S the actor_copy table.
3. Delete all actors with the last names“Kilmer”sfrom
i @ h i
t prompt and receive the results shown:
Enter the following statement
ฺ r i ccat thesmysql
e
r t o u
toFROM actor_copy
mysql> DELETE
o b e e
WHERE last_name = 'Kilmer';
Query OK,
( r 5 rows
n s affected (0.07 sec)
4. Using
i c ca isingle query
l i ceon the actor_copy table, sort the actors by first name in reverse
t o R
alphabetical order and display the full names of the five actors whose first names appear at
b r
e the end of the alphabet.
Ro Hint: The first name of the final actor sorted alphabetically is “Zero.”
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT first_name, last_name FROM actor_copy
-> ORDER BY first_name DESC LIMIT 5;
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| ZERO | CAGE |
| WOODY | HOFFMAN |
| WOODY | JOLIE |
| WILLIAM | HACKMAN |
| WILL | WILSON |
+------------+-----------+
5 rows in set (0.01 sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 7
5. Delete the row in the actor_copy table containing the actor named “Zero” without
specifying Zero’s first name, last name, or ID in the statement. Reissue the query in the
preceding step to confirm the deletion.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> DELETE FROM actor_copy ORDER BY first_name DESC LIMIT 1;
Query OK, 1 row affected (0.01 sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT first_name, last_name FROM actor_copy


-> ORDER BY first_name DESC LIMIT 5;
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| WOODY | HOFFMAN |
| WOODY | JOLIE |
| WILLIAM | HACKMAN |
ble
| WILL
| WARREN
| WILSON
| NOLTE
|
|
fe r a
+------------+-----------+
ans
5 rows in set (0.00 sec)
n - t r
o
6.
an
Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice. s
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 8
Practice 11-3: Updating Table Data
Overview
In this practice, you use the UPDATE statement to make changes to the actor_copy table that
you created in the preceding practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately ten minutes to complete.

Tasks
1. Using the actor_copy table, change all occurrences of the first name “PENELOPE” to
“Penelope.” Issue a suitable query to verify the name change.
2. Use the LOWER() function to set all occurrences of the first name “KENNETH” to “kenneth”
for all actors. Issue a suitable query to verify the name change. ble
fe r a
3. Set the value of the SQL_SAFE_UPDATES variable to 1.
ans
Note: For beginners, a useful startup option is --safe-updates (or --i-am-a-dummy,
n - t r
no
which has the same effect). It is helpful for cases when you might have issued a DELETE
a
h a s
FROM tbl_name statement but forgotten the WHERE clause. Normally, such a statement
deletes all rows from the table. With --safe-updates, you can delete rows only by
ฺ b r) deฺ
specifying the key values that identify them. This helps to prevent accidental deletion of
data. c o m Gui
4. p a rฺ ent
Attempt to set all occurrences of the first name “JULIA” to “Julia” for all actors. Why did you
receive an error?
s one s Stud
5. i@ thi
Change the first name of the actor with ID 199 from “JULIA” to “Julia.” Issue a suitable
c c
r i se
query to verify the change. Why is there no error on this occasion?
o ฺ u
6. e r t to
Set the SQL_SAFE_UPDATES option to 0.
b e
c i (ro terminal
7. Keep the Linux
c e nswindow open and connected to the mysql command-line client for
c practice.li
the inext
R
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 9
Solution 11-3: Updating Table Data
Solution Steps
1. Using the actor_copy table, change all occurrences of the first name “PENELOPE” to
“Penelope.” Issue a suitable query to verify the name change.
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> UPDATE actor_copy SET first_name='Penelope'


-> WHERE first_name='PENELOPE';
Query OK, 4 rows affected (0.04 sec)
Rows matched: 4 Changed: 4 Warnings: 0

mysql> SELECT * FROM actor_copy WHERE first_name = 'Penelope';


+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
ble
+----------+------------+-----------+---------------------+
| 1 | Penelope | GUINESS | 2013-08-22 10:06:04 |
fe r a
| 54 | Penelope | PINKETT | 2013-08-22 10:06:04 |
ans
| 104 | Penelope | CRONYN | 2013-08-22 10:06:04 |
n - t r
| 120 | Penelope | MONROE | 2013-08-22 10:06:04 |
+----------+------------+-----------+---------------------+ a no
4 rows in set (0.01 sec)
h a s
2. Use the LOWER() function to set all occurrences of the first ฺ b ) “KENNETH”
rname e ฺ to “kenneth”
m u i d
a
Enter the following statements at the mysql prompt r ฺcoandnreceive
for all actors. Issue a suitable query to verify the name change.
t G the results shown:
o n ep tud=e LOWER(first_name)
mysql> UPDATE actor_copy SET
=s'Kenneth';
S
first_name
i s
-> WHERE first_name
i @ h
t sec)
Rows matched: o
icc use(0.04
Query OK, 4 rows affected
4 ฺrChanged:
e r t 4 Warnings: 0
toactor_copy WHERE first_name = 'Kenneth';
mysql>ro b * sFROM e
i ( licen
SELECT
c c
+----------+------------+-----------+---------------------+
i| actor_id | first_name | last_name | last_update
o R |

b e rt +----------+------------+-----------+---------------------+

R o |
|
69 | kenneth
88 | kenneth
| PALTROW
| PESCI
| 2013-08-22 10:07:49 |
| 2013-08-22 10:07:49 |
| 94 | kenneth | TORN | 2013-08-22 10:07:49 |
| 169 | kenneth | HOFFMAN | 2013-08-22 10:07:49 |
+----------+------------+-----------+---------------------+
4 rows in set (0.00 sec)
3. Set the value of the SQL_SAFE_UPDATES variable to 1.
Note: For beginners, a useful startup option is --safe-updates (or --i-am-a-dummy,
which has the same effect). It is helpful for cases when you might have issued a DELETE
FROM tbl_name statement but forgotten the WHERE clause. Normally, such a statement
deletes all rows from the table. With --safe-updates, you can delete rows only by
specifying the key values that identify them. This helps to prevent accidental deletion of
data.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SET SQL_SAFE_UPDATES=1;
Query OK, 0 rows affected (0.00 sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 10
4. Attempt to set all occurrences of the first name “JULIA” to “Julia” for all actors. Why did you
receive an error?
Enter the following statement at the mysql prompt and receive the results shown:
mysql> UPDATE actor_copy SET first_name='Julia'
-> WHERE first_name='JULIA';
ERROR 1175 (HY000): You are using safe update mode and you tried to
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

update a table without a WHERE that uses a KEY column


− The SQL_SAFE_UPDATES option prevents row modifications, such as updates, that
do not specify the key values of those rows.
5. Change the first name of the actor with ID 199 from “JULIA” to “Julia.” Issue a suitable
query to verify the change. Why is there no error on this occasion?
Enter the following statements at the mysql prompt and receive the results shown:
mysql> UPDATE actor_copy SET first_name='Julia'
-> WHERE actor_id=199; ble
Query OK, 1 row affected (0.05 sec)
fe r a
Rows matched: 1 Changed: 1 Warnings: 0
ans
n - t r
mysql> SELECT * FROM actor_copy WHERE actor_id = 199;
+----------+------------+-----------+---------------------+ a no
| actor_id | first_name | last_name | last_update |
h a s
ฺ b r) deฺ
+----------+------------+-----------+---------------------+
| 199 | Julia | FAWCETT
m Gui
| 2016-05-16 14:50:10 |
c o
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
p a rฺ ent
− The SQL_SAFE_UPDATES option
s o neallowsSrow
t udmodifications that identify the row with
a key value.
c i @ t h is
6. Set the SQL_SAFE_UPDATES
t o ฺ ric option
u s eto 0.
Enter the following rstatementto at the mysql prompt and receive the results shown:
mysql>ro
b e e
c i ( OK, c e ns affected (0.00 sec)
SET SQL_SAFE_UPDATES=0;

R ic
Query
li
0 rows
7. oKeep the Linux terminal window open and connected to the mysql command-line client for
bert the next practice.
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 11
Practice 11-4: Replacing Table Data
Overview
In this practice, you use the REPLACE statement to replace existing table rows and add new
rows.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately ten minutes to complete.

Tasks
1. Using a REPLACE statement, add the new actor “John Johnson” to the actor_copy table
with an ID of 250. Verify the addition with a suitable query.
2. Use a REPLACE statement to replace the actor added in the preceding step with one named
ble
“Pete Peterson.” Verify the change with a suitable query.
fe r a
3. Keep the Linux terminal window open and connected to the mysql command-line client for
ans
the next practice.
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 12
Solution 11-4: Replacing Table Data
Solution Steps
1. Using a REPLACE statement, add the new actor “John Johnson” to the actor_copy table
with an ID of 250. Verify the addition with a suitable query.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT * FROM actor_copy WHERE actor_id > 200;
Empty set (0.00 sec)

mysql> REPLACE INTO actor_copy(actor_id, first_name, last_name)


-> VALUES (250, 'John', 'Johnson');
Query OK, 1 row affected (0.04 sec)

mysql> SELECT * FROM actor_copy WHERE actor_id > 200;


ble
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update | fe r a
+----------+------------+-----------+---------------------+
ans
| 250 | John | Johnson | 2016-05-16 14:51:47 |
n - t r
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec) a no
− There is no existing record with the specified key, so this h a s operation is
effectively the same as an INSERT. Note how only ฺ b ) REPLACE
arsingle row
e ฺ is affected.
omin thet G i d
u step with one named
2. Use a REPLACE statement to replace the actor added
r ฺ c
a query. n
preceding
p
“Pete Peterson.” Verify the change with a suitable
e d e
Enter the following statements at theo
s n prompt
mysql S tu and receive the results shown:
i@ thi
mysql> REPLACE INTO cactor_copy(actor_id, s first_name, last_name)
r i c e
Query OK, 2 rrows toฺ affected
-> VALUES (250,
t o us (0.05 sec)
'Pete', 'Peterson');

b e e
i
mysql> ( roSELECTe * sFROM actor_copy WHERE actor_id > 200;
n
R cc lic
i+----------+------------+-----------+---------------------+
erto +----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
b
Ro | 250 | Pete | Peterson | 2016-05-16 14:52:32 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
− In this instance, the row with this ID already exists, so REPLACE performs an
UPDATE. The update affects two rows. (The original is removed and the new row is
inserted.)
3. Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 13
Practice 11-5: Avoiding Data Insertion Errors
Overview
In this practice, you build and populate a user login table in the dbtest database. You avoid
data insertion errors by using REPLACE and the ON DUPLICATE KEY UPDATE clause to
replace values.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 15 minutes to complete.

Tasks
1. In the dbtest database, create a table called current_users to represent users who are
currently logged in. Use the following CREATE TABLE statement:
ble
CREATE TABLE current_users (
fe r a
userid INT UNSIGNED,
ans
username VARCHAR(100),
login_time TIMESTAMP,
n - t r
visits INT UNSIGNED DEFAULT 1,
a no
);
PRIMARY KEY (userid)
h a s
2. Enter the following statement to simulate a user logging ฺin: b r) deฺ
c o m Gui
INSERT INTO current_users (userid, username)
p a rฺ ent
tud
VALUES (100, 'Tobias');
e the results.
onnote
3. Query the current_users table and s is S
4. Reissue the preceding INSERT c i @ t
statement hto simulate the user attempting to log in a second
time.
t o ฺ ric use
b e r INSERTtostatement so that it performs a REPLACE instead, and verify
5. Modify the preceding
(
that it works
i n se query.
rowith a esuitable
icc the userliclogging in again with the following SQL statement:
6. Simulate
R
berto INSERT INTO current_users (userid, username)
Ro
VALUES (100, 'Tobias')
ON DUPLICATE KEY UPDATE visits=visits+1;
7. Execute a suitable query to verify any differences in behavior between the preceding
INSERT statement and the earlier REPLACE statement.
8. Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 14
Solution 11-5: Avoiding Data Insertion Errors
Solution Steps
1. In the dbtest database, create a table called current_users to represent users who are
currently logged in. Use the following CREATE TABLE statement:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

CREATE TABLE current_users (


userid INT UNSIGNED,
username VARCHAR(100),
login_time TIMESTAMP,
visits INT UNSIGNED DEFAULT 1,
PRIMARY KEY (userid)
);
Enter the following statements at the mysql prompt and receive the results shown:
mysql> USE dbtest
ble
Reading table information ...
fe r a
ans
Database changed
n - t r
no
mysql> CREATE TABLE current_users (
-> userid INT UNSIGNED,
s a
-> username VARCHAR(100),
h a
->
->
login_time TIMESTAMP,
visits INT UNSIGNED DEFAULT 1, ฺ b r) deฺ
-> PRIMARY KEY (userid)
c o m Gui
-> );
p a rฺ ent
onea user tud in.
Query OK, 0 rows affected (0.20 sec)
s
2. Enter the following statement to simulate S logging
is username)
c i @ (userid,
t h
INSERT INTO current_users
t o
VALUES (100, 'Tobias');ฺ ric use
b e rstatementtoat the mysql prompt and receive the results shown:
i ( o
Enter the following
r e n se
R cc -> INSERT
imysql> lic INTO current_users (userid, username)
VALUES (100, 'Tobias');

berto Query OK, 1 row affected (0.04 sec)


Ro 3. Query the current_users table and note the results.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM current_users;
+--------+----------+---------------------+--------+
| userid | username | login_time | visits |
+--------+----------+---------------------+--------+
| 100 | Tobias | 2016-05-16 14:53:42 | 1 |
+--------+----------+---------------------+--------+
1 row in set (0.00 sec)
− The output shows one active login for the user “Tobias,” including the time he
logged on.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 15
4. Reissue the preceding INSERT statement to simulate the user attempting to log in a second
time.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> INSERT INTO current_users (userid, username)
-> VALUES (100, 'Tobias');
ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY'
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

− You cannot insert a second row with the same primary key value as before. This
supports the idea that a user cannot log in more than once.
5. Modify the preceding INSERT statement so that it performs a REPLACE instead, and verify
that it works with a suitable query.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> REPLACE INTO current_users (userid, username)
-> VALUES (100, 'Tobias');
Query OK, 2 rows affected (0.00 sec) ble
fe r a
mysql> SELECT * FROM current_users;
ans
+--------+----------+---------------------+--------+
n - t r
| userid | username | login_time | visits |
+--------+----------+---------------------+--------+ a no
| 100 | Tobias | 2016-05-16 14:54:39 | 1 |
h a s
+--------+----------+---------------------+--------+
ฺ b r) deฺ
1 row in set (0.00 sec)
o i
m is unchanged.
u
− The login_time field changes. Every other
a c
rฺ SQL
field
n t G
p e
tud
6. Simulate the user logging in again with the following statement:
INSERT INTO current_usersso
ne username)
(userid,S
VALUES (100, 'Tobias')
c i @ this
ON DUPLICATE KEYrUPDATE
o ฺ ic uvisits=visits+1;
se
Enter the followinge t
rstatementtoat the mysql prompt and receive the results shown:
b
roINSERTenINTOse current_users (userid, username)
i
mysql> (
R icc -> l ic (100, 'Tobias')
VALUES

e r to Query->OK, ON DUPLICATE KEY UPDATE visits=visits+1;


2 rows affected (0.03 sec)
R ob 7. Execute a suitable query to verify any differences in behavior between the preceding
INSERT statement and the earlier REPLACE statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM current_users;
+--------+----------+---------------------+--------+
| userid | username | login_time | visits |
+--------+----------+---------------------+--------+
| 100 | Tobias | 2016-05-16 14:55:15 | 2 |
+--------+----------+---------------------+--------+
1 row in set (0.00 sec)
− As before, the login_time field contains an updated time. Also, the visits field
is incremented by one.
8. Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 16
Practice 11-6: Truncating Table Data
Overview
In this practice, you use the TRUNCATE TABLE statement to empty a table of its data.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately five minutes to complete.

Tasks
1. In the sakila database, inspect the next AUTO_INCREMENT value for the actor_copy
table by issuing a suitable SHOW CREATE TABLE statement.
2. Empty the actor_copy table of all data with a TRUNCATE statement. Verify row removal
with a suitable query. e
3. Inspect the next value for the AUTO_INCREMENT column of the actor_copy table. r a bl
s fe
4. Insert a record into the actor_copy table, specifying a first_name of “Lars,” and a
last_name of “Larsson.” Leave the other values unspecified. Verify the addition with a - t r an
suitable query. no n
5. s a
Inspect the next value for the AUTO_INCREMENT column of the actor_copy table again.
h a
6. Drop the actor_copy table from the sakila database. br) ฺ
ฺ i d e
7. Keep the Linux terminal window open and connected
r ฺ c om t G u command-line client for
to the mysql
the next practice.
e p a den
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 17
Solution 11-6: Truncating Table Data
Solution Steps
1. In the sakila database, inspect the next AUTO_INCREMENT value for the actor_copy
table by issuing a suitable SHOW CREATE TABLE statement.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statements at the mysql prompt and receive the results shown:
mysql> USE sakila;
Reading table information ...
Database changed

mysql> SHOW CREATE TABLE actor_copy\G


*************************** 1. row ***************************
Table: actor_copy
Create Table: CREATE TABLE `actor_copy` (
ble
`actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) NOT NULL, fe r a
`last_name` varchar(45) NOT NULL,
ans
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
n - t r
CURRENT_TIMESTAMP,
PRIMARY KEY (`actor_id`), a no
KEY `idx_actor_last_name` (`last_name`)
h a s
) ENGINE=InnoDB AUTO_INCREMENT=251 DEFAULT CHARSET=utf8
ฺ b r) deฺ
1 row in set (0.00 sec)
o m actor_id
u i
− The next value for the AUTO_INCREMENT
a r ฺ c
column
n t G is 251.
2. Empty the actor_copy table of all data e
o n p a TRUNCATE
with
t u de statement. Verify row removal
with a suitable query.
@ s is S
Enter the following statements c i th prompt and receive the results shown:
c at theemysql
r i
oฺTABLE us
mysql> TRUNCATE
e r
Query OK,b0 rows e
t t o actor_copy;

( r o n s affected (0.34 sec)

i c ci SELECT
mysql> l i ce * FROM actor_copy;
t o R Empty set (0.00 sec)
r
R obe3. Inspect the next value for the AUTO_INCREMENT column of the actor_copy table.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW CREATE TABLE actor_copy\G
*************************** 1. row ***************************
Table: actor_copy
Create Table: CREATE TABLE `actor_copy` (
`actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEY (`actor_id`),
KEY `idx_actor_last_name` (`last_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
− The AUTO_INCREMENT table option is not present in the output.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 18
4. Insert a record into the actor_copy table, specifying a first_name of “Lars,” and a
last_name of “Larsson.” Leave the other values unspecified. Verify the addition with a
suitable query.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> INSERT INTO actor_copy(first_name, last_name)
-> VALUES ('Lars', 'Larsson');
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Query OK, 1 row affected (0.02 sec)

mysql> SELECT * FROM actor_copy;


+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 1 | Lars | Larsson | 2016-05-16 14:57:03 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
ble
− The actor_id column contains the value 1, assigned by the AUTO_INCREMENT
fe r a
setting.
ans
5. Inspect the next value for the AUTO_INCREMENT column of the actor_copy table again.
n - t r
no
Enter the following statements at the mysql prompt and receive the results shown:
a
mysql> SHOW CREATE TABLE actor_copy\G
h a s
ฺ b r) deฺ
*************************** 1. row ***************************
Table: actor_copy
o m u i
Create Table: CREATE TABLE `actor_copy`
`actor_id` smallint(5) unsignedaNOT
c
rฺ NULL
(
n t G
p
`first_name` varchar(45) NOTeNULL, d
n Stu e AUTO_INCREMENT,

`last_name` varchar(45)so NOT NULL,


c
`last_update` timestamp i is DEFAULT CURRENT_TIMESTAMP ON
@ NOTthNULL UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEYto ฺ ric use
b e r to
(`actor_id`),

( r o n s e
KEY `idx_actor_last_name` (`last_name`)

c i in set
) ENGINE=InnoDB
crow l i ce(0.00 sec)
AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

R i1

e r to − The AUTO_INCREMENT table option is now present and its value is 2.

R ob 6. Drop the actor_copy table from the sakila database.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> DROP TABLE actor_copy;
Query OK, 0 rows affected (0.01 sec)
7. Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 19
Practice 11-7: Modifying Table Data
Overview
In this practice, you modify table data by using REPLACE and UPDATE statements.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately ten minutes to complete.

Tasks
1. In the sakila database, create a copy of the film table called film_copy.
2. Insert a new record into the film_copy table, with the title “MySQL Training” and a
language_id of 1. Leave the other fields unspecified.
3. Use a suitable function to inspect the AUTO_INCREMENT value generated for the film_id
ble
column.
fe r a
4. Issue a REPLACE statement to change the title of the newly added film to “MySQL for
ans
Developers.”
n - t r
5. Update the rental_duration of the newly added film to 4.
a no
6. a
Increase the replacement_cost of the newly added film by 20%.
h s
7. b r) deฺ
Verify that the preceding updates have succeeded by issuing a suitable query.

8. Delete the newly added film. c o m Gui
9. Drop the film_copy table. p a rฺ ent
oneterminal d open for the next practice.
tuwindow
10. Exit the mysql client, but keep the Linux
s S
c i @ this
t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 20
Solution 11-7: Modifying Table Data
Solution Steps
1. In the sakila database, create a copy of the film table called film_copy.
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> CREATE TABLE film_copy LIKE film;


Query OK, 0 rows affected (0.72 sec)

mysql> INSERT INTO film_copy SELECT * FROM film;


Query OK, 1000 rows affected (0.60 sec)
Records: 1000 Duplicates: 0 Warnings: 0
2. Insert a new record into the film_copy table with the title “MySQL Training” and a
language_id of 1. Leave the other fields unspecified.
Enter the following statement at the mysql prompt and receive the results shown: ble
fe r a
mysql> INSERT INTO film_copy (title, language_id)
ans
-> VALUES ('MySQL Training', 1);
n - t r
no
Query OK, 1 row affected (0.07 sec)
3. a
Use a suitable function to inspect the AUTO_INCREMENT value generated for the film_id
s
column. h a
ฺ b r) deฺ
Enter the following statement at the mysql prompt and receive the results shown:
c o m Gui
mysql> SELECT LAST_INSERT_ID();
+------------------+ p a rฺ ent
| LAST_INSERT_ID() |
s one s Stud
hi
+------------------+
1001 |ci@ t
|
i c
ฺr sec)us e
o
+------------------+
1 row in setrt(0.00
e to
b e
c i ( oYouccan
e s
− TherLAST_INSERT_ID()
nuse function displays the current the AUTO_INCREMENT field

Ric
value. li it instead of SHOW CREATE TABLE.

e
4.
r toDevelopers.”
Issue a REPLACE statement to change the title of the newly added film to “MySQL for

R ob Enter the following statement at the mysql prompt and receive the results shown:
mysql> REPLACE INTO film_copy(film_id, title, language_id)
-> VALUES (1001, 'MySQL for Developers', 1);
Query OK, 2 rows affected (0.04 sec)
5. Update the rental_duration of the newly added film to 4.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> UPDATE film_copy SET rental_duration = 4
-> WHERE film_id = 1001;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
6. Increase the replacement_cost of the newly added film by 20%.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> UPDATE film_copy
-> SET replacement_cost = replacement_cost * 1.2
-> WHERE film_id = 1001;
Query OK, 1 row affected, 1 warning (0.05 sec)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 21
Rows matched: 1 Changed: 1 Warnings: 1

mysql> SHOW WARNINGS;


+-------+------+-------------------------------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------------------------------+
| Note | 1265 | Data truncated for column 'replacement_cost' at row 1 |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+-------+------+-------------------------------------------------------+
1 row in set (0.00 sec)
− Note the warning about data truncation. The calculated value contains more digits
than that the replacement_cost column can accommodate.
7. Verify that the preceding updates have succeeded by issuing a suitable query.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM film_copy WHERE film_id = 1001\G
*************************** 1. row ***************************
ble
film_id: 1001
fe r a
title: MySQL for Developers
description: NULL
ans
release_year: NULL
n - t r
language_id: 1
a no
original_language_id: NULL
rental_duration: 4
h a s
rental_rate: 4.99
ฺ b r) deฺ
length: NULL
c o m Gui
replacement_cost: 23.99
rating: G
p a rฺ ent
special_features: NULL
s one s Stud
last_update: 2013-08-22 10:33:28
1 row in set (0.00 sec)
c c i@ thi
8. Delete the newly added o ฺ i
rfilm. use
e t
rstatementtoat the mysql prompt and receive the results shown:
b
Enter the following
se film_copy WHERE film_id = 1001;
roDELETEenFROM
i (
R cc OK,li1crow affected (0.01 sec)
mysql>
iQuery
be9.rtoDrop the film_copy table.
Ro Enter the following statement at the mysql prompt and receive the results shown:
mysql> DROP TABLE film_copy;
Query OK, 0 rows affected (0.05 sec)
10. Exit the mysql client, but keep the Linux terminal window open for the next practice.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> EXIT
Bye
#

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 11: Modifying Table Data


Chapter 11 - Page 22
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 12:
om t Gu
Transactions i
r ฺ c
a 12den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 1
Practices for Lesson 12: Transactions
Practices Overview
These practices test your knowledge of transactions. They assume that you are using the Linux
operating system environment provided in Oracle classrooms. For non-Oracle classrooms, you
might need to make some adjustments to the file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The sakila sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 2
Practice 12-1: Quiz – Transactions, Isolation Levels, and Locking
Overview
In this practice, you test your knowledge of transactions, isolation levels, and locking in InnoDB.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately five minutes to complete.

Questions
1. What is a transaction?
2. What are the implications of disabling AUTOCOMMIT mode?
3. What does the acronym ACID stand for?
4. Name the four transaction isolation levels.
ble
5. Which three types of inconsistencies can occur when two simultaneous transactions access
fe r a
the same table?
ans
6. The Serializable locking level allows nonrepeatable reads.
n - t r
o
a. True
s an
b. False
r ) ha ฺ
7.
ฺb uide
Name the two locking modifiers that MySQL supports.
m
8.
a r ฺco nt G
Both locking types lock selected ___________ to prevent problems that might occur when
multiple transactions access the same table simultaneously.

o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 3
Solution 12-1: Quiz – Transactions, Isolation Levels, and Locking
Answers to Quiz Questions
1. In database terminology, a transaction is a set of data manipulation tasks treated as a
single unit of work.
2. Each statement belongs to a transaction. You can perform multiple statements in a single
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

transaction. You can explicitly commit or roll back a transaction by using the COMMIT and
ROLLBACK statements, respectively.
3. Atomic, Consistent, Isolated, Durable
4. Serializable, Repeatable Read, Read Committed, Read Uncommitted
5. Dirty reads, nonrepeatable reads, phantom reads
6. b. False. This isolation level specifies that all transactions occur in a completely isolated
fashion. It is as if all transactions execute serially, one after the other.
ble
7. LOCK IN SHARE MODE and FOR UPDATE.
fe r a
8. Both locking types lock selected rows to prevent problems that might occur when multiple ans
transactions access the same table simultaneously. n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 4
Practice 12-2: Using Transaction Control Statements
Overview
In this practice, you issue SQL commands to start, commit, and roll back transactions.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take you approximately ten minutes to complete.

Tasks
1. At a Linux terminal prompt, log in to the mysql client as root (password: oracle).
2. Using a SHOW statement, list all storage engines. Determine which engine is the default,
and which supports transactions.
3. Display the value of AUTOCOMMIT for the current session. What effect does the value have
ble
on SQL statements that modify table data?
fe r a
4. Identify the storage engines used by the city and film_text tables in the sakila
ans
database.
n - t r
5. no
Delete a record from the city table in the sakila database within an explicit transaction.
a
h a s
Confirm that it has been removed and then roll back the transaction. Verify that the record
is restored. Perform the following steps to achieve this:
ฺ b r) deฺ
• Explicitly start a new transaction.
c o m Gui
• Find the ID of the Canadian city of London.
p a rฺ ent
• Delete that city, and issue a SELECT
o neto ensure d removal.
tuits
• Roll back the transaction. @ s is S
c i
• Confirm that the rowriiscrestored
t h
t o ฺ u seto the table.
e
6. Delete a record from
b r the film_text
to table within an explicit transaction and confirm its
removal. Roll e
(robackcethensteps
s
transaction and take note of any differences from the preceding task.
Perform
c c i li
the following to achieve this:
R i
• Explicitly start a new transaction.
berto • Find the ID of the film_text row for the film titled “Rock Instinct.”
Ro • Delete the row for that film text, and issue a SELECT to confirm its removal.
• Roll back the transaction.
• Check if the row is restored, noting any differences from the preceding task.
7. Repeat the tasks in step 5 to delete the Canadian city of London; however, this time
COMMIT the statement, instead of rolling it back.
8. Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 5
Solution 12-2: Using Transaction Control Statements
Solution Steps
1. At a Linux terminal prompt, log in to the mysql client as root (password: oracle).
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
2. Using a SHOW statement, list all storage engines. Determine which engine is the default,
and which supports transactions.
Enter the following statement at the mysql prompt, and receive the results shown:
mysql> SHOW ENGINES\G
ble
*************************** 1. row ***************************
fe r a
Engine: MyISAM
ans
Support: YES
Comment: MyISAM storage engine n - t r
o
Transactions: NO
XA: NO s an
Savepoints: NO
r ) ha ฺ
ฺb uide
*************************** 2. row ***************************
m
ฺco nt G
Engine: CSV
Support: YES
a r
Comment: CSV storage engine
o n ep tude
Transactions: NO
XA: NO
@ s is S
c c i th
Savepoints: NO
r i e
e r toฺ to us
*************************** 3. row ***************************
Engine: MRG_MYISAM

i ( rob ense
Support: YES
c lic
Comment: Collection of identical MyISAM tables

to RicTransactions: NO

e r XA: NO

ob
Savepoints: NO
R *************************** 4. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it
disappears)
Transactions: NO
XA: NO
Savepoints: NO
*************************** 5. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign
keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 6. row ***************************
Engine: MEMORY
Support: YES

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 6
Comment: Hash based, stored in memory, useful for temporary
tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: ARCHIVE
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 8. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL ble
XA: NULL
fe r a
Savepoints: NULL
ans
*************************** 9. row ***************************
n - t r
Engine: PERFORMANCE_SCHEMA
Support: YES
a no
Comment: Performance Schema
h a s
Transactions: NO
ฺ b r) deฺ
XA: NO
Savepoints: NO
c o m Gui
9 rows in set (#.## sec)
p a rฺ ent
3. Display the value of AUTOCOMMIT for the
s o necurrent
S ud What effect does the value have
tsession.
on SQL statements that modify@ table data?is
c c i th prompt, and receive the results shown:
r
Enter the following statement
ฺ i e
at the mysql
us
mysql> SELECT e r to@@AUTOCOMMIT;
t o
( rob en|se
+--------------+
i
R cc lic
| @@AUTOCOMMIT
i+--------------+
erto +--------------+
| 1 |
b
Ro 1 row in set (#.## sec)
− Answer: AUTOCOMMIT is enabled. This means that as soon as you submit any SQL
statements that modify table data, the changes are persisted and cannot be rolled
back. To be able to control whether changes are committed to the database or
rolled back, you must explicitly start a transaction.
4. Identify the storage engines used by the city and film_text tables in the sakila
database.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> USE sakila
Database changed

mysql> SHOW TABLE STATUS WHERE name IN ('city', 'film_text')\G


*************************** 1. row ***************************
Name: city
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 600
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 7
Avg_row_length: 81
Data_length: 49152
Max_data_length: 0
Index_length: 16384
Data_free: 0
Auto_increment: 601
Create_time: 2015-11-04 09:53:44
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
*************************** 2. row ***************************
Name: film_text
Engine: MyISAM
Version: 10 ble
Row_format: Dynamic
fe r a
Rows: 1000
ans
Avg_row_length: 119
n - t r
Data_length: 119616
Max_data_length: 281474976710655
a no
Index_length: 10240
h a s
Data_free: 0
ฺ b r) deฺ
Auto_increment: NULL
Create_time: 2015-11-10 15:12:20
c o m Gui
Update_time: 2015-11-10 15:12:20
p a rฺ ent
one s Stud
Check_time: NULL
s
Collation: utf8_general_ci
Checksum: NULL
c c i@ thi
Create_options:
o ฺ r i u se
r t
Comment:
e to
b e
2 rows in set (#.## sec)
i (ro The
− Answer:
c c e s table uses InnoDB, and film_text uses MyISAM.
ncity
R
5. Delete
i the city table in the sakila database within an explicit transaction.
ic a record lfrom
bertoConfirm that it has been removed and then roll back the transaction. Verify that the record
Ro
is restored. Perform the following steps to achieve this:
• Explicitly start a new transaction.
• Find the ID of the Canadian city of London.
• Delete that city, and issue a SELECT to ensure its removal.
• Roll back the transaction.
• Confirm that the row is restored to the table.
a. To explicitly start a transaction, enter the following statement at the mysql prompt and
receive the results shown:
mysql> START TRANSACTION;
Query OK, 0 rows affected (#.## sec)
b. To find the ID of the Canadian city London, enter the following statements at the
mysql prompt and receive the results shown:
mysql> SELECT country_id FROM country
-> WHERE country = 'Canada';
+------------+
| country_id |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 8
+------------+
| 20 |
+------------+
1 row in set (#.## sec)

mysql> SELECT city_id FROM city


-> WHERE city = 'London'
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

-> AND country_id = 20;


+---------+
| city_id |
+---------+
| 313 |
+---------+
1 row in set (#.## sec)
c. To delete the city, and verify its removal, enter the following statements at the mysql
prompt and receive the results shown:
ble
mysql> DELETE FROM city WHERE city_id = 313;
fe r a
Query OK, 1 row affected (#.## sec)
ans
n - t r
mysql> SELECT * FROM city WHERE city = 'London';
+---------+--------+------------+---------------------+ a no
| city_id | city | country_id | last_update |
h a s
+---------+--------+------------+---------------------+
ฺ b r) deฺ
| 312 | London |
m Gui
102 | 2006-02-15 04:45:25 |
c o
1 row in set (#.## sec)
p a rฺ ent
+---------+--------+------------+---------------------+

− The row deleted previously (with


s o S ud does not appear in the resultset. The
e ID of t313)
nan
c i t h is
remaining city refers to London in England.
@
t o ฺ ric usbyeissuing the following statement at the mysql prompt:
d. Roll back the open transaction
e
mysql> ROLLBACK;
b r to (#.## sec)
(rothat ctheerow
Query OK, 0 rows e
ns has been restored to the table by issuing the following statement
affected
c i
iatc the mysqlli prompt:
e. Confirm
R
berto mysql> SELECT * FROM city WHERE city = 'London';
Ro +---------+--------+------------+---------------------+
| city_id | city | country_id | last_update |
+---------+--------+------------+---------------------+
| 312 | London | 102 | 2006-02-15 04:45:25 |
| 313 | London | 20 | 2006-02-15 04:45:25 |
+---------+--------+------------+---------------------+
2 rows in set (#.## sec)
− The London record with an ID of 313 has been restored to the city table.
6. Delete a record from the film_text table within an explicit transaction and confirm its
removal. Roll back the transaction and take note of any differences from the preceding task.
Perform the following steps to achieve this:
• Explicitly start a new transaction.
• Find the ID of the film_text row for the film titled “Rock Instinct.”
• Delete the row for that film text, and issue a SELECT to confirm its removal.
• Roll back the transaction.
• Check if the row is restored, noting any differences from the preceding task.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 9
a. Enter the following statements at the mysql prompt, and receive the results shown:
mysql> SELECT film_id FROM film_text
-> WHERE title = 'Rock Instinct';
+---------+
| film_id |
+---------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| 737 |
+---------+
1 row in set (#.## sec)

mysql> DELETE FROM film_text WHERE film_id = 737;


Query OK, 1 row affected (#.## sec)

mysql> SELECT film_id FROM film_text WHERE film_id = 737;


Empty set (#.## sec)

ble
mysql> ROLLBACK;
fe r a
Query OK, 0 rows affected, 1 warning (#.## sec)
ans
b. View the warning generated as a result of issuing ROLLBACK in the previous step by
n - t r
issuing the following command:
n o
mysql> SHOW WARNINGS\G s a
h a
r) deฺ
*************************** 1. row ***************************
Level: Warning
m ฺ b i
Code: 1196
ฺ c o G u
Message: Some non-transactional changed
a r n t
tables couldn't be rolled back
1 row in set (#.## sec)
o n ep tude
c. Enter the following statement to s see if ithe
s S
row has been restored:
i @
mysql> SELECT * FROMc film_text h
t WHERE film_id = 737;
r
Empty set (#.## ฺsec) i c s e
rtonot return
t o u
e
− The rowbdoes when you roll back the transaction. This is because
i ( ro eisnnot
film_text sea transactional table, because it is based on the MyISAM storage
R iccengine. lic
erto
7. Repeat the tasks in step 5 to delete the Canadian city of London; however, this time,
b COMMIT the statement, instead of rolling it back.
Ro a. Explicitly start a transaction with the following statement at the mysql prompt:
mysql> START TRANSACTION;
Query OK, 0 rows affected (#.## sec)
b. To delete the city with the ID 313 as previously seen, and verify its removal, issue the
following statements at the mysql prompt:
mysql> DELETE FROM city WHERE city_id = 313;
Query OK, 1 row affected (#.## sec)

mysql> SELECT * FROM city WHERE city='London';


+---------+--------+------------+---------------------+
| city_id | city | country_id | last_update |
+---------+--------+------------+---------------------+
| 312 | London | 102 | 2006-02-15 04:45:25 |
+---------+--------+------------+---------------------+
1 row in set (#.## sec)
− The row found is a different city (London in England) with a different ID.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 10
c. Commit the open transaction by issuing the following statement at the mysql prompt:
mysql> COMMIT;
Query OK, 0 rows affected (#.## sec)
d. Confirm that the transaction was successfully committed by issuing the following
statement at the mysql prompt:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SELECT * FROM city WHERE city='London';


+---------+--------+------------+---------------------+
| city_id | city | country_id | last_update |
+---------+--------+------------+---------------------+
| 312 | London | 102 | 2006-02-15 04:45:25 |
+---------+--------+------------+---------------------+
1 row in set (#.## sec)
− The changes made in the transaction are now permanent, and cannot be undone.
8. Keep the Linux terminal window open and connected to the mysql command-line client for
ble
the next practice.
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 11
Practice 12-3: Examining the Effect of Isolation Levels in Concurrent
Transactions
Overview
In this practice, you test your knowledge of transaction isolation levels and how transactions
interact.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Note: This practice uses two Linux terminal windows. The instructions refer to the terminal
windows as T1 and T2.

Duration
This practice should take you approximately 30 minutes to complete.

Tasks
ble
1. Open a second Linux terminal window and log in to the mysql command-line client.
fe r a
2. Change the mysql> prompt in both terminal windows so that you can easily identify each
ans
session. These instructions refer to the original terminal window as T1 and the second
n - t r
terminal window as T2.
a no
h a s
Note: If you are using MySQL Workbench for this practice, open a second SQL Editor tab
and perform the following steps to change the prompt.
ฺ b r) deฺ
c o m Gui
a. Change the mysql client prompt in the second terminal window to T2>:
mysql> PROMPT T2>
p a rฺ ent
one s Stud
PROMPT set to 'T2> '
T2>
s
b. Switch to the first terminal
i c c i@ t hi change the prompt to T1>:
window and
e
mysql> PROMPT o
r t ฺr
T1> us
PROMPT seteto 'T1> 'to
T1>
i ( rob ense
3. In T1,
R iccstart a newlictransaction.
be4.rtoIn T2, change the current database to sakila and start another transaction:
Ro 5.
6.
In T1, select all rows from the country table where the country_id is greater than 100.
In T2, insert a new row into the Country table for Belgium.
7. In T1, reissue the SELECT statement you issued in step 5. What do the results tell you
about the current isolation level?
8. In T2, commit the transaction.
9. In T1, reissue the previous SELECT statement you issued in step 7. What do the results tell
you about the current isolation level?
10. Roll back T1 and reissue the previous select statement. Is the Belgium row visible? Why?
11. Change the isolation level in T1 to READ COMMITTED.
12. Start new transactions in T1 and T2.
13. In T1, select all rows from the country table where the country_id is greater than 100.
14. In T2, insert a new row for the country Ghana.
15. In T1, reissue the query that selects all rows from the country table where the
country_id is greater than 100. Explain your results in the context of the current isolation
level.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 12
16. Commit the transaction in T2.
17. In T1, reissue the query that selects all rows from the country table where the
country_id is greater than 100. Explain your results in the context of the current isolation
level.
18. Roll back the transaction in T1.
19. Change the isolation level in T1 to READ UNCOMMITTED.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

20. Start new transactions in T1 and T2.


21. In T1, select all rows from the country table where the country_id is greater than 100.
22. In T2, insert a new row for the country of Jamaica.
23. In T1, reissue the query that selects all rows from the country table where the
country_id is greater than 100. Explain your results in the context of the current isolation
level.
24. Commit the transaction in T2. ble
fe r a
25. Roll back the transaction in T1.
ans
26. In T1, reissue the query that selects all rows from the country table where the
n - t r
country_id is greater than 100.
a no
27. Revert T1 to the default prompt and exit the mysql client session.
h a s
Enter the following statements at the mysql prompt in T1 and
ฺ b r) receive
d e ฺthe results shown:
om t Gu i
T1> PROMPT
Returning to default PROMPT of mysql> r ฺ
a den c
e p
mysql> EXIT
s on s Stu
Bye
c c i@ thi
#
o ฺ r i u s e
t
r prompt
28. Revert T2 to the default
e to and exit the mysql client session.
b e
(ro cestatements
Enter the following
c i ns at the mysql prompt in T2 and receive the results shown:
R c PROMPTli
iT2>
erto
Returning to default PROMPT of mysql>
b
Ro mysql> EXIT
Bye
#
29. Close the T1 and T2 terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 13
Solution 12-3: Examining the Effect of Isolation Levels in Concurrent
Transactions
Solution Steps
1. Open a second Linux terminal window and log in to the mysql command-line client.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

In the second Linux terminal window, enter the following statement at the mysql prompt
and receive the results shown:
# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
2. Change the mysql> prompt in both terminal windows so that you can easily identify each
session. These instructions refer to the original terminal window as T1 and the second e
terminal window as T2.
r a bl
Note: If you are using MySQL Workbench for this practice, open a second SQL Editor tab s fe
and perform the following steps to change the prompt.
- t r an
a. Change the mysql client prompt in the second terminal window to T2>: no n
s a
mysql> PROMPT T2>
h a
PROMPT set to 'T2> '
ฺ b r) deฺ
T2>
o mprompt u i
b. Switch to the first terminal window and change
a r ฺ c the
n t Gto T1>:
mysql> PROMPT T1>
o n ep tude
PROMPT set to 'T1> '
@ s is S
T1>
c c i th
r i us e
Enter the followinge toฺ toat the
3. In T1, start a new transaction.
rstatement mysql prompt and receive the results shown:
r o b s e
c c e n
( TRANSACTION;
T1> i START
R i c
Query OK, l i
0 rows affected (#.## sec)

be4.rtoIn T2, change the current database to sakila and start another transaction:
Ro Enter the following statements at the mysql prompt and receive the results shown:
T2> USE sakila
Reading table information ...
Database changed

T2> START TRANSACTION;


Query OK, 0 rows affected (#.## sec)
5. In T1, select all rows from the country table where the country_id is greater than 100.
Enter the following statement at the mysql prompt in T1 and receive the results shown:
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
| country_id | country | last_update |
+------------+----------------------+---------------------+
| 101 | United Arab Emirates | 2006-02-15 04:44:00 |
| 102 | United Kingdom | 2006-02-15 04:44:00 |
| 103 | United States | 2006-02-15 04:44:00 |
| 104 | Venezuela | 2006-02-15 04:44:00 |
| 105 | Vietnam | 2006-02-15 04:44:00 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 14
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
| 109 | Zambia | 2006-02-15 04:44:00 |
+------------+----------------------+---------------------+
9 rows in set (#.## sec)
6. In T2, insert a new row into the Country table for Belgium.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt in T2 and receive the results shown::
T2> INSERT INTO country (country) VALUES ('Belgium');
Query OK, 1 row affected (#.## sec)
7. In T1, reissue the SELECT statement you issued in step 5. What do the results tell you
about the current isolation level?
Enter the following statement at the T1 prompt and receive the results shown:
ble
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
fe r a
| country_id | country | last_update |
ans
+------------+----------------------+---------------------+
n - t r
|
|
101 | United Arab Emirates | 2006-02-15 04:44:00 |
102 | United Kingdom | 2006-02-15 04:44:00 | a no
| 103 | United States | 2006-02-15 04:44:00 |
h a s
| 104 | Venezuela r) deฺ
| 2006-02-15 04:44:00 |
ฺ b
| 105 | Vietnam
m Gui
| 2006-02-15 04:44:00 |
c o
|
| 107 | Yemen
p rฺ ent
106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
a
| 2006-02-15 04:44:00 |

one s Stud
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
| 109 | Zambia s | 2006-02-15 04:44:00 |
c i@ thi
+------------+----------------------+---------------------+
c
o ฺ r i
9 rows in set (#.## sec)
u s e
− Answer: e t
r new rowtois not visible. You can tell that the isolation level is not “Read
The
r o b
Uncommitted,” se you cannot see the row you added at the T2 prompt in step
because
i ( e
c6, and neither n
8. Ric lic transaction has been committed.
In T2, commit the transaction.
e r toEnter the following statement at the mysql prompt in T2 and receive the results shown:
R ob T2> COMMIT;
Query OK, 0 rows affected (#.## sec)
9. In T1, reissue the previous SELECT statement you issued in step 7. What do the results tell
you about the current isolation level?
Enter the following statement at the mysql prompt in T1 and receive the results shown:
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
| country_id | country | last_update |
+------------+----------------------+---------------------+
| 101 | United Arab Emirates | 2006-02-15 04:44:00 |
| 102 | United Kingdom | 2006-02-15 04:44:00 |
| 103 | United States | 2006-02-15 04:44:00 |
| 104 | Venezuela | 2006-02-15 04:44:00 |
| 105 | Vietnam | 2006-02-15 04:44:00 |
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
| 109 | Zambia | 2006-02-15 04:44:00 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 15
+------------+----------------------+---------------------+
9 rows in set (#.## sec)
− Answer: The new row is still not visible, which indicates that the isolation level is not
“Read Committed,” because in step 8, you committed the INSERT statement that
added the new row. The result is the same as the query you issued in step 7. This
tells you that this is a “Repeatable Read,” and that the isolation level is, therefore,
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

either “Repeatable Read” or “Serializable.”


10. Roll back T1 and reissue the previous select statement. Is the Belgium row visible? Why?
Enter the following statements at the mysql prompt in T1 and receive the results shown:
T1> ROLLBACK;
Query OK, 0 rows affected (#.## sec)

T1> SELECT * FROM country WHERE country_id > 100;


+------------+----------------------+---------------------+
ble
| country_id | country | last_update |
+------------+----------------------+---------------------+ fe r a
| 101 | United Arab Emirates | 2006-02-15 04:44:00 |
ans
| 102 | United Kingdom | 2006-02-15 04:44:00 |
n - t r
|
|
103 | United States
104 | Venezuela
| 2006-02-15 04:44:00 |
| 2006-02-15 04:44:00 | a no
| 105 | Vietnam | 2006-02-15 04:44:00 |
h a s
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
ฺ b r) deฺ
| 107 | Yemen
m Gui
| 2006-02-15 04:44:00 |
c o
|
|
108 | Yugoslavia
109 | Zambia
p a rฺ ent
| 2006-02-15 04:44:00 |
| 2006-02-15 04:44:00 |
| 110 | Belgium
s one s Stud
| 2016-05-18 10:29:29 |
+------------+----------------------+---------------------+
10 rows in set (#.## sec)
c c i@ thi
− Answer: The row
o ฺ i u seis now visible because the transaction that performed
r for Belgium
the INSERT e t
ris now committed
to and the transaction is complete. “Repeatable Read”
r o b s e
c i ( The
is not relevant
c e noutside of a transaction.

Ri−c Note: l i default transaction isolation level is “Repeatable Read.”

e11.
r toChange the isolation level in T1 to READ COMMITTED.
R ob Enter the following statements at the mysql prompt and receive the results shown:
T1> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (#.## sec)
− Note: The SET TRANSACTION ISOLATION LEVEL statement affects the isolation
level only for the current transaction. To persist the change in isolation level, you
must run SET [scope] TRANSACTION LEVEL, where scope is either SESSION
or GLOBAL and affects the value of the tx_isolation variable for the scope.
12. Start new transactions in T1 and T2.
a. Enter the following statement at the mysql prompt in T1 and receive the results
shown:
T1> START TRANSACTION;
Query OK, 0 rows affected (#.## sec)
b. Enter the following statement at the mysql prompt in T2 and receive the results
shown:
T2> START TRANSACTION;
Query OK, 0 rows affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 16
13. In T1, select all rows from the country table where the country_id is greater than 100.
Enter the following statement at the mysql prompt in T1 and receive the results shown:
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
| country_id | country | last_update |
+------------+----------------------+---------------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| 101 | United Arab Emirates | 2006-02-15 04:44:00 |


| 102 | United Kingdom | 2006-02-15 04:44:00 |
| 103 | United States | 2006-02-15 04:44:00 |
| 104 | Venezuela | 2006-02-15 04:44:00 |
| 105 | Vietnam | 2006-02-15 04:44:00 |
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
| 109 | Zambia | 2006-02-15 04:44:00 |
| 110 | Belgium | 2016-05-18 10:29:29 |
ble
+------------+----------------------+---------------------+
fe r a
10 rows in set (#.## sec)
ans
14. In T2, insert a new row for the country Ghana. n - t r
no
Enter the following statement at the mysql prompt in T2 and receive the results shown:
a
T2> INSERT INTO country (country) VALUES ('Ghana');
h a s
Query OK, 1 row affected (#.## sec)
ฺ b r) deฺ
15. In T1, reissue the query that selects all rows from the o mcountryu i where the
table
country_id is greater than 100. Explain your a c
ฺ innthe
rresults G
t context of the current isolation
level.
p
ne Stud e
Enter the following statement at@ s o
the mysqlis
prompt and receive the results shown:
c i t h
T1> SELECT * FROM
t o ฺ riccountry
u seWHERE country_id > 100;
r | countryto
+------------+----------------------+---------------------+
b e
( r o
| country_id
n s e | last_update |

i|c ci l
101 ce| United Arab Emirates | 2006-02-15 04:44:00 |
+------------+----------------------+---------------------+
i
t o R| 102 | United Kingdom | 2006-02-15 04:44:00 |

be r | 103 | United States | 2006-02-15 04:44:00 |

Ro |
|
104 | Venezuela
105 | Vietnam
| 2006-02-15 04:44:00 |
| 2006-02-15 04:44:00 |
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
| 109 | Zambia | 2006-02-15 04:44:00 |
| 110 | Belgium | 2016-05-18 10:29:29 |
+------------+----------------------+---------------------+
10 rows in set (#.## sec)
− Answer: The READ COMMITTED isolation level prevents you from seeing
uncommitted changes in T2.
16. Commit the transaction in T2.
Enter the following statement at the mysql prompt in T2 and receive the results shown:
T2> COMMIT;
Query OK, 0 rows affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 17
17. In T1, reissue the query that selects all rows from the country table where the
country_id is greater than 100. Explain your results in the context of the current isolation
level.
Enter the following statement at the mysql prompt in T1 and receive the results shown:
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| country_id | country | last_update |


+------------+----------------------+---------------------+
| 101 | United Arab Emirates | 2006-02-15 04:44:00 |
| 102 | United Kingdom | 2006-02-15 04:44:00 |
| 103 | United States | 2006-02-15 04:44:00 |
| 104 | Venezuela | 2006-02-15 04:44:00 |
| 105 | Vietnam | 2006-02-15 04:44:00 |
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
ble
|
|
108 | Yugoslavia
109 | Zambia
| 2006-02-15 04:44:00 |
| 2006-02-15 04:44:00 | fe r a
| 110 | Belgium | 2016-05-18 10:29:29 |
ans
| 111 | Ghana | 2016-05-18 10:32:52 |
n - t r
+------------+----------------------+---------------------+
11 rows in set (#.## sec) a no
− Answer: The new row appears in T1 as soon as T2 commits, h a s even though T1 has
b
read from the table already. This is not a “repeatable
ฺ r)read.”deฺ
18. Roll back the transaction in T1. c o m Gui
Enter the following statement at the mysqlp a rฺ andereceive
prompt n t the results shown:
T1> ROLLBACK; s one s Stud
Query OK, 0 rows affected
i c c i@ (#.##
e t hi sec)
19. Change the isolation o
r t ฺr in T1 tousREAD UNCOMMITTED.
level
b e
Enter the following e
statements toat the mysql prompt and receive the results shown:
c (roTRANSACTION
T1> i SET
c e ns ISOLATION LEVEL READ UNCOMMITTED;
R c OK,li0 rows affected (#.## sec)
iQuery
b rtoStart new transactions in T1 and T2.
e20.
Ro a. Enter the following statement at the mysql prompt in T1 and receive the results
shown:
T1> START TRANSACTION;
Query OK, 0 rows affected (#.## sec)
b. Enter the following statement at the mysql prompt in T2 and receive the results
shown:
T2> START TRANSACTION;
Query OK, 0 rows affected (#.## sec)
21. In T1, select all rows from the country table where the country_id is greater than 100.
Enter the following statement at the mysql prompt in T1 and receive the results shown:
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
| country_id | country | last_update |
+------------+----------------------+---------------------+
| 101 | United Arab Emirates | 2006-02-15 04:44:00 |
| 102 | United Kingdom | 2006-02-15 04:44:00 |
| 103 | United States | 2006-02-15 04:44:00 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 18
| 104 | Venezuela | 2006-02-15 04:44:00 |
| 105 | Vietnam | 2006-02-15 04:44:00 |
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
| 109 | Zambia | 2006-02-15 04:44:00 |
| 110 | Belgium | 2016-05-18 10:29:29 |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| 111 | Ghana | 2016-05-18 10:32:52 |


+------------+----------------------+---------------------+
11 rows in set (#.## sec)11 rows in set (#.## sec)
22. In T2, insert a new row for the country Jamaica.
Enter the following statement at the mysql prompt in T2 and receive the results shown:
T2> INSERT INTO country (country) VALUES ('Jamaica');
Query OK, 1 row affected (#.## sec)
23. In T1, reissue the query that selects all rows from the country table where the ble
country_id is greater than 100. Explain your results in the context of the current isolation fe r a
level. ans
Enter the following statement at the mysql prompt in T1 and receive the results shown: n - t r
o
T1> SELECT * FROM country WHERE country_id > 100;
s an
r ) ha ฺ
+------------+----------------------+---------------------+
| country_id | country
m ฺb uide
| last_update |
+------------+----------------------+---------------------+
|
r ฺco nt G
101 | United Arab Emirates | 2006-02-15 04:44:00 |
a
|
|
102 | United Kingdom
103 | United States
o n ep tude
| 2006-02-15 04:44:00 |
| 2006-02-15 04:44:00 |
| 104 | Venezuela
@ s is S | 2006-02-15 04:44:00 |
| 105 | Vietnam
c c i th | 2006-02-15 04:44:00 |
r i e
toฺ to us
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
|
e r
107 | Yemen | 2006-02-15 04:44:00 |
|
i ( rob ense
108 | Yugoslavia | 2006-02-15 04:44:00 |
|
c 109 | Zambia
lic
| 2006-02-15 04:44:00 |

to Ric|
|
110 | Belgium
111 | Ghana
| 2016-05-18 10:29:29 |
| 2016-05-18 10:32:52 |
e r
ob
| 112 | Jamaica | 2016-05-18 10:38:23 |
R +------------+----------------------+---------------------+
12 rows in set (#.## sec)
− Answer: The READ UNCOMMITTED isolation level causes the new row to appear in
T1 even before you commit the transaction in T2.
24. Commit the transaction in T2.
Enter the following statement at the mysql prompt in T2 and receive the results shown:
T2> COMMIT;
Query OK, 0 rows affected (#.## sec)
25. Roll back the transaction in T1.
Enter the following statement at the mysql prompt and receive the results shown:
T1> ROLLBACK;
Query OK, 0 rows affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 19
26. In T1, reissue the query that selects all rows from the country table where the
country_id is greater than 100.
Enter the following statement at the mysql prompt and receive the results shown:
T1> SELECT * FROM country WHERE country_id > 100;
+------------+----------------------+---------------------+
| country_id | country | last_update |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+------------+----------------------+---------------------+
| 101 | United Arab Emirates | 2006-02-15 04:44:00 |
| 102 | United Kingdom | 2006-02-15 04:44:00 |
| 103 | United States | 2006-02-15 04:44:00 |
| 104 | Venezuela | 2006-02-15 04:44:00 |
| 105 | Vietnam | 2006-02-15 04:44:00 |
| 106 | Virgin Islands, U.S. | 2006-02-15 04:44:00 |
| 107 | Yemen | 2006-02-15 04:44:00 |
| 108 | Yugoslavia | 2006-02-15 04:44:00 |
ble
|
|
109 | Zambia
110 | Belgium
| 2006-02-15 04:44:00 |
| 2016-05-18 10:29:29 |
fe r a
| 111 | Ghana | 2016-05-18 10:32:52 |
ans
| 112 | Jamaica | 2016-05-18 10:38:23 |
n - t r
+------------+----------------------+---------------------+
12 rows in set (#.## sec) a no
a
− The new record has been permanently committed to thehdatabase
s and, therefore,
the ROLLBACK statement has no effect.
ฺ b r) deฺ
27. Revert T1 to the default prompt and exit the mysql o m session.
client u i
a c
rฺ ineT1nand G
t receive the results shown:
Enter the following statements at the mysqlp prompt
T1> PROMPT s one s Stud
Returning to default iPROMPT
c @ ofthimysql>
r i c se
mysql> EXIT toฺ u
b e r to
Bye
(ro cens e
#
c i
ic T2 to thelidefault prompt and exit the mysql client session.
28. Revert
R
e r toEnter the following statements at the mysql prompt in T2 and receive the results shown:
R ob T2> PROMPT
Returning to default PROMPT of mysql>

mysql> EXIT
Bye
#
29. Close the T1 and T2 terminal windows.
Enter the following command at the T1 and T2 Linux terminal prompts:
# exit

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 12: Transactions


Chapter 12 - Page 20
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 13:
Query m Gu
oOptimizationi
a r ฺ c n t
p e
one s Stud
Chapter 13
s
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 1
Practices for Lesson 13: Query Optimization
Practices Overview
These practices test your knowledge of MySQL query optimization concepts. They assume that
you are using the Linux operating system environment provided in Oracle classrooms. For
non-Oracle classrooms, you might need to make some adjustments to file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• You have created the dbtest database as described in the practices for the lesson
titled “Modifying Table Data.”
• The employees2.sql database creation script is available in the
/stage/databases/employees_db directory.
• MySQL Enterprise Monitor is installed, configured, and bookmarked in your web
ble
browser as described in the practice titled “Course Environment Overview.”
fe r a
• The sakila sample database is installed.
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 2
Practice 13-1: Quiz – Optimization
Overview
In this practice, you test your knowledge of query optimization and optimization techniques.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately ten minutes to complete.

Questions
1. Under what circumstances can adding indexes to a table make table operations slower?
2. True or false: Indexing improves performance of SELECT queries only; it deteriorates
performance of queries that change data.
3. “For my purposes, it doesn’t matter whether a query returns a result within one second or e
one minute, so I do not care about indexing.” Do you agree or disagree with the preceding
r a bl
statement, and why? s fe
4. What are the main reasons not to index table columns?
- t r an
5. The following is an excerpt from the description of the film table: no n
s a
mysql> DESCRIBE film;
h a
r|) Null|deKey|
+-------------+-----------------------------------+-----+----+--------+
| Field | Type
ฺ b ฺ Default|
i
om t |GNOu | PRI| NULL |
+-------------+-----------------------------------+-----+----+--------+
| film_id | smallint(5) unsigned
r ฺ c
a den || NO
| title | varchar(255)
n e p u
| MUL| NULL |
| description | text
... o
s is S t YES | | NULL |

| rating
i @ t h
| enum('G','PG','PG-13','R','NC-17')|
c YES | | G |
...
ฺr i c e
t o us
+-------------+-----------------------------------+-----+----+--------+
r t o
e
robWould
− If the rating esituation
column had a PRIMARY KEY index based on it, how many rows would
(
iti have? e n s
the be different if it had a UNIQUE key instead?
c c l i c
6. Ri should you consider when making index prefix values as short as possible?
What
toWhat statement would create a 10-character prefix index on the description field of the
e r
7.
R ob film table?
8. How can the LIMIT clause help improve the performance of queries?
9. What can you do to speed up data insertion operations?

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 3
Solutions 13-1: Quiz – Optimization
Answers
1. The performance of table data modification operations suffers if there are many indexes, or
if the indexes are large.
2. False. UPDATE and DELETE statements benefit from indexes that are used in a WHERE
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

clause.
3. This statement disregards the fact that the server is not idle during the time it takes to
handle a query. If the statement takes one minute to execute, that means the server is busy
for that time, and is less able to handle other requests. Speeding up a query by using an
index improves the performance of other operations happening at the same time. For these
reasons, you must disagree with this statement.
4. The following are reasons not to use indexes:
ble
• Indexes consume extra disk space.
fe r a
• Indexes negatively affect the performance of data modification operations if:
ans
− The data modification statement does not have a WHERE clause
n - t r
no
− The data modification statement uses a WHERE clause, but there are other indexes
a
on the table
h a s
− The data modification statement uses a WHERE clause
ฺ b r) in thedeabsence
ฺ of any
indexes om t Gu i
r ฺ
5. The film table would have at most five rowsaif the rating
c n field was a PRIMARY KEY (one
e p d e
row per value in the enum). If the rating
s onin the
field
S
was
tu column.key,
a UNIQUE it could have the same
five rows, plus any rows with null values
i @ h i s rating
t indexes also allow nulls.
This is because the
rating column allows nulls,
ฺ r i ccand UNIQUE
s e
6. You must consider rhow to unique t o u prefix value is. The optimizer cannot efficiently use an
each
e
i ( rob idx_desc_prefix
index with a low degree
e n se
of uniqueness.
7. CREATE
i c c INDEX
l i c ON film(description(10));

t o R allows the server to terminate query processing earlier than it would otherwise and
8. LIMIT
b r
e the server returns less information over the network to the client.
Ro 9. Use multiple-row INSERT statements instead of several single-row INSERT statements.
Also, consider LOAD DATA INFILE, which is even faster than multiple-row INSERT
statements.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 4
Practice 13-2: Creating a Table with Indexes
Overview
In this practice, you create a table with indexes.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately five minutes to complete.

Tasks
1. At a Linux terminal prompt, connect to the MySQL server with the mysql command-line
client.
2. Create a new table called Indexed in the dbtest database with two columns:
- c1 of data type INT
ble
- c2 of data type VARCHAR (width of 50)
fe r a
Index both these columns with a single index.
ans
3. Show the CREATE TABLE statement for the Indexed table, and confirm the proper column n - t r
o
attributes and indexes (shown as keys).
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 5
Solutions 13-2: Creating a Table with Indexes
Tasks
1. At a Linux terminal prompt, connect to the MySQL server with the mysql command-line
client.
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -u root -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql>
2. Create a new table called Indexed in the dbtest database with two columns:
- c1 of data type INT
- c2 of data type VARCHAR (width of 50)
ble
Index both these columns with a single index.
fe r a
Enter the following statements at the mysql prompt, and receive the results shown: ans
n - t r
no
mysql> USE dbtest
Reading table information
s a
...
h a
Database changed
ฺ b r) deฺ
mysql> CREATE TABLE Indexed (
c o m Gui
-> c1 INT,
p a rฺ ent
->
->
c2 VARCHAR(50),
INDEX (c1, c2)
s o ne Stud
-> );
c i @ (#.##t h issec)
t o ฺ ric use
Query OK, 0 rows affected
3. Show the CREATE rTABLE statementtoas keys).
for the Indexed table, and confirm the proper column
b e e
c (ro cestatement
attributes and indexes
i following ns at the mysql prompt, and receive the results shown:
(shown
Entercthe
R i li
erto *************************** 1. row ***************************
mysql> SHOW CREATE TABLE Indexed\G
b
Ro Table: Indexed
Create Table: CREATE TABLE `Indexed` (
`c1` int(11) DEFAULT NULL,
`c2` varchar(50) DEFAULT NULL,
KEY `c1` (`c1`,`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (#.## sec)
− Note the KEY called c1, and the index that uses both columns.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 6
Practice 13-3: Altering the Indexes in an Existing Table
Overview
In this practice, you use an ALTER TABLE statement to change the indexes in an existing table.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately five minutes to complete.

Tasks
1. Add a primary key to the Indexed table, in the c1 column.
2. Show the CREATE TABLE statement for the Indexed table, and confirm the creation of the
primary key.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 7
Solutions 13-3: Altering the Indexes in an Existing Table
Tasks
1. Add a primary key to the Indexed table, in the c1 column.
Enter the following statement at the mysql prompt, and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> ALTER TABLE Indexed ADD PRIMARY KEY (c1);


Query OK, 0 rows affected (#.## sec)
Records: 0 Duplicates: 0 Warnings: 0
2. Show the CREATE TABLE statement for the Indexed table, and confirm the creation of the
primary key.
Enter the following statement at the mysql prompt, and receive the results shown:
mysql> SHOW CREATE TABLE Indexed\G
*************************** 1. row ***************************
ble
Table: Indexed
fe r a
Create Table: CREATE TABLE `Indexed` (
ans
`c1` int(11) NOT NULL DEFAULT '0',
n - t r
`c2` varchar(50) DEFAULT NULL,
o
PRIMARY KEY (`c1`),
s an
ha ฺ
KEY `c1` (`c1`,`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (#.## sec) r )
ฺb uide
− Note the new PRIMARY KEY designation.co m G
a r ฺ n t
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 8
Practice 13-4: Removing an Existing Index
Overview
In this practice, you use a DROP INDEX statement to remove an index from an existing table.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately five minutes to complete.

Tasks
1. Remove the primary key from the Indexed table.
2. Show the CREATE TABLE statement for the Indexed table, and confirm the removal of the
primary key.
3. Drop the dbtest database.
ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 9
Solutions 13-4: Removing an Existing Index
Tasks
1. Remove the primary key from the Indexed table.
Enter the following statement at the mysql prompt, and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> DROP INDEX `PRIMARY` ON Indexed;


Query OK, 0 rows affected (#.## sec)
Records: 0 Duplicates: 0 Warnings: 0
− The key name needs to be quoted, because PRIMARY is a reserved word in
MySQL.
2. Show the CREATE TABLE statement for the Indexed table, and confirm the removal of the
primary key.
Enter the following statement at the mysql prompt, and receive the results shown:
ble
mysql> SHOW CREATE TABLE Indexed\G
fe r a
*************************** 1. row ***************************
ans
Table: Indexed
n - t r
Create Table: CREATE TABLE `Indexed` (
`c1` int(11) NOT NULL DEFAULT '0', a no
`c2` varchar(50) DEFAULT NULL,
h a s
KEY `c1` (`c1`,`c2`)
ฺ b r) deฺ
) ENGINE=InnoDB DEFAULT CHARSET=latin1
c o m Gui
rฺpresent
1 row in set (#.## sec)
− Note that the PRIMARY KEY is no longer p a e n t
in the table creation statement.
3. Drop the dbtest database.
s one s Stud
Enter the following statementcat
i c i@ t hi prompt and receive the results shown:
the mysql
e
t
mysql> DROP DATABASE
r o ฺr dbtest;us (#.## sec)
Query OK, e t o
rob ense
0 rows affected

i (
R icc lic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 10
Practice 13-5: Using Optimization Techniques
Overview
In this practice, you use various optimization techniques.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately 20 minutes to complete.

Tasks
1. Using an EXPLAIN statement, display information from the optimizer about the query
execution plan for the following query of the sakila database:
SELECT * FROM actor WHERE first_name = 'Whoopi'
2. Add an index on the first_name column in the actor table. ble
3. Verify that the optimizer can use the new index by reissuing the previous EXPLAIN fe r a
statement. ans
n - t r
4.
no
Using an EXPLAIN statement, display information from the optimizer about the query
execution plan for the following statement: a
h a s
r) ondetheฺ actor table.
SELECT * FROM actor WHERE actor_id = 22
b
5. Use a SHOW… statement to display information about all ฺindexes
m customers i
ฺ c o G u
and year, then you would need to aggregate a r
6. If you wanted to find the total amounts paid by video
p ude
this
t
rental
n
information for each
for a particular month
query. If many users
n e t
o s Sthis could cause a performance impact.
were executing similar queries simultaneously,
s
Instead, create a summary table
i c c @
e hi
i called tpayment_summary to improve the performance of
r
oฺ to us AS
these queries by entering the following
tpayment_summary
statement:

b e r
se
CREATE TABLE
SELECTro
i ( n
customer_id,
e
R cc licamount FROM payment_date) yearmonth,
iEXTRACT(YEAR_MONTH
SUM(amount)

berto FROM payment


Ro
GROUP BY 1,2
ORDER BY 2,1;
7. Create an index called ym on the yearmonth column of payment_summary.
8. Query the payment_summary table to find the highest paying customer in June 2005.
9. Query the payment_summary table to find the month with the lowest total payment
amount.
10. Query the payment_summary table to find the largest total amount spent by a single
customer.
11. Exit the mysql client program and keep the Linux terminal window open for the next
practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 11
Solutions 13-5: Using Optimization Techniques
Tasks
1. Using an EXPLAIN statement, display information from the optimizer about the query
execution plan for the following query of the sakila database:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

SELECT * FROM actor WHERE first_name = 'Whoopi'


a. Make sakila the current database:
mysql> USE sakila
Reading table information
...
Database changed
b. Enter the following statement at the mysql prompt, and receive the results shown:
mysql> EXPLAIN SELECT * FROM actor WHERE first_name = 'Whoopi'\G
ble
*************************** 1. row ***************************
fe r a
id: 1
ans
select_type: SIMPLE
n - t r
table: actor
type: ALL
a no
possible_keys: NULL
h a s
key: NULL
ฺ b r) deฺ
key_len: NULL
ref: NULL
c o m Gui
rows: 200
p a rฺ ent
one s Stud
Extra: Using where
1 row in set (#.## sec)
s
− The null values for keys
i c c i@
e hi the query will not use any indexes. The value
indicatetthat
ฺr columnuindicates
of 200 in the rows s that the query requires a full table scan to
execute. erto t o
r o b the first_name
s e
c i ( cen
2. Add an index on column in the actor table.
Enter
R li statement at the mysql prompt, and receive the results shown:
icthe following
berto mysql> ALTER TABLE actor ADD INDEX fname(first_name);
Ro
Query OK, 0 rows affected (#.## sec)
Records: 0 Duplicates: 0 Warnings: 0
3. Verify that the optimizer can use the new index by reissuing the previous EXPLAIN
statement.
Enter the following statement at the mysql prompt, and receive the results shown:
mysql> EXPLAIN SELECT * FROM actor WHERE first_name = 'Whoopi'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: actor
type: ref
possible_keys: fname
key: fname
key_len: 137
ref: const
rows: 1
Extra: Using index condition
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 12
− Note that the number of rows the query has to read drops from 200 to 1 and that the
query will use the fname index key.
4. Using an EXPLAIN statement, display information from the optimizer about the query
execution plan for the following statement:
SELECT * FROM actor WHERE actor_id = 22
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt, and receive the results shown:
mysql> EXPLAIN SELECT * FROM actor WHERE actor_id=22\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: actor
type: const
possible_keys: PRIMARY
key: PRIMARY
ble
key_len: 2
ref: const fe r a
rows: 1
ans
Extra: NULL
n - t r
1 row in set (#.## sec)
n o
s
− Note that the query has to read a single row, and that the optimizer a will use the
PRIMARY key. h a
5. Use a SHOW… statement to display information aboutm br) on
all ฺindexes i d etheฺ actor table.
ฺ c oand receiveG uthe results shown:
r
Enter the following statement at the mysql prompt,
a den t
mysql> SHOW INDEX FROM actor\Gep
s on1. rowS tu
***************************
Table: actor i@
c thi s ***************************

Non_unique: 0ric e
Key_name: r t ฺ
oPRIMARY
t o us
o b e 1 e
Seq_in_index:
i ( r
Column_name:
e n s
actor_id
c
ic Cardinality: c
li A200
Collation:
R
berto Sub_part: NULL

Ro Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: actor
Non_unique: 1
Key_name: idx_actor_last_name
Seq_in_index: 1
Column_name: last_name
Collation: A
Cardinality: 200
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 3. row ***************************

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 13
Table: actor
Non_unique: 1
Key_name: fname
Seq_in_index: 1
Column_name: first_name
Collation: A
Cardinality: 200
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
3 rows in set (#.## sec)
6. If you wanted to find the total amounts paid by video rental customers for a particular month
and year, then you would need to aggregate this information for each query. If many users
ble
were executing similar queries simultaneously, this could cause a performance impact.
fe r a
Instead, create a summary table called payment_summary to improve the performance of
ans
these queries.
n - t r
no
Enter the following statement at the mysql prompt, and receive the results shown:
a
mysql> CREATE TABLE payment_summary AS
h a s
-> SELECT customer_id,
ฺ b )
ryearmonth,
e ฺ
-> EXTRACT(YEAR_MONTH FROM payment_date)
om t Gu i d
-> SUM(amount) amount
r ฺ
a denc
-> FROM payment
e p
-> GROUP BY 1,2
-> ORDER BY 2,1; s on s Stu
Query OK, 2466 rows affected
c i sec)
i@ 0 t(#.##
hWarnings:
ฺ r
Records: 2466 Duplicates: i c s e 0
t o u
r ym ontothe yearmonth column of payment_summary.
e
7. Create an index called
b
(
Enter thei following n se at the mysql prompt, and receive the results shown:
ro estatement
R cc CREATE
imysql> lic INDEX ym ON payment_summary(yearmonth);
e r to Query OK, 0 rows affected (#.## sec)

R ob Records: 0 Duplicates: 0 Warnings: 0


8. Query the payment_summary table to find the highest paying customer in June 2005.
Enter the following statement at the mysql prompt, and receive the results shown:
mysql> SELECT customer_id, amount FROM payment_summary
-> WHERE yearmonth='200506' ORDER BY 2 DESC LIMIT 1;
+-------------+--------+
| customer_id | amount |
+-------------+--------+
| 454 | 52.90 |
+-------------+--------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 14
9. Query the payment_summary table to find the month with the lowest total payment
amount.
Enter the following statement at the mysql prompt, and receive the results shown:
mysql> SELECT yearmonth, SUM(amount) FROM payment_summary
-> GROUP BY 1 ORDER BY 2 LIMIT 1;
+-----------+-------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| yearmonth | SUM(amount) |
+-----------+-------------+
| 200602 | 514.18 |
+-----------+-------------+
1 row in set (#.## sec)
10. Query the payment_summary table to find the largest total amount spent by a single
customer.
Enter the following statement at the mysql prompt, and receive the results shown:
ble
mysql> SELECT customer_id, sum(amount) FROM payment_summary
fe r a
-> GROUP BY 1 ORDER BY 2 DESC LIMIT 1;
ans
+-------------+-------------+
n - t r
no
| customer_id | sum(amount) |
+-------------+-------------+
s a
| 526 | 221.55 |
h a
+-------------+-------------+
1 row in set (#.## sec)
ฺ b r) deฺ
o m window u i open for the next
11. Exit the mysql client program and keep the Linux
a cterminal
rฺ ent G
practice. p
Enter the following at the mysql prompt
s S tudthe message shown:
oneandsreceive
mysql> EXIT
c c i@ thi
Bye
o ฺ r i u se
#
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 15
Practice 13-6: Identifying and Fixing Slow Queries with MySQL
Enterprise Monitor Query Analyzer
Overview
In this practice, you use MySQL Enterprise Monitor’s Query Analyzer module to identify and
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

resolve a poorly performing query.

Duration
This practice should take approximately 15 minutes to complete.

Tasks
1. Execute the following commands at a Linux terminal prompt to install the employees
example database:
ble
# cd /stage/databases/employees_db
fe r a
# mysql -uroot -poracle -t < employees2.sql
ans
2. Check the status of the MySQL Enterprise Monitor service and start it if necessary.
n - t r
o
an
Enter the following commands at the Linux terminal prompt and receive the results shown:
s
# service mysql-monitor-server status
r ) ha ฺ
MySQL Enterprise MySQL is not running
m ฺb uide
MySQL Enterprise Tomcat is not running
a r ฺco nt G
ep tude
# service mysql-monitor-server start
Starting mysql service [ OK ] o n
s is S
i @ th
160518 11:49:02 mysqld_safe Logging to
c
r i c e
toฺ to us
'/opt/mysql/enterprise/monitor/mysql/runtime/mysqld.log'.
e r
160518 11:49:02 mysqld_safe Starting mysqld daemon with

i ( rob ense
databases from /opt/mysql/enterprise/monitor/mysql/data/
c lic
Ric
Starting tomcat service [ OK ]

e
3.
r to Open the Firefox web browser and navigate to https://localhost:18443.

R ob Note: Alternatively, you can use the bookmark that you created in the “Course Environment
Overview” activity in the lesson titled “Introduction to MySQL.”

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 16
4. Log in to MySQL Enterprise Monitor using the username monitormanager and password
oracle.
The Dashboard appears with a snapshot of the MySQL server activity for the last hour.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i
oฺ to us e
e r t
5. b instances”
Select the “MySQL
r o s e option from the Dashboard drop-down list.
ci ( ce n
R i c l i
e r to
R ob

6. Add the local MySQL server running on port 3306 to the list of MySQL instances:
a. Click the “Add MySQL Instance” button.
b. In the dialog box that appears, enter the following information:
− Instance address: localhost
− Port: 3306
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 17
− Admin User: root
− Admin User: oracle
− Auto-Create Less Privileged Users: Yes
− General User: general
− General Password: oracle
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

− Limited User: limited


− Limited Password: oracle
The dialog box should appear as follows:

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

7. Click the “Add Instance” button.


8. Wait for the page to refresh and ensure that the local MySQL server instance on port 3306
appears in the list of instances.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 18
9. Click the Query Analyzer link at the top of the display. Ensure that “Query Analysis
Reporting – Query Response Time Index (Aggregate)” is selected in the drop-down list.
The Query Analyzer shows the query response time information for all queries that have
executed in the last 30 minutes.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
10. Change the refresh e t
rinterval intothe top-right corner of the page to “Every 10 Seconds.”
b
ro thaneone e
sinstance
c i (
11. If there is more
c n in the list of running instances on the left of the page,

R i
ensure c that you l i
select the local MySQL server instance running on port 3306.

erto
12. Execute the following query against the employees database by using the mysql
b command-line client:
Ro SELECT * FROM employees, salaries
WHERE employees.emp_no = salaries.emp_no
ORDER BY salary DESC LIMIT 10
Note how the query takes several seconds to execute.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 19
13. When the MySQL Enterprise Monitor Query Analyzer refreshes, click the “Database”
column in the grid to view the queries against the employees database at the top of the
grid. Note how the Query Response Time Index (QRTi) column entry for the query you just
executed displays in red. This is because MySQL Enterprise Monitor has determined that
the execution time for the query is unacceptable.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
14. Click the query in the grid to display detailed information about the query. n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 20
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Note the execution time, the row statistics, the execution summary and when the query was
first seen. Query Analyzer has determined that the query requires a full table scan, which
frequently results in poor performance.
15. Close the detailed query information dialog box by clicking the Close button.
16. Use the mysql command-line client to execute an EXPLAIN statement to verify that this
query requires a full table scan.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> EXPLAIN SELECT * FROM employees, salaries
-> WHERE employees.emp_no = salaries.emp_no
-> ORDER BY salary DESC LIMIT 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 21
table: employees
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

rows: 299600
filtered: 100.00
Extra: Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: salaries
partitions: NULL
type: ref
possible_keys: PRIMARY,emp_no ble
key: PRIMARY
fe r a
key_len: 4
ans
ref: employees.employees.emp_no
n - t r
rows: 9
filtered: 100.00
a no
Extra: NULL
h a s
The EXPLAIN statement shows that MySQL performs a full
ฺ b ) scan
rtable e ฺon the employees
table which examines nearly 300,000 rows. It joins o m rowG
each of u i d
the employees table to the
salaries table and examines nine rows for a r ฺcjoinednrow.
each t Therefore in total, this query
examines over one million rows each time
o n t u de The ORDER BY clause also results
eitpis executed.
in the creation of a temporary tablesand the use
i s Sof a filesort operation, which both
increase the amount of file I/O. c i @
If many t h
users execute this query repeatedly it will result in a
r i c e
significant performance
r t oฺimpact.
t o us
e
If you create anbindex on e
( ro theenumber
index to ireduce n s theofsalaries table’s salary column, the query can use the
operations required by the ORDER BY and LIMIT clauses.
17. Add
R icancindex tolthe
ic salaries table’s salary column by executing the following SQL at
bertothe mysql prompt:
Ro ALTER TABLE salaries ADD INDEX(salary)
The MySQL server takes several seconds to generate the index.
18. Modify the EXPLAIN statement you created in step 9 to force the MySQL server to use the
index on the salaries table’s salary column and compare the results with the previous
output:
mysql> EXPLAIN SELECT * FROM employees,
-> salaries FORCE INDEX(salary)
-> WHERE employees.emp_no = salaries.emp_no
-> ORDER BY salary DESC LIMIT 10;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: salaries
partitions: NULL
type: index
possible_keys: NULL
key: salary
key_len: 4
ref: NULL
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 22
rows: 10
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: employees
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: employees.salaries.emp_no
rows: 1
filtered: 100.00
Extra: NULL
2 rows in set, 1 warning (#.## sec) ble
Note how the use of the index drastically reduces the number of rows that MySQL mustsfe
r a
examine to execute the query and avoids the use of a temporary table and filesort.
- t r an
19. Execute the new query and examine the QRTi column entry for the query inoMySQL
n n
Enterprise Monitor Query Analyzer. The Query Response Time Index a is now acceptable:
a
h ฺs
b r )
ฺ uide
o m
a r ฺc nt G
20. Click the “monitormanager” button ato n
the
de and select “Log Out.”
etopp of thetupage
s allisrunningS
21. Drop the employees database
c i @
and exitth mysql sessions.
i c
ฺr at the
Enter the following command e
sLinux terminal prompt and receive the results shown:
r t o o u
be DATABASEt employees;
mysql> DROP
i o
Query(rOK,
e
6 rowsn seaffected (#.## sec)
R cc EXIT
imysql>
Bye
lic
b rtoStop the MySQL Enterprise Monitor service.
e22.
Ro Enter the following command at the Linux terminal prompt and receive the results shown:
# service mysql-monitor-server stop
Stopping tomcat service . [ OK ]
Stopping mysql service 160518 12:33:04 mysqld_safe mysqld from pid
file /opt/mysql/enterprise/monitor/mysql/runtime/mysqld.pid ended
. [ OK ]
#
23. Close any open Linux terminal windows:
# exit

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 23
Solution 13-6: Identifying and Fixing Slow Queries with MySQL
Enterprise Monitor Query Analyzer

There is no solution for this practice.


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 13: Query Optimization


Chapter 13 - Page 24
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 14:
Stored om
Routines u i
r ฺ c
a 14den t G
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 1
Practices for 14: Stored Routines
Practices Overview
These practices test your knowledge of stored routines. They assume that you are using the
Linux operating system environment provided in Oracle classrooms. For non-Oracle
classrooms, you might need to make some adjustments to file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The sakila sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 2
Practice 14-1: Creating Simple Stored Routines
Overview
In this practice, you create two stored routines: a stored procedure and a stored function.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately ten minutes to complete.

Tasks
1. Log in to the mysql command-line client and create a new database called
storedroutines.
2. Create a stored procedure in the storedroutines database called hello. The hello
stored procedure should accept no parameter arguments and simply display the message
“Hello world!” when executed. ble
fe r a
3. Execute the stored procedure hello.
ans
4. Create a stored function in the storedroutines database called hello. The hello
n - t r
o
an
stored function must return the string “Hello,” followed by the text value contained within the
input parameter. Use the CHAR(20) data type for the input parameter and CHAR(50)
s
for the return value.
r ) ha ฺ
5. ฺb uide
Invoke the hello stored function by issuing a suitable SELECT statement.
m
6. ฺconext npractice.
Leave the mysql command-line client open forrthe
a t G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 3
Solution 14-1: Creating Simple Stored Routines
Solution Steps
1. Log in to the mysql command-line client and create a new database called
storedroutines.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

a. Log in to mysql by entering the following at the Linux terminal prompt:


# mysql -uroot -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
b. Create the storedroutines database:
mysql> CREATE DATABASE storedroutines;
ble
Query OK, 1 row affected (#.## sec)
fe r a
2. Create a stored procedure in the storedroutines database called hello. The hello
ans
stored procedure should accept no parameter arguments and simply display the message
n - t r
“Hello world!” when executed.
a no
h a s
Enter the following statements at the mysql prompt and receive the results shown:
mysql> USE storedroutines;
ฺ b r) deฺ
Reading table information
c o m Gui
rฺ ent
...
Database changed
p a
s
mysql> CREATE PROCEDURE hello()one s Stud
i c
Query OK, 0 rowsraffected thi sec)
c @ e(#.##
-> SELECT 'Hello iworld!';

r us
toฺ tohello.
3. Execute the storede procedure
( rob estatement
Enter the following
i n se at the mysql prompt and receive the results shown:
R cc CALL
imysql> lichello();
erto | Hello world! |
+--------------+
b
Ro +--------------+
| Hello world! |
+--------------+
1 row in set (#.## sec)

Query OK, 0 rows affected (#.## sec)


4. Create a stored function in the storedroutines database called hello. The hello
stored function must return the string “Hello, ” followed by the text value contained within
the input parameter. Use the CHAR(20) data type for the input parameter and
CHAR(50) for the return value.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE FUNCTION hello(input CHAR(20))
-> RETURNS CHAR(50)
-> RETURN CONCAT('Hello, ', input, '!');
Query OK, 0 rows affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 4
5. Invoke the hello stored function by issuing a suitable SELECT statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Hello, world! |
+----------------+
1 row in set (#.## sec)
6. Leave the mysql command-line client open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 5
Practice 14-2: Creating Stored Routines with Compound Statements
Overview
In this practice, you create a stored routine, which contains compound statements. Because of
the length of the routine, you might prefer to enter your code using MySQL Workbench instead
of the mysql command-line client.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately ten minutes to complete.

Tasks
1. Change the current database to sakila and create the film_info stored procedure with
the following code:
ble
DELIMITER //
fe r a
CREATE PROCEDURE film_info(IN f_id int)
BEGIN
ans
SELECT title FROM film
n - t r
WHERE film_id = f_id;
a no
SELECT first_name, last_name FROM actor
WHERE actor_id IN (
h a s
SELECT actor_id FROM film_actor
ฺ b r) deฺ
WHERE film_id = f_id);
c o m Gui
SELECT name FROM category
WHERE category_id IN(
p a rฺ ent
WHERE film_id = f_id); s one s Stud
SELECT category_id FROM film_category

END//
c c i@ thi
DELIMITER ;
o ฺ r i u se
t
r thetostored procedure film_info. This procedure takes a film ID
− This codeecreates
b se and returns the name of the film, the actors appearing in the
roinput parameter
as (an
i
cfilm, andlithee n
c film category.
2.
to Ric
Invoke the film_info stored procedure with a suitable CALL statement.
e r
R ob 3. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 6
Solution 14-2: Creating Stored Routines with Compound Statements
Solution Steps
1. Change the current database to sakila and create the film_info stored procedure:
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> USE sakila


Reading table information
...
Database changed

mysql> DELIMITER //
mysql> CREATE PROCEDURE film_info(IN f_id int)
-> BEGIN
-> SELECT title FROM film
-> WHERE film_id = f_id; ble
-> SELECT first_name, last_name FROM actor
fe r a
-> WHERE actor_id IN (
ans
-> SELECT actor_id FROM film_actor
n - t r
->
->
WHERE film_id = f_id);
SELECT name FROM category a no
-> WHERE category_id IN(
h a s
-> SELECT category_id FROM film_category
ฺ b r) deฺ
->
-> END//
WHERE film_id = f_id);
c o m Gui
Query OK, 0 rows affected (#.## sec)
p a rฺ ent
mysql> DELIMITER ;
s one s Stud
c
− This procedure is a compound
i c e t hi
i@ statement, which contains three queries and two
subqueries. When
t o ฺ r you
u s
invoke the procedure, you get three resultsets. The
DELIMITER
b e r statement t o changes the delimiter so that you can use semicolons in the
(ro PROCEDURE
CREATE e
ns statement without terminating the statement after each query.
c i li c e
R ic the film_info
2. Invoke stored procedure with a suitable CALL statement.

bertoEnter the following statement at the mysql prompt and receive the results shown:
Ro mysql> CALL film_info(51);
+------------------+
| title |
+------------------+
| BALLOON HOMEWARD |
+------------------+
1 row in set (#.## sec)

+------------+-----------+
| first_name | last_name |
+------------+-----------+
| PARKER | GOLDBERG |
| MENA | TEMPLE |
| GARY | PENN |
| RICHARD | PENN |
| RENEE | BALL |
| ROCK | DUKAKIS |
+------------+-----------+
6 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 7
+-------+
| name |
+-------+
| Music |
+-------+
1 row in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Query OK, 0 rows affected (#.## sec)


− Feel free to experiment with different film IDs.
3. Leave the mysql command-line client open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 8
Practice 14-3: Creating Stored Routines with Parameter Declarations
Overview
In this practice, you create a stored function and a stored procedure that both take parameters.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately 15 minutes.

Tasks
1. Create a stored function called actor_name in the sakila database with the following
code:
CREATE FUNCTION actor_name(a_id int)
RETURNS varchar(91)
BEGIN ble
DECLARE f, l varchar(45);
fe r a
SELECT first_name, last_name INTO f, l
ans
FROM actor
n - t r
WHERE actor_id = a_id;
RETURN CONCAT(f, ' ', l); a no
END
h a s
ฺ b r) namedeofฺthat actor.
− Given an actor’s ID, the stored function returns the full
2. Invoke the actor_name stored function with a suitable o mSELECT u i
statement.
3. In the storedroutines database, create a a
c
rฺ encalled
procedure
G
t select_params that
p
necode S d
displays three values passed into it. The
s o tufollows:
is as

i
CREATE PROCEDURE select_params
c @ INT,t h isINOUT param3 INT)
(IN param1 INT, OUT

SELECT param1,oparam2,
t ric uparam3;
se
param2

b e r different
to user variables by entering the following statement:
4. Assign values to three
(ro = n100, s e
c
SETc i @value1ce
l i @value2 = 200, @value3 = 300;
i
R the select_params stored procedure by using the three variables assigned.
5. oCall
e r t
b 6. In the storedroutines database, create a procedure called change_params with the
Ro following code:
CREATE PROCEDURE change_params
(IN param1 INT, OUT param2 INT, INOUT param3 INT)
SET param1 = 1 , param2 = 2, param3 = 3;
7. Execute change_params, passing in the variables declared in step 4 as parameters:
CALL change_params(@value1,@value2, @value3);
8. Inspect the values that have been assigned to the three variables by the change_params
stored procedure, and explain the result:
SELECT @value1, @value2, @value3;
9. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 9
Solution 14-3: Creating Stored Routines with Parameter Declarations
Solution Steps
1. Create a stored function called actor_name in the sakila database.
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> USE sakila;


Reading table information
...
Database changed
mysql> DELIMITER //
mysql> CREATE FUNCTION actor_name(a_id int)
-> RETURNS varchar(91)
-> BEGIN
-> DECLARE f, l varchar(45);
-> SELECT first_name, last_name INTO f, l ble
-> FROM actor
fe r a
-> WHERE actor_id = a_id;
ans
-> RETURN CONCAT(f, ' ', l);
n - t r
-> END//
Query OK, 0 rows affected (#.## sec) a no
h a s
mysql> DELIMITER ;
ฺ b r) deฺ
2. Invoke the actor_name stored function with a suitable
o SELECT i
m Gustatement.
a
Enter the following statements at the mysql prompt
c
rฺ and n t the results shown:
receive
p e
mysql> SELECT actor_name(1);ne
s o S tud
+------------------+ @
c i t h is
| actor_name(1) ic|
t o ฺ r u se
e r
+------------------+
b to
(ro cens
| PENELOPE GUINESS e |
c i li (#.## sec)
R i1c row in set
+------------------+

berto − Try using different values for actor_id.


Ro 3. In the storedroutines database, create a procedure called select_params that
displays three values passed into it.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> USE storedroutines
Reading table information
...
Database changed

mysql> CREATE PROCEDURE select_params


-> (IN param1 INT, OUT param2 INT, INOUT param3 INT)
-> SELECT param1, param2, param3;
Query OK, 0 rows affected (#.## sec)
4. Assign values to three different user variables.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SET @value1 = 100, @value2 = 200, @value3 = 300;
Query OK, 0 rows affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 10
5. Call the select_params stored procedure by using the three variables assigned.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CALL select_params (@value1,@value2, @value3);
+--------+--------+--------+
| param1 | param2 | param3 |
+--------+--------+--------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| 100 | NULL | 300 |


+--------+--------+--------+
1 row in set (#.## sec)
− The displayed value of param2 is NULL because the parameter is declared as an
OUT parameter, so any value passed is ignored by the procedure.
6. In the storedroutines database, create a procedure called change_params with the
following code.
Enter the following statement at the mysql prompt and receive the results shown:
ble
mysql> CREATE PROCEDURE change_params
fe r a
-> (IN param1 INT, OUT param2 INT, INOUT param3 INT)
ans
-> SET param1 = 1 , param2 = 2, param3 = 3;
n - t r
Query OK, 0 rows affected (#.## sec)
n o
7. Execute change_params, passing in the variables declared in steps4 as parameters. a
Enter the following statement at the mysql prompt and receive r ) hthea results
ฺ shown:
ฺ b
m @value3); id e
mysql> CALL change_params(@value1, @value2,
c o G u
Query OK, 0 rows affected (#.## sec)
p a rฺ ent
− There is no output from the procedure,
o n e tud there is no query within the
because
procedure. s is S
@assigned
8. Inspect the values that havec
c i
been th to the three variables by the change_params

stored procedure, andoexplain r i the s e
uresult.
e r t t o
r o b statement
Enter the following
s e at the mysql prompt and receive the results shown:
(
ci SELECT
mysql> n
ce @value1, @value2, @value3;
i c l i
R | @value1 | @value2 | @value3 |
+---------+---------+---------+

e r t o
b +---------+---------+---------+
Ro | 100 | 2 | 3 |
+---------+---------+---------+
1 row in set (#.## sec)
− Answer: The change_params stored procedure affects the OUT parameter
argument @value2 and the INOUT parameter argument @value3, but does not
change the IN parameter argument @value1.
9. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 11
Practice 14-4: Examining Stored Routines
Overview
In this practice, you examine stored routine metadata.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately ten minutes to complete.

Tasks
1. Execute SHOW CREATE PROCEDURE for the select_params procedure created in the
preceding practice.
2. Execute SHOW CREATE FUNCTION for the hello function created in the first practice.
3. Issue a statement that displays the status of all stored procedures in the sakila database.
bl e
4. Issue a statement that displays the status of all stored functions in the sakila database. ra
5. Query the INFORMATION_SCHEMA database for information about all stored routines n
ins fe
the
sakila database. n - tra
Leave the mysql command-line client open for the next practice. a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 12
Solution 14-4: Examining Stored Routines
Solution Steps
1. Execute SHOW CREATE PROCEDURE for the select_params procedure created in the
preceding practice.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> SHOW CREATE PROCEDURE select_params\G


*************************** 1. row ***************************
Procedure: select_params
sql_mode:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER
ROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE
`select_params`(IN param1 INT, OUT param2 INT, INOUT param3 INT)
ble
SELECT param1, param2, param3
character_set_client: utf8
fe r a
collation_connection: utf8_general_ci
ans
Database Collation: latin1_swedish_ci
n - t r
1 row in set (#.## sec)
n o
− The output displays the procedure name, sql_mode used, and a
s the SQL used to
create the procedure. h a
) ineฺthe first practice.
ฺ b rcreated
2. Execute SHOW CREATE FUNCTION for the hello function
o mreceive u id
a r ฺ
Enter the following statement at the mysql prompt c and
n t G the results shown:
mysql> SHOW CREATE FUNCTION hello\G
o n ep t u de
***************************
Function:i@
s 1.
hello his
row S***************************

ฺ r i
sql_mode: cc se t
r to to u
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER
e
rob eFunction:
se CREATE DEFINER=`root`@`localhost` FUNCTION
ROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
i (
Create n
R cc
i`hello`(inputlic CHAR(20)) RETURNS char(50) CHARSET latin1
to character_set_client: utf8
RETURN CONCAT('Hello, ', input, '!')
e r
R ob collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
1 row in set (#.## sec)
3. Issue a statement that displays the status of all stored procedures in the sakila database.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW PROCEDURE STATUS WHERE Db='sakila'\G
*************************** 1. row ***************************
Db: sakila
Name: film_info
Type: PROCEDURE
Definer: root@localhost
Modified: 2016-05-18 15:36:24
Created: 2016-05-18 15:36:24
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
*************************** 2. row ***************************
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 13
Db: sakila
Name: film_in_stock
Type: PROCEDURE
Definer: root@localhost
Modified: 2016-05-10 13:11:36
Created: 2016-05-10 13:11:36
Security_type: DEFINER
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
*************************** 3. row ***************************
Db: sakila
Name: film_not_in_stock
Type: PROCEDURE
Definer: root@localhost
Modified: 2016-05-10 13:11:36 ble
Created: 2016-05-10 13:11:36
fe r a
Security_type: DEFINER
ans
Comment:
n - t r
character_set_client: utf8 o
collation_connection: utf8_general_ci
s an
Database Collation: latin1_swedish_ci
r ) ha ฺ
*************************** 4. row ***************************
Db: sakila
m ฺb uide
Name: rewards_report
Type: PROCEDURE
a r ฺco nt G
n ep tude
Definer: root@localhost
o
s is S
Modified: 2016-05-10 13:11:36
@
i th
Created: 2016-05-10 13:11:36
c c
r i e
toฺ to us
Security_type: DEFINER

e r Comment: Provides a customizable report on best customers

rob ense
character_set_client: utf8

c i (
collation_connection: utf8_general_ci

Ric lic
Database Collation: latin1_swedish_ci
4 rows in set (#.## sec)
e r
4.
toIssue a statement that displays the status of all stored functions in the sakila database.
R ob Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW FUNCTION STATUS WHERE Db='sakila'\G
*************************** 1. row ***************************
Db: sakila
Name: actor_name
Type: FUNCTION
Definer: root@localhost
Modified: 2016-05-18 15:37:41
Created: 2016-05-18 15:37:41
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
*************************** 2. row ***************************
Db: sakila
Name: get_customer_balance
Type: FUNCTION
Definer: root@localhost

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 14
Modified: 2016-05-10 13:11:36
Created: 2016-05-10 13:11:36
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

*************************** 3. row ***************************


Db: sakila
Name: inventory_held_by_customer
Type: FUNCTION
Definer: root@localhost
Modified: 2016-05-10 13:11:36
Created: 2016-05-10 13:11:36
Security_type: DEFINER
Comment:
character_set_client: utf8 ble
collation_connection: utf8_general_ci
fe r a
Database Collation: latin1_swedish_ci
ans
*************************** 4. row ***************************
n - t r
Db: sakila
Name: inventory_in_stock
a no
Type: FUNCTION
h a s
Definer: root@localhost
ฺ b r) deฺ
Modified: 2016-05-10 13:11:36
c
Created: 2016-05-10 13:11:36 o m Gui
Security_type: DEFINER
p a rฺ ent
one s Stud
Comment:
character_set_client: utf8
s
c c i@ thi
collation_connection: utf8_general_ci
r i se
Database Collation: latin1_swedish_ci
o ฺ u
r t
4 rows in set (#.## sec)
e to database for information about all stored routines in the
b e
c i (ro cens
5. Query the INFORMATION_SCHEMA
database.
sakila
R li statement at the mysql prompt and receive the results shown:
icthe following
Enter
berto mysql> SELECT * FROM INFORMATION_SCHEMA.ROUTINES
Ro -> WHERE ROUTINE_SCHEMA = 'sakila'\G
*************************** 1. row ***************************
SPECIFIC_NAME: actor_name
ROUTINE_CATALOG: def
ROUTINE_SCHEMA: sakila
...
ROUTINE_DEFINITION: BEGIN
DECLARE f, l varchar(45);
SELECT first_name, last_name INTO f, l
FROM actor
WHERE actor_id = a_id;
RETURN CONCAT(f, ' ', l);
END
...
*************************** 8. row ***************************
SPECIFIC_NAME: rewards_report
ROUTINE_CATALOG: def
ROUTINE_SCHEMA: sakila
ROUTINE_NAME: rewards_report
ROUTINE_TYPE: PROCEDURE
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 15
...
DEFINER: root@localhost
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: latin1_swedish_ci
8 rows in set (#.## sec)
6. Leave the mysql command-line client open for the next practice.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 16
Practice 14-5: Deleting and Re-creating a Stored Routine
Overview
In this practice, you delete a stored routine and re-create it with new SQL code.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately ten minutes to complete.

Tasks
1. Connect to the storedroutines database.
2. Attempt to drop a nonexistent stored function called no_such_function.
3. Repeat the previous step using the IF EXISTS clause. Note any differences between the
outputs of the preceding steps.
ble
4. Display any warnings associated with the preceding task.
fe r a
5. Display the code for the hello stored function.
ans
6. Drop the hello function. Note any differences from earlier attempts to drop stored n - t r
functions in this practice. a no
7. Re-create the hello function with the following code: h a s
ฺ b r) deฺ
m Gui
CREATE FUNCTION hello (input CHAR(20))
RETURNS CHAR(100)

RETURN CONCAT('Hello, ', input, '! rWelcomec o t MySQL training.');
p a d e n to

oneSELECT
8. Invoke the hello function with a suitable
s S tustatement.
c i @ this
t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 17
Solution 14-5: Deleting and Re-creating a Stored Routine
Solution Steps
1. Connect to the storedroutines database.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> USE storedroutines;


Reading table information
...
Database changed
2. Attempt to drop a nonexistent stored function called no_such_function.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> DROP FUNCTION no_such_function;
ERROR 1305 (42000): FUNCTION storedroutines.no_such_function does not
ble
exist
fe r a
3. Repeat the previous step using the IF EXISTS clause. Note any differences between the
ans
outputs of the preceding steps.
n - t r
no
Enter the following statement at the mysql prompt and receive the results shown:
a
mysql> DROP FUNCTION IF EXISTS no_such_function; as
r ) h ฺ
Query OK, 0 rows affected, 1 warning (#.## sec)
− Task 2 resulted in an error; task 3 results in a m
b
ฺ uide
warning.
4. Display any warnings associated with the precedingr o
ฺc task.nt G
a dereceive the results shown:
epprompttuand
o n
Enter the following statement at the mysql
S
mysql> SHOW WARNINGS; @s i s
i
cc se t h
r i
+-------+------+---------------------------------------------------------+
| Level | Code | ฺMessage
e r to to u
+-------+------+---------------------------------------------------------+
|

| Note o
i ( r | b1305e|nsFUNCTION
e storedroutines.no_such_function does not exist |
i1ccrow in set lic (#.## sec)
+-------+------+---------------------------------------------------------+

R
be5.rtoDisplay the code for the hello stored function.
Ro Enter the following statement at the mysql prompt and receive the results:
mysql> SHOW CREATE FUNCTION hello\G
*************************** 1. row ***************************
Function: hello
sql_mode:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER
ROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION
`hello`(input CHAR(20)) RETURNS char(50) CHARSET latin1
RETURN CONCAT('Hello, ', input, '!')
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
1 row in set (#.## sec)
− The output displays the function name, the SQL modes that are used, and the code
used to create the function.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 18
6. Drop the hello function. Note any differences from earlier attempts to drop stored
functions in this practice.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> DROP FUNCTION IF EXISTS hello;
Query OK, 0 rows affected (#.## sec)
− The statement ends without any warnings.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

7. Re-create the hello function with the following code:


CREATE FUNCTION hello (input CHAR(20))
RETURNS CHAR(100)
RETURN CONCAT('Hello, ', input, '! Welcome to MySQL training.');
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE FUNCTION hello (input CHAR(20))
-> RETURNS CHAR(100)
ble
-> RETURN CONCAT('Hello, ', input,
fe r a
-> '! Welcome to MySQL training.');
ans
Query OK, 0 rows affected (#.## sec)
n - t r
8. Invoke the hello function with a suitable SELECT statement. o
an
Enter the following statement at the mysql prompt and receive the results shown:
s
mysql> SELECT hello('Mark');
r ) ha ฺ
+-----------------------------------------+
m ฺ|b uide
| hello('Mark')
a r ฺco nt G
+-----------------------------------------+
| Hello, Mark! Welcome to MySQL
o n eptraining.
t u de |
s is S
+-----------------------------------------+
@
1 row in set (#.## sec)
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 19
Practice 14-6: Creating Stored Routines with Flow Control Statements
Overview
In this practice, you write functions and procedures that use flow control statements.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately 25 minutes to complete.

Tasks
1. Create the docase function in the storedroutines database by using the following SQL
code:
CREATE FUNCTION docase (1st_Num DOUBLE(10,2),
2nd_Num DOUBLE(10,2), formula_type CHAR(15))
ble
RETURNS CHAR(30)
BEGIN fe r a
CASE formula_type
ans
WHEN 'Multiplication' THEN
n - t r
o
an
RETURN CONCAT(1st_Num,' * ',2nd_Num,' = ',
1st_Num * 2nd_Num);
WHEN 'Division' THEN s
ha ฺ
r )
ฺb uide
RETURN CONCAT(1st_Num,' / ',2nd_Num,' = ',
m
1st_Num / 2nd_Num);
WHEN 'Addition' THEN
a r ฺco nt G
ep tude
RETURN CONCAT(1st_Num,' + ',2nd_Num,' = ',

WHEN 'Subtraction' THEN o n


1st_Num + 2nd_Num);
s is S
c i @ th
RETURN CONCAT(1st_Num,' - ',2nd_Num,' = ',
r i c e
toฺ to us
1st_Num - 2nd_Num);
ELSE
e r
i ( rob ense
RETURN 'Invalid Formula Type';
END CASE;
c lic
Ric
END

e r
2. toTest the docase stored function with a suitable SELECT statement, performing an addition.
R ob 3. Test the docase stored function with a suitable SELECT statement, performing a division.
4. Test the docase stored function with a statement that attempts to perform an operation
called “invalid,” noting any issues.
5. Create the dorepeat stored procedure in the storedroutines database.
6. Test the dorepeat stored procedure with a suitable CALL statement.
7. Create the dowhile stored procedure in the storedroutines database.
8. Test the dowhile stored procedure with a suitable CALL statement. Are the outputs from
dorepeat and dowhile different? If so, why?
9. Create the doloopif stored procedure in the storedroutines database.
10. Test the doloopif stored procedure with a suitable CALL statement.
11. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 20
Solution 14-6: Creating Stored Routines with Flow Control Statements
Solution Steps
1. Create the docase function in the storedroutines database.
Enter the following statements at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> DELIMITER //
mysql> CREATE FUNCTION docase (1st_Num DOUBLE(10,2),
-> 2nd_Num DOUBLE(10,2), formula_type CHAR(15))
-> RETURNS CHAR(30)
-> BEGIN
-> CASE formula_type
-> WHEN 'Multiplication' THEN
-> RETURN CONCAT(1st_Num,' * ',2nd_Num,' = ',
-> 1st_Num * 2nd_Num);
-> WHEN 'Division' THEN ble
-> RETURN CONCAT(1st_Num,' / ',2nd_Num,' = ',
fe r a
-> 1st_Num / 2nd_Num);
ans
-> WHEN 'Addition' THEN
n - t r
->
->
RETURN CONCAT(1st_Num,' + ',2nd_Num,' = ',
1st_Num + 2nd_Num); a no
-> WHEN 'Subtraction' THEN
h a s
-> RETURN CONCAT(1st_Num,' - ',2nd_Num,' = ',
ฺ b r) deฺ
->
-> ELSE
c o m Gui
1st_Num - 2nd_Num);

-> RETURN 'Invalid Formula Type';


p a rฺ ent
one s Stud
-> END CASE;
-> END//
s
c c i@ thi
Query OK, 0 rows affected (#.## sec)

o ฺ i
r; use
mysql> DELIMITER
e t
r demonstratesto the use of the CASE flow control statement. The function
b
− This function e
c i (ro thecefirstnstwo parameters to be of data type DOUBLE(10,2). If you provide a
expects
i
Ric decimal lnumber for either of the first two parameters, the function truncates the
e r to value to two digits after the decimal point. The third parameter is the type of

R ob mathematical operation you want to perform on the numbers.


− The function selects which mathematical operation to use by testing the third
parameter with the CASE statement. It performs the correct operation on the values
and returns the result. If it cannot interpret the third parameter, it returns an error
message.
2. Test the docase stored function with a suitable SELECT statement, performing an addition.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT docase (10,5,'Addition');
+--------------------------+
| docase (10,5,'Addition') |
+--------------------------+
| 10.00 + 5.00 = 15.00 |
+--------------------------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 21
3. Test the docase stored function with a suitable SELECT statement, performing a division.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT docase (22.3785, 12.3, 'Division');
+-----------------------------------+
| docase (22.3785, 12.3,'Division') |
+-----------------------------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| 22.38 / 12.30 = 1.819512 |


+-----------------------------------+
1 row in set (#.## sec)
− In this statement, the docase function, expecting two values of type
DOUBLE(10,2), rounds its first parameter to 22.38 and expands the second
parameter to 12.30 before performing a division using the two numbers.
4. Test the docase stored function with a statement that attempts to perform an operation
called “invalid,” noting any issues.
ble
Enter the following statement at the mysql prompt and receive the results shown:
fe r a
mysql> SELECT docase (15, 5, 'invalid');
ans
+--------------------------+
n - t r
| docase (15, 5,'invalid') |
+--------------------------+ a no
| Invalid Formula Type |
h a s
+--------------------------+
ฺ b r) deฺ
1 row in set (#.## sec)
o m Gtype u i
− The function produces this error because
a r ฺ c
the formula
n t “invalid” does not exist,
causing the ELSE portion of the CASE
n e p ude
flow control statement to execute.
5. Create the dorepeat stored procedure so in ithe S t
storedroutines database.
Enter the following statements @
ci at theemysqls
th prompt and receive the results shown:
r i c
ฺ // us
mysql> DELIMITER
e r toPROCEDURE
to dorepeat (p1 INT)
b
mysql> CREATE
e
c i (roBEGIN
->
c e ns var_x INT;
R ic -> SET
-> li var_x = 0;
DECLARE

berto -> REPEAT SET var_x = var_x + 1;

Ro
-> SELECT CONCAT('The x variable is ', var_x)
-> AS Repeat_Counter;
-> UNTIL var_x > p1
-> END REPEAT;
-> SELECT CONCAT('The final REPEAT number is ',var_x)
-> AS Repeat_Results;
-> END//
Query OK, 0 rows affected (#.## sec)

mysql> DELIMITER ;
− This procedure demonstrates the use of the REPEAT flow control statement. The
procedure accepts a single integer parameter. The procedure counts from 0,
incrementing by 1, until it reaches the value of its parameter. The procedure then
displays the final value and exits.
6. Test the dorepeat stored procedure with a suitable CALL statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CALL dorepeat (10);
+---------------------+

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 22
| Repeat_Counter |
+---------------------+
| The x variable is 1 |
+---------------------+
1 row in set (#.## sec)

+---------------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Repeat_Counter |
+---------------------+
| The x variable is 2 |
+---------------------+
1 row in set (#.## sec)
...

+----------------------+
| Repeat_Counter |
+----------------------+ ble
| The x variable is 11 |
fe r a
+----------------------+
ans
1 row in set (#.## sec)
n - t r
+-------------------------------+
a no
| Repeat_Results |
h a s
+-------------------------------+
ฺ b r) deฺ
| The final REPEAT number is 11 |
+-------------------------------+
c o m Gui
1 row in set (#.## sec)
p a rฺ ent
Query OK, 0 rows affected o
s ne sec)
(#.## S tud
− The final value is 11.ci@ t h is
7. Create the dowhile o
t ฺ ric procedure
stored u se in the storedroutines database.
b e rstatementstoat the mysql prompt and receive the results shown:
Enter the following
i ( roDELIMITER
e n se//
R cc CREATE
mysql>
imysql> lic PROCEDURE dowhile (p1 INT)
erto
-> BEGIN
b -> DECLARE var_x INT;
Ro ->
->
SET var_x = 0;
WHILE var_x < p1 DO
-> SET var_x = var_x + 1;
-> SELECT CONCAT('The x variable is', var_x)
-> AS While_Counter;
-> END WHILE;
-> SELECT CONCAT('The final WHILE number is ', var_x)
-> AS While_Results;
-> END//
Query OK, 0 rows affected (#.## sec)

mysql> DELIMITER ;
8. Test the dowhile stored procedure with a suitable CALL statement. Are the outputs from
dorepeat and dowhile different? If so, why?
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CALL dowhile (10);
+---------------------+
| While_Counter |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 23
+---------------------+
| The x variable is 1 |
+---------------------+
1 row in set (#.## sec)

+---------------------+
| While_Counter |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+---------------------+
| The x variable is 2 |
+---------------------+
1 row in set (#.## sec)
...

+------------------------------+
| While_Results |
+------------------------------+
| The final WHILE number is 10 | ble
+------------------------------+
fe r a
1 row in set (#.## sec)
ans
n - t r
Query OK, 0 rows affected (#.## sec)
a no
− The final value is 10, because the WHILE loop checks the condition before entering
h a s
the loop, but the REPEAT loop checks the condition after performing the loop code,
incrementing the value of x one extra time. ฺ b r) deฺ
9. c o m Gui
Create the doloopif stored procedure in the storedroutines database:
Enter the following statements at the mysql p a rฺ and
prompt e n t the results shown:
receive
mysql> DELIMITER // s one s Stud
mysql> CREATE PROCEDURE
i c c e t hi (p1 INT)
i@doloopif
-> BEGIN
r t o ฺr INT; us
-> DECLARE
e var_x
b var_xse=0; t o
(
i -> IFo
-> SET
r n LOOP
c
i ->c
->
l i e
loop_test:
c var_x < p1 THEN

t o R SET var_x = var_x + 1;

be r -> ELSE

Ro ->
->
LEAVE loop_test;
END IF;
-> END LOOP loop_test;
-> SELECT CONCAT('The final LOOP and IF number is ',
-> var_x) AS Results;
-> END//
Query OK, 0 rows affected (#.## sec)

mysql> DELIMITER ;

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 24
10. Test the doloopif stored procedure with a suitable CALL statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CALL doloopif (1000);
+--------------------------------------+
| Results |
+--------------------------------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| The final LOOP and IF number is 1000 |


+--------------------------------------+
1 row in set (#.## sec)

Query OK, 0 rows affected (#.## sec)


11. Leave the mysql command-line client open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 25
Practice 14-7: Working with the DECLARE CONDITION and DECLARE
HANDLER Statements

Overview
In this practice, you work with conditions and handlers.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately ten minutes to complete.

Tasks
1. Create a table called handler_table in the storedroutines database with the
following statement:
CREATE TABLE handler_table (s1 int, primary key (s1));
ble
2. Create the dohandler stored procedure and explain how it works: fe r a
ans
CREATE PROCEDURE dohandler ()
n - t r
no
BEGIN
DECLARE dup_keys CONDITION FOR SQLSTATE '23000';
s a
DECLARE CONTINUE HANDLER FOR dup_keys SET @garbage = 1;
h a
SET @x = 1;
INSERT INTO storedroutines.handler_table VALUES (1);
ฺ b r) deฺ
SET @x = 2;
c o m Gui
a rฺ ent
INSERT INTO storedroutines.handler_table VALUES (1);
p
one s Stud
SET @x = 3;
END
s
3. Test the dohandler stored c
i c i@ with
procedure
e t hi a suitable CALL statement.
4. Check the value of the
r t o ฺr user variable
us assigned in the execution of the dohandler stored
e
@x
t o
procedure.
5. Checkc i
the
robof ethen@garbage
(value se
i c l i c procedure. user variable assigned in the execution of the
t o R
dohandler stored

be r
6. Keep the mysql command-line client open for the next practice.
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 26
Solution 14-7: Working with the DECLARE CONDITION and DECLARE
HANDLER Statements

Solution Steps
1. Create a table called handler_table in the storedroutines database with the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

following statement:
CREATE TABLE handler_table (s1 int, primary key (s1));
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE TABLE handler_table (s1 int, primary key (s1));
Query OK, 0 rows affected (#.## sec)
− The table contains a single column, s1, defined as a primary key.
2. Create the dohandler stored procedure and explain how it works.
ble
Enter the following statements at the mysql prompt and receive the results shown:
fe r a
mysql> DELIMITER //
ans
mysql> CREATE PROCEDURE dohandler ()
n - t r
-> BEGIN
-> DECLARE dup_keys CONDITION FOR SQLSTATE '23000'; a no
->
h a s
DECLARE CONTINUE HANDLER FOR dup_keys SET @garbage = 1;
-> SET @x = 1;
ฺ b r) deฺ
->
m Gui
INSERT INTO storedroutines.handler_table VALUES (1);
c o
->
->
SET @x = 2;
p a rฺ ent
INSERT INTO storedroutines.handler_table VALUES (1);

one s Stud
-> SET @x = 3;
-> END// s
c i@ thi
Query OK, 0 rows affected (#.## sec)
c
o ฺ i
r; use
mysql> DELIMITER
e t
r procedure to declares both a condition and a handler to demonstrate
b
− The dohandler e
o workntogether.
s
c i
how(rthey c e
i
Ri−c The firstlINSERT INTO statement enters a value into handler_table. The
e r to second INSERT INTO generates an error of type SQLSTATE 23000, which fires
R ob the handler declared with DECLARE CONTINUE HANDLER. This handler sets the
@garbage variable before continuing with the procedure.
3. Test the dohandler stored procedure with a suitable CALL statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CALL dohandler();
Query OK, 0 rows affected, 1 warning (#.## sec)
− The dohandler procedure runs without any errors, but raises a warning indicating
the duplicate key.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 27
4. Check the value of the @x user variable assigned in the execution of the dohandler stored
procedure.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT @x;
+------+
| @x |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+------+
| 3 |
+------+
1 row in set (#.## sec)
− The value of @x is 3, which shows that the procedure completed all its steps. If the
procedure did not handle the error correctly, it would have terminated before setting
the value to 3, and the value of @x would be 2.
5. Check the value of the @garbage user variable assigned in the execution of the
ble
dohandler stored procedure.
fe r a
Enter the following statement at the mysql prompt and receive the results shown:
ans
mysql> SELECT @garbage;
n - t r
+----------+
a no
| @garbage |
+----------+
h a s
| 1 |
ฺ b r) deฺ
+----------+
c o m Gui
1 row in set (#.## sec)
− The user-defined variable @garbage p a rฺ the value
has e n t 1, proving that the procedure
one did nottu
d
called the handler. If the procedure
s S call the handler, the value of @garbage
would be NULL.
c i @ this
6. ฺ
Keep the mysql command-line
t o ric client
u seopen for the next practice.
b e r to
(ro cens e
c i li
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 28
Practice 14-8: Creating a Stored Function to Retrieve Database
Metadata
Overview
In this practice, you create a function, which contains a cursor to traverse table rows together
with a handler that responds to the cursor reaching the end of the table, to demonstrate features
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

of stored routines.

Duration
This practice should take approximately 15 minutes to complete.

Tasks
1. Create the find_table function in the storedroutines database by using the following
SQL code: ble
fe r a
CREATE FUNCTION find_table (tbl_name CHAR(64))
ans
RETURNS INT
n - t r
BEGIN o
DECLARE result BOOL DEFAULT FALSE;
s an
DECLARE show_table CHAR(64);
DECLARE doneFlag BOOL DEFAULT FALSE; r ) ha ฺ
DECLARE q1 CURSOR FOR m ฺb uide
r ฺco nt G
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
a
o n ep tude
WHERE TABLE_SCHEMA = DATABASE();
DECLARE CONTINUE HANDLER FOR NOT FOUND SET doneFlag=true;
OPEN q1;
@ s is S
c c i th
doloop: LOOP
r i e
e r toฺ to us
FETCH q1 INTO show_table;

rob ense
IF doneFlag THEN

c i (LEAVE doloop;

Ric lic
END IF;

e r to IF show_table = tbl_name THEN


SET result = TRUE, doneFlag = TRUE;
R ob END IF;
END LOOP doloop;
CLOSE q1;
RETURN result;
END
2. Execute a SELECT statement that uses the find_table function, providing the parameter
value “no_such_table”.
3. Execute a SELECT statement that uses the find_table function, providing the name of a
valid table in the storedroutines database.
4. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 29
Solution 14-8: Creating a Stored Function to Retrieve Database
Metadata
Solution Steps
1. Create the find_table function in the storedroutines database.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> DELIMITER //
mysql> CREATE FUNCTION find_table (tbl_name CHAR(64))
-> RETURNS INT
-> BEGIN
-> DECLARE result BOOL DEFAULT FALSE;
-> DECLARE show_table CHAR(64);
-> DECLARE doneFlag BOOL DEFAULT FALSE;
-> DECLARE q1 CURSOR FOR
ble
-> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
fe r a
-> WHERE TABLE_SCHEMA = DATABASE();
ans
->
->
DECLARE CONTINUE HANDLER FOR NOT FOUND SET doneFlag=true;
OPEN q1;
n - t r
o
an
-> doloop: LOOP
->
->
FETCH q1 INTO show_table;
IF doneFlag THEN s
ha ฺ
-> LEAVE doloop; r )
ฺb uide
-> END IF; m
->
r ฺco nt G
IF show_table = tbl_name THEN
a
->
-> END IF;
o n ep tude
SET result = TRUE, doneFlag = TRUE;

-> END LOOP doloop;


@ s is S
-> CLOSE q1;
c c i th
r i e
toฺ to us
-> RETURN result;
e r
-> END //

i ( rob ense
Query OK, 0 rows affected (#.## sec)

cc DELIMITER
Rimysql> lic ;

e r to − The find_table function determines if a named table exists in the current

R ob database. If so, the function returns the number 1, to represent “true.” If the table
does not exist in the current database, the function returns 0, representing “false.”
− The function uses a query within a cursor to retrieve a list of tables from the
INFORMATION_SCHEMA database. The cursor processes the results of the query
one record at a time and sets the result variable to true if it finds a match.
2. Execute a SELECT statement that uses the find_table function, providing the parameter
value “no_such_table”.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT find_table ('no_such_table');
+------------------------------+
| find_table ('no_such_table') |
+------------------------------+
| 0 |
+------------------------------+
1 row in set (#.## sec)
− The table does not exist, so find_table returns 0, representing “false.”

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 30
3. Execute a SELECT statement that uses the find_table function, providing the name of a
valid table in the storedroutines database.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT find_table ('handler_table');
+------------------------------+
| find_table ('handler_table') |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+------------------------------+
| 1 |
+------------------------------+
1 row in set (#.## sec)
− In this case, the handler_table table exists, so the function returns the number 1,
representing “true.”
4. Leave the mysql command-line client open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 31
Practice 14-9: Additional Practice
Overview
In this practice, you create two more stored routines to test your knowledge of the concepts
learned in this lesson.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 20 minutes to complete.

Tasks
1. Create a function called c_length in the storedroutines database that returns the
length of a right-angled triangle’s longest side (hypotenuse) based on parameters
containing the lengths of the other two sides.
Hint: The square root function in MySQL is SQRT. ble
fe r a
2. Test the c_length function with the values 3 and 4.
ans
3. Review the details of the c_length procedure by using the INFORMATION_SCHEMA
n - t r
database.
a no
4. s
Create a function called factorial that calculates the factorial (n!) of a given value.
h a
5. Test the factorial function with the values 3 and 10.
ฺ b r) deฺ
6. Use SHOW CREATE FUNCTION to view the syntax used
o m to create
u i the factorial
function.
a c
rฺ ent G
p d window.
oneterminal
7. Exit the mysql client and close the Linux
s S tuprompt
c i @ this
t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 32
Solution 14-9: Additional Practice
Solution Steps
1. Create a function called c_length in the storedroutines database that returns the
length of a right-angled triangle’s longest side (hypotenuse) based on parameters
containing the lengths of the other two sides.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Hint: The square root function in MySQL is SQRT.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> DELIMITER //
mysql> CREATE FUNCTION c_length (side_a DOUBLE(10,2),
-> side_b DOUBLE(10,2))
-> RETURNS DOUBLE(10,2)
-> BEGIN
-> RETURN SQRT(side_a * side_a + side_b * side_b);
ble
-> END//
fe r a
Query OK, 0 rows affected (#.## sec)
ans
n - t r
no
mysql> DELIMITER ;
2. Test the c_length function with the values 3 and 4. a
sresults shown:
Enter the following statement at the mysql prompt and receive h a
the
ฺ b r) deฺ
mysql> SELECT c_length(3, 4);
c o m Gui
+----------------+
| c_length(3, 4) |
p a rฺ ent
+----------------+
| 5.00 | s one s Stud
+----------------+
c c i@ thi
1 row in set (#.##
o ฺ r i sec)
u se
3. Review the detailse t
rof the c_length
to procedure by using the INFORMATION_SCHEMA
database. (ro
b e
c i c e ns
Enter
R li statement at the mysql prompt and receive the results shown:
icthe following
berto mysql> SELECT * FROM INFORMATION_SCHEMA.ROUTINES
Ro
-> WHERE ROUTINE_NAME = 'c_length'\G
*************************** 1. row ***************************
SPECIFIC_NAME: c_length
ROUTINE_CATALOG: def
ROUTINE_SCHEMA: storedroutines
ROUTINE_NAME: c_length
ROUTINE_TYPE: FUNCTION
DATA_TYPE: double
CHARACTER_MAXIMUM_LENGTH: NULL
CHARACTER_OCTET_LENGTH: NULL
NUMERIC_PRECISION: 10
NUMERIC_SCALE: 2
DATETIME_PRECISION: NULL
CHARACTER_SET_NAME: NULL
COLLATION_NAME: NULL
DTD_IDENTIFIER: double(10,2)
ROUTINE_BODY: SQL
ROUTINE_DEFINITION: BEGIN
RETURN SQRT(side_a * side_a + side_b * side_b);
END
EXTERNAL_NAME: NULL
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 33
EXTERNAL_LANGUAGE: NULL
PARAMETER_STYLE: SQL
IS_DETERMINISTIC: NO
SQL_DATA_ACCESS: CONTAINS SQL
SQL_PATH: NULL
SECURITY_TYPE: DEFINER
CREATED: 2016-05-18 16:14:36
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

LAST_ALTERED: 2016-05-18 16:14:36


SQL_MODE:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER
ROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
ROUTINE_COMMENT:
DEFINER: root@localhost
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: latin1_swedish_ci
1 row in set (#.## sec) ble
4. Create a function called factorial that calculates the factorial (n!) of a given value. fe r a
ans
Enter the following statement at the mysql prompt and receive the results shown:
n - t r
o
an
mysql> DELIMITER //
mysql> CREATE FUNCTION factorial (n INT)
-> RETURNS INT
s
ha ฺ
-> BEGIN r )
ฺb uide
m
ฺco nt G
-> DECLARE result INT;
-> SET result = 1;
a r
->
->
WHILE n > 1 DO
o n ep tude
SET result = result * n;
-> SET n = n - 1;
@ s is S
-> END WHILE;
c c i th
r i e
->
e r
-> END//toฺ to us
RETURN result;

i ( rob ense
Query OK, 0 rows affected (#.## sec)

cc DELIMITER
Rimysql> lic ;

e r
5. toTest the factorial function with the values 3 and 10.
R ob Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT factorial(3);
+--------------+
| factorial(3) |
+--------------+
| 6 |
+--------------+
1 row in set (#.## sec)

mysql> SELECT factorial(10);


+---------------+
| factorial(10) |
+---------------+
| 3628800 |
+---------------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 34
6. Use SHOW CREATE FUNCTION to view the syntax used to create the factorial
function.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SHOW CREATE FUNCTION factorial\G
*************************** 1. row ***************************
Function: factorial
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

sql_mode:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER
ROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION
`factorial`(n INT) RETURNS int(11)
BEGIN
DECLARE result INT;
SET result = 1;
WHILE n > 1 DO
SET result = result * n; ble
SET n = n - 1;
fe r a
END WHILE;
ans
RETURN result;
n - t r
END o
character_set_client: utf8
s an
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
r ) ha ฺ
1 row in set (#.## sec)
m ฺb uide
7. Exit the mysql client and close the Linux terminal r o window.
ฺcprompt t G
a. Enter the following statement at the mysql
a
ep prompt: de n
o n
s is S t u
mysql> EXIT
c i @ th
Bye
r i c e
#
e r t oฺ to us
r o b
b. Enter the following
s e
command at the Linux terminal prompt:
ci
# exit( ce n
R i c l i
e r t o
b
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 35
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 14: Stored Routines


Chapter 14 - Page 36
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 15:
Triggers om and i
Scheduled
u
r ฺ
a denc t G
Events
p
e
on Chaptertu15
s s S
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 1
Practices for Lesson 15: Triggers and Scheduled Events
Practices Overview
These practices test your knowledge of triggers and scheduled events. They assume that you
are using the Linux operating system environment provided in Oracle classrooms. For
non-Oracle classrooms, you might need to make some adjustments to file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
• The sakila sample database is installed.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 2
Practice 15-1: Creating and Dropping Triggers
Overview
In this practice, you create various triggers to audit data modifications, and finally drop a trigger
that you no longer require.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately 25 minutes.

Tasks
1. Connect to the MySQL server by using the mysql command-line client and create a new
database called triggertest.
2. In the triggertest database, create a table called dotriggers with a single column
ble
called column1 of INT data type.
fe r a
3. Create a table called audit_triggers that contains the following columns:
ans
• old_column (INT)
n - t r
• new_column (INT)
a no
• date_completed (DATETIME) h a s
4. Create a trigger called dotriggers_ai by executing the ฺ b r) dstatement:
following e ฺ
i
om ONt dotriggers
u
CREATE TRIGGER dotriggers_ai AFTER INSERT
r ฺ
a denc G
FOR EACH ROW
e p
on s Stu date_completed)
INSERT INTO audit_triggers (new_column,
s
hi
VALUES (NEW.column1, NOW());
c c i@ thetdotriggers table.
o i
5. Insert the values 1 – 6 inclusive
ฺr rows into e
usin the previous step by issuing an appropriate SELECT
e t
6. Verify the insertion rof the new t o
statement. rob se
i ( e n
icc the execution
7. Confirm
R
statement.
lic of the dotriggers_ai trigger by issuing an appropriate SELECT
be8.rtoCreate a trigger called dotriggers_au by executing the following statement:
Ro CREATE TRIGGER dotriggers_au AFTER UPDATE ON dotriggers
FOR EACH ROW
INSERT INTO audit_triggers (old_column,
new_column,date_completed)
VALUES (OLD.column1, NEW.column1,NOW());
9. Update the dotriggers table, setting all values less than three to the new value of 10.
10. Verify the update in the previous step with a suitable SELECT statement.
11. Confirm the execution of the dotriggers_au trigger by issuing an appropriate SELECT
statement.
12. Create a trigger called dotriggers_ad by executing the following statement:
CREATE TRIGGER dotriggers_ad AFTER DELETE ON dotriggers
FOR EACH ROW
INSERT INTO audit_triggers(old_column, date_completed)
VALUES (OLD.column1, NOW());
13. Delete all rows from the dotriggers table with values greater than 2 and less than 10.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 3
14. Verify the deletion of the rows in the previous step by issuing an appropriate SELECT
statement.
15. Confirm the execution of the dotriggers_ad trigger by issuing an appropriate SELECT
statement.
16. Drop the dotriggers_ad trigger.
17. Delete all the rows in the dotriggers table.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

18. Verify the deletion in the previous step by issuing an appropriate SELECT statement.
19. Confirm that the dotriggers_ad trigger has not executed by issuing an appropriate
SELECT statement.
20. Leave the mysql command-line client open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 4
Solution 15-1: Creating and Dropping Triggers
Solution Steps
1. Connect to the MySQL server by using the mysql command-line client and create a new
database called triggertest.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -uroot -poracle


mysql: [Warning] Using a password on the command line interface can be
insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql> CREATE DATABASE triggertest;
Query OK, 1 row affected (#.## sec)

mysql> SHOW DATABASES;


+--------------------+
ble
| Database |
fe r a
+--------------------+
ans
| information_schema |
n - t r
no
| mysql |
| performance_schema |
s a
| sakila |
h a
| storedroutines
| sys
|
| ฺ b r) deฺ
| triggertest |
c o m Gui
| world |
p a rฺ ent
one s Stud
+--------------------+
8 rows in set (#.## sec)
s i called dotriggers with a single column
2. In the triggertest database,
c c i@ t
create a htable
called column1 of INTฺdata
o i
r type.us e
e r t
statementto
r o b
Enter the following
s e at the mysql prompt and receive the results shown:

c i ( USEchanged
mysql>
c e n
triggertest;
R i c
Database l i
ert o
b mysql> CREATE TABLE dotriggers (column1 INT);
Ro Query OK, 0 rows affected (#.## sec)
3. Create a table called audit_triggers that contains the following columns:
• old_column (INT)
• new_column (INT)
• date_completed (DATETIME)
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE TABLE audit_triggers (
-> old_column INT,
-> new_column INT,
-> date_completed DATETIME
-> );
Query OK, 0 rows affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 5
4. Create a trigger called dotriggers_ai by executing the following statement:
CREATE TRIGGER dotriggers_ai AFTER INSERT ON dotriggers
FOR EACH ROW
INSERT INTO audit_triggers (new_column, date_completed)
VALUES (NEW.column1, NOW());
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> CREATE TRIGGER dotriggers_ai AFTER INSERT ON dotriggers


-> FOR EACH ROW
-> INSERT INTO audit_triggers (new_column, date_completed)
-> VALUES (NEW.column1, NOW());
Query OK, 0 rows affected (#.## sec)
5. Insert the values 1 – 6 inclusive into the dotriggers table.
Enter the following statement at the mysql prompt and receive the results shown:
ble
mysql> INSERT INTO dotriggers
-> VALUES (1), (2), (3), (4), (5), (6);
fe r a
Query OK, 6 rows affected (#.## sec)
ans
Records: 6 Duplicates: 0 Warnings: 0
n - t r
o
6.
an
Verify the insertion of the new rows in the previous step by issuing an appropriate SELECT
statement. s
r ) ha ฺ
Enter the following statement at the mysql prompt and receive the results shown:
m ฺb uide
ฺco nt G
mysql> SELECT * FROM dotriggers;
+---------+
a r
| column1 |
o n ep tude
+---------+
@ s is S
| 1 |
c c i th
| 2 |
r i
oฺ to us e
| rt
| 3 |
4 e
ro5b| se
|

| ci ( 6 |cen
|
c li
Ri+---------+
e r to 6 rows in set (#.## sec)

R ob 7. Confirm the execution of the dotriggers_ai trigger by issuing an appropriate SELECT


statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM audit_triggers;
+------------+------------+---------------------+
| old_column | new_column | date_completed |
+------------+------------+---------------------+
| NULL | 1 | 2016-05-18 16:25:33 |
| NULL | 2 | 2016-05-18 16:25:33 |
| NULL | 3 | 2016-05-18 16:25:33 |
| NULL | 4 | 2016-05-18 16:25:33 |
| NULL | 5 | 2016-05-18 16:25:33 |
| NULL | 6 | 2016-05-18 16:25:33 |
+------------+------------+---------------------+
6 rows in set (#.## sec)
− The query displays the six rows added to the audit_triggers table by the
dotriggers_ai trigger. The result shows the value inserted and the date and time
of the insertion.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 6
8. Create a trigger called dotriggers_au by executing the following statement:
CREATE TRIGGER dotriggers_au AFTER UPDATE ON dotriggers
FOR EACH ROW
INSERT INTO audit_triggers (old_column,
new_column,date_completed)
VALUES (OLD.column1, NEW.column1,NOW());
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE TRIGGER dotriggers_au AFTER UPDATE ON dotriggers
-> FOR EACH ROW
-> INSERT INTO audit_triggers (
-> old_column, new_column, date_completed)
-> VALUES (OLD.column1, NEW.column1, NOW());
Query OK, 0 rows affected (#.## sec)
9. Update the dotriggers table, setting all values less than three to the new value of 10.
ble
Enter the following statement at the mysql prompt and receive the results shown:
fe r a
mysql> UPDATE dotriggers SET column1=10 WHERE column1 < 3;
ans
Query OK, 2 rows affected (#.## sec)
n - t r
Rows matched: 2 Changed: 2 Warnings: 0
a no
h a s
10. Verify the update in the previous step with a suitable SELECT statement.
Enter the following statement at the mysql prompt and receive
ฺ b r) dresults
the
e ฺ shown:
mysql> SELECT * FROM dotriggers;
c o m Gui
+---------+
p a rฺ ent
ne Stud
| column1 |
+---------+
s o
| 10 |
c i @ this
ric use
| 10 |
| 3 |
| r t o ฺ
| 4 e
b e to
|
ro
| i ( 6 | en
5 | s
c c
i+---------+ li c
R
erto
6 rows in set (#.## sec)
b − The query displays all rows in the dotriggers table. The first two rows now have a
Ro value of 10.
11. Confirm the execution of the dotriggers_au trigger by issuing an appropriate SELECT
statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM audit_triggers;
+------------+------------+---------------------+
| old_column | new_column | date_completed |
+------------+------------+---------------------+
| NULL | 1 | 2016-05-18 16:25:33 |
| NULL | 2 | 2016-05-18 16:25:33 |
| NULL | 3 | 2016-05-18 16:25:33 |
| NULL | 4 | 2016-05-18 16:25:33 |
| NULL | 5 | 2016-05-18 16:25:33 |
| NULL | 6 | 2016-05-18 16:25:33 |
| 1 | 10 | 2016-05-18 16:27:03 |
| 2 | 10 | 2016-05-18 16:27:03 |
+------------+------------+---------------------+
8 rows in set (#.## sec)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 7
− There are two additional rows that record the update of the dotriggers table in
step 9.
12. Create a trigger called dotriggers_ad by executing the following statement:
CREATE TRIGGER dotriggers_ad AFTER DELETE ON dotriggers
FOR EACH ROW
INSERT INTO audit_triggers(old_column, date_completed)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

VALUES (OLD.column1, NOW());


Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE TRIGGER dotriggers_ad AFTER DELETE ON dotriggers
-> FOR EACH ROW
-> INSERT INTO audit_triggers(
-> old_column, date_completed)
-> VALUES (OLD.column1, NOW());
Query OK, 0 rows affected (#.## sec)
ble
13. Delete all rows from the dotriggers table with values greater than 2 and less than 10.
fe r a
Enter the following statement at the mysql prompt and receive the results shown:
t r a ns
mysql> DELETE FROM dotriggers WHERE column1 > 2 AND column1n<- 10;
Query OK, 4 rows affected (#.## sec)
a no
a s
14. Verify the deletion of the rows in the previous step by issuing an appropriate
h SELECT
statement. r )
ฺb theidresults
e ฺ
Enter the following statement at the mysql prompt o
c m
and receive u
G shown:
mysql> SELECT * FROM dotriggers; a r ฺ n t
e p d e
+---------+
s on s Stu
i@ thi
| column1 |
+---------+
r i c c e
| 10 |
10 | r t o ฺ u s
|
b e e to
(roin set s sec)
+---------+
c i
2 rows
c e n(#.##
R li
i−c The dotriggers table contains only two rows. You have deleted all rows with a
ert o value less than 10 and greater than 2.
b
Ro 15. Confirm the execution of the dotriggers_ad trigger by issuing an appropriate SELECT
statement.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM audit_triggers;
+------------+------------+---------------------+
| old_column | new_column | date_completed |
+------------+------------+---------------------+
| NULL | 1 | 2016-05-18 16:25:33 |
| NULL | 2 | 2016-05-18 16:25:33 |
| NULL | 3 | 2016-05-18 16:25:33 |
| NULL | 4 | 2016-05-18 16:25:33 |
| NULL | 5 | 2016-05-18 16:25:33 |
| NULL | 6 | 2016-05-18 16:25:33 |
| 1 | 10 | 2016-05-18 16:27:03 |
| 2 | 10 | 2016-05-18 16:27:03 |
| 3 | NULL | 2016-05-18 16:28:37 |
| 4 | NULL | 2016-05-18 16:28:37 |
| 5 | NULL | 2016-05-18 16:28:37 |
| 6 | NULL | 2016-05-18 16:28:37 |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 8
+------------+------------+---------------------+
12 rows in set (#.## sec)
− There are now four new rows in the audit_triggers table, recording the
deletions in step 13.
16. Drop the dotriggers_ad trigger.
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> DROP TRIGGER dotriggers_ad;


Query OK, 0 rows affected (#.## sec)
17. Delete all the rows in the dotriggers table.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> DELETE FROM dotriggers;
Query OK, 2 rows affected (#.## sec)
18. Verify the deletion in the previous step by issuing an appropriate SELECT statement. ble
Enter the following statement at the mysql prompt and receive the results shown: fe r a
ans
mysql> SELECT * FROM dotriggers;
n - t r
Empty set (#.## sec)
n o
19. Confirm that the dotriggers_ad trigger has not executed by issuing a
s an appropriate
SELECT statement. h a
ฺ b r) thedresults
e ฺ shown:
Enter the following statement at the mysql prompt and receive
om t Gu i
mysql> SELECT * FROM audit_triggers; r ฺ
a denc
e p
+------------+------------+---------------------+
| old_column | new_column o
s |n
S tu
date_completed |
hi s
i@1 | 2016-05-18
+------------+------------+---------------------+
c t
| NULL |
NULL |oฺr
i c s e 16:25:33 |
|
r t| t o u3 | 2016-05-18 16:25:33
2 | 2016-05-18 |
| e
b | se
NULL 16:25:33 |
| roNULL
| ci ( NULL e n 4 | 2016-05-18 16:25:33 |

i c l i c| | 5 | 2016-05-18 16:25:33 |

o R | NULL 6 | 2016-05-18 16:25:33 |

ert
| 1 | 10 | 2016-05-18 16:27:03 |
b | 2 | 10 | 2016-05-18 16:27:03 |
Ro |
|
3 |
4 |
NULL | 2016-05-18 16:28:37 |
NULL | 2016-05-18 16:28:37 |
| 5 | NULL | 2016-05-18 16:28:37 |
| 6 | NULL | 2016-05-18 16:28:37 |
+------------+------------+---------------------+
12 rows in set (#.## sec)
− The audit_triggers table does not contain entries for the rows deleted in step
17 because the dotriggers_ad trigger no longer exists.
20. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 9
Practice 15-2: Investigating Triggers in the sakila Database

Overview
In this practice, you investigate the behavior of triggers in the sakila database.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately ten minutes.

Tasks
1. Using the INFORMATION_SCHEMA database, display information about all the triggers in
the sakila database. Explain the purpose of the rental_date trigger.
2. Examine the structure of the rental table.
3. Disable the SQL_MODE system variable by setting it to an empty string. Ignore any warning
ble
messages that result from this step.
fe r a
4. Insert a new row into the rental table.
t r a ns
5. Verify the previous insertion by issuing an appropriate SELECT statement. Explain
o n - the
contents of the columns you did not provide values for.
s an
6. Query the film_text table for the film with an ID of 113.
r ) ha ฺ
7. Update the description of the film with an ID of 113 in theฺb
film tableeto read “No longer
available.” o m u id
a c
ฺ film_text
rthe n G
t table.
Note: Make this change in the film table, p not e
8. Reissue the query in step 6 to query o
s nefilm_text
the S tudtable for the film with an ID of 113.
Explain the result.
c i @ this
9. Leave the mysql command-line
t o ฺ ric uclient
se open for the next practice.
b e r to
(ro cens e
c i li
R ic
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 10
Solution 15-2: Investigating Triggers in the sakila Database

Solution Steps

Tasks
1. Using the INFORMATION_SCHEMA database, display information about all the triggers in
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

the sakila database. Explain the purpose of the rental_date trigger.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
-> WHERE TRIGGER_SCHEMA = 'sakila'\G
*************************** 1. row ***************************
TRIGGER_CATALOG: def
TRIGGER_SCHEMA: sakila
TRIGGER_NAME: customer_create_date
ble
EVENT_MANIPULATION: INSERT
fe r a
...
ans
*************************** 6. row ***************************
TRIGGER_CATALOG: def n - t r
TRIGGER_SCHEMA: sakila
a no
TRIGGER_NAME: rental_date
h a s
r) deฺ
EVENT_MANIPULATION: INSERT
...

m Gui b
... c o
ACTION_STATEMENT: SET NEW.rental_date = NOW()
rฺ ent
p a
ne setsStthe udinitial value of the rental_date
6 rows in set (#.## sec)
− Answer: The rental_date s otrigger
column to the date andi@
c time the row
t h isis inserted into the table, effectively acting as a
ric foruthat
dynamic defaultฺvalue
t o secolumn.
e r of thetrental
2. Examine the structure
b o table.
Enter the following
e
(ro cestatements
ns at the mysql prompt and receive the results shown:
c c i li sakila
R imysql> USE

erto ...
Reading table information for completion of table and column names
b
Ro Database changed
mysql> DESCRIBE rental\G
*************************** 1. row ***************************
Field: rental_id
Type: int(11)
Null: NO
Key: PRI
Default: NULL
Extra: auto_increment
*************************** 2. row ***************************
Field: rental_date
Type: datetime
Null: NO
Key: MUL
Default: NULL
Extra:
*************************** 3. row ***************************
Field: inventory_id
Type: mediumint(8) unsigned
Null: NO
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 11
Key: MUL
Default: NULL
Extra:
*************************** 4. row ***************************
Field: customer_id
Type: smallint(5) unsigned
Null: NO
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Key: MUL
Default: NULL
Extra:
*************************** 5. row ***************************
Field: return_date
Type: datetime
Null: YES
Key:
Default: NULL
Extra: ble
*************************** 6. row ***************************
fe r a
Field: staff_id
ans
Type: tinyint(3) unsigned
n - t r
Null: NO
Key: MUL
a no
Default: NULL
h a s
Extra:
ฺ b r) deฺ
Field: last_update
c o m Gui
*************************** 7. row ***************************

Type: timestamp
p a rฺ ent
one s Stud
Null: NO
Key:
s
Default: CURRENT_TIMESTAMP
c c i@ thi
r i se
Extra: on update CURRENT_TIMESTAMP
o ฺ u
r t
7 rows in set (#.## sec)
e tovariable by setting it to an empty string. Ignore any warning
b
ro resultenfrom
3. Disable the SQL_MODE e
s this step.
system
c
messagesi (that c
R
Enter
li statement at the mysql prompt and receive the results shown:
icthe following
berto mysql> SET SQL_MODE='';
Ro Query OK, 0 rows affected, 1 warning (#.## sec)

mysql> SHOW WARNINGS;


+---------+------+---------------------------------------------------+
| Level | Code | Message
|
+---------+------+---------------------------------------------------+
| Warning | 3129 | Unsetting sql mode 'NO_AUTO_CREATE_USER' is |
| | | deprecated. It will be made read-only in a future |
| | | release. |
+---------+------+---------------------------------------------------+
1 row in set (#.## sec)
− Disabling the SQL mode allows the statement in the next step to execute without
failing.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 12
4. Insert a new row into the rental table.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> INSERT INTO rental (inventory_id, customer_id, staff_id)
-> VALUES (1352, 88, 1);
Query OK, 1 row affected (#.## sec)
5. Verify the previous insertion by issuing an appropriate SELECT statement. Explain the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

contents of the columns you did not provide values for.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM rental
-> ORDER BY rental_id DESC
-> LIMIT 1\G
*************************** 1. row ***************************
rental_id: 16050
rental_date: 2016-05-18 16:33:09
ble
inventory_id: 1352
fe r a
customer_id: 88
ans
return_date: NULL
staff_id: 1 n - t r
last_update: 2016-05-18 16:33:09
a no
1 row in set (#.## sec)
h a s
− Answer: The rental_id column is set to auto_increment.
ฺ b r) trigger.
d e ฺThe rental_date
column is set to the current date by the rental_date
o m u i The last_update
column has a default value of “on update
a r n t G
ฺcasCURRENT_TIMESTAMP ”, which records
are e
epan IDtuofd113.
the time of insertion. All other columns provided, or NULL.
6. Query the film_text table for thesfilm onwith s S
Enter the following statementcat i @ t
the mysqlh i prompt and receive the results shown:
r i c e
mysql> SELECTto
r t o us
* ฺFROM film_text WHERE film_id = 113\G
e
rob e113 se
*************************** 1. row ***************************
i (
film_id: n
R cc title:
idescription:lic CALIFORNIA BIRDS
A Thrilling Yarn of a Database Administrator And a Robot

berto who must Battle a Database Administrator in Ancient India


Ro
1 row in set (#.## sec)
7. Update the description of the film with an ID of 113 in the film table to read “No longer
available.”
Note: Make this change in the film table, not the film_text table.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> UPDATE film SET description = 'No longer available.'
-> WHERE film_id = 113;
Query OK, 1 row affected (#.## sec)
Rows matched: 1 Changed: 1 Warnings: 0

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 13
8. Reissue the query in step 6 to query the film_text table for the film with an ID of 113.
Explain the result.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT * FROM film_text WHERE film_id = 113\G
*************************** 1. row ***************************
film_id: 113
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

title: CALIFORNIA BIRDS


description: No longer available.
1 row in set (#.## sec)
− Although the previous UPDATE statement updated the description value in the
film table, the film_text table also has its description changed. This is due
to the execution of the upd_film trigger, which updates the film_text table’s
film_id, title, and description fields to match those in film whenever they
change.
ble
9. Leave the mysql command-line client open for the next practice.
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 14
Practice 15-3: Creating a Scheduled Event
Overview
In this practice, you create a scheduled event that increments the value of a table column at
regular intervals.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately 15 minutes.

Tasks
1. Inspect the value of the global event_scheduler system variable. If the
event_scheduler system variable is OFF, enable it.
2. Set the triggertest database that you created in an earlier practice to be the default
database. ble
fe r a
3. Create a table in the triggertest database called timer_table with a single column of
ans
INT data type called timer_count.
n - t r
4. no
Insert a single row into the timer_table table with a value of zero in the timer_count
a
column.
h a s
5.
ฺ b r) deฺ
Create a scheduled event that fires one minute after its creation and every minute
thereafter indefinitely. When the event fires, it must increment the value of the
c o m Gui
timer_count column in the timer_table table by one.
6. p a rฺ ent
Immediately execute SHOW PROCESSLIST and verify that the scheduled event you created
one s Stud
in the previous step is waiting for activation.
s
7. i@ thi
Keep querying the timer_table every minute or so for a few minutes and verify that the
c c
o ฺ r i se
timer_count column is incremented by one every time the event fires.
u
e t
r database,
8. Drop the triggertest to exit the mysql command-line client, and close the Linux
b e
c i (ro cens
terminal window.

R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 15
Solution 15-3: Creating a Scheduled Event
Solution Steps

Tasks
1. Inspect the value of the global event_scheduler system variable. If the
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

event_scheduler system variable is OFF, enable it.


Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT @@event_scheduler;
+-------------------+
| @@event_scheduler |
+-------------------+
| OFF |
+-------------------+
ble
1 row in set (#.## sec)
fe r a
ans
mysql> SET GLOBAL event_scheduler = ON;
Query OK, 0 rows affected (#.## sec)
n - t r
a no
mysql> SELECT @@event_scheduler;
h a s
+-------------------+
ฺ b r) deฺ
| @@event_scheduler |
c o m Gui
+-------------------+
p a rฺ ent
one s Stud
| ON |
+-------------------+ s
1 row in set (#.## sec)
c c i@ thi
2. Set the triggertest o ฺ r i
database u seyou created in an earlier practice to be the default
that
database. e r t to
b e
(ro cestatement
Enter thei following
c ns at the mysql prompt and receive the results shown:
R c
imysql> li triggertest
USE

e r to Reading table information for completion of table and column names

R ob ...
Database changed
3. Create a table in the triggertest database called timer_table with a single column of
INT data type called timer_count.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE TABLE timer_table (timer_count INT);
Query OK, 0 rows affected (#.## sec)
4. Insert a single row into the timer_table table with a value of zero in the timer_count
column.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> INSERT INTO timer_table VALUES(0);
Query OK, 1 row affected (#.## sec)

mysql> SELECT * FROM timer_table;


+-------------+
| timer_count |
+-------------+

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 16
| 0 |
+-------------+
1 row in set (#.## sec)
5. Create a scheduled event that fires one minute after its creation and every minute
thereafter indefinitely. When the event fires it must increment the value of the
timer_count column in the timer_table table by one.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statements at the mysql prompt and receive the results shown:
mysql> DELIMITER //
mysql> CREATE EVENT event_timer
-> ON SCHEDULE EVERY 1 MINUTE
-> ON COMPLETION PRESERVE
-> DO
-> BEGIN
-> UPDATE triggertest.timer_table
-> SET timer_count = timer_count + 1;
ble
-> END //
fe r a
Query OK, 0 rows affected (#.## sec)
ans
mysql> DELIMITER ;
n - t r
6. no
Immediately execute SHOW PROCESSLIST and verify that the scheduled event you created
in the previous step is waiting for activation: a
h a s
ฺ b r) deฺ
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SHOW PROCESSLIST\G
c o m Gui
Id: 4 p a rฺ ent
*************************** 1. row ***************************

User: root
s one s Stud
hi
Host: localhost
db: triggertestci@ t
Command: Query ฺr i c e
Time: 0 rto
t o us
State: b
o e
startinge
i ( r e s
nPROCESSLIST
c cInfo:
c
SHOW
li
to Ri***************************
Id: 5
2. row ***************************

e r
ob
User: event_scheduler
R Host: localhost
db: NULL
Command: Daemon
Time: 9
State: Waiting for next activation
Info: NULL
2 rows in set (#.## sec)
7. Keep querying the timer_table every minute or so for a few minutes and verify that the
timer_count column is incremented by one every time the event fires.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT * FROM timer_table;
+-------------+
| timer_count |
+-------------+
| 1 |
+-------------+
1 row in set (#.## sec)
...

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 17
mysql> SELECT * FROM timer_table;
+-------------+
| timer_count |
+-------------+
| 2 |
+-------------+
1 row in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

...
mysql> SELECT * FROM timer_table;
+-------------+
| timer_count |
+-------------+
| 3 |
+-------------+
1 row in set (#.## sec)
...
ble
8. Drop the triggertest database, exit the mysql command-line client, and close the Linux
fe r a
terminal window.
ans
Enter the following statement at the mysql prompt and receive the results shown:
n - t r
mysql> DROP DATABASE triggertest;
a no
Query OK, 1 row affected (#.## sec)
h a s
mysql> EXIT;
ฺ b r) deฺ
Bye
c o m Gui
#
p a rฺ ent
Enter the following command at the Linux
o neterminal d and receive the results shown:
tuprompt
s S
# exit
c i @ this
t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 15: Triggers and Scheduled Events


Chapter 15 - Page 18
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 16:
Reporting om t Gu i
r ฺ c
a 16den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 1
Practices for Lesson 16: Reporting
Practices Overview
These practices test your knowledge of aggregating and grouping data to create reports. They
assume that you are using the Linux operating system environment provided in Oracle
classrooms. For non-Oracle classrooms, you might need to make some adjustments to file
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

locations.

Assumptions
• The sakila and world sample databases are installed.
• The /labs/sql directory contains the logins.sql file.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 2
Practice 16-1: Aggregating Data
Overview
In this practice, you write SQL to aggregate data into formats suitable for reporting.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately 20 minutes.

Tasks
1. Connect to the MySQL server by using either the mysql command-line client in a Linux
terminal session or MySQL Workbench, and make world the current database.
2. Issue a query that uses an aggregation function to display the number of countries in the
Country table.
ble
3. Use an aggregation function to write a single query that displays the number of countries in
fe r a
the Country table that:
ans
• Gained independence earlier than 1945
n - t r
• Gained independence in 1945 or later
a no
• Have no specified independence date
h a s
In the following format:
ฺ b r) deฺ
c o m Gui
+-------------------+---------------+---------------+
| Earlier than 1945 | 1945 or Laterrฺ| Not n t
p a e specified |

one s##St|ud
+-------------------+---------------+---------------+
| ## |
@ s i
## |
i thsurface areas of the countries with the smallest
+-------------------+---------------+---------------+
c cname
r i e
us in the following format:
e r toฺrespectively,
4. Issue queries that display
and largest land mass,
the
t o
and

( rob with
Query 1: Country
i e n sesmallest surface area:
the

R cc lic
i+-------------------------------+--------------------+
e r to |+-------------------------------+--------------------+
Smallest Country | Surface Area |

R ob | Name of country | ################## |


+-------------------------------+--------------------+
Query 2: Country with the largest surface area:
+-------------------------------+--------------------+
| Largest Country | Surface Area |
+-------------------------------+--------------------+
| Name of country | ################## |
+-------------------------------+--------------------+
5. Issue a query that uses aggregation functions to display the average (mean) and total
population of all countries in the following format:
+------------------+--------------------+
| Total Population | Average Population |
+------------------+--------------------+
| ########## | #######.### |
+------------------+--------------------+

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 3
6. Issue a query that lists all countries where the population is greater than the average
population you determined in the previous step. Display the results in the following format:
+---------------------------------------+------------+
| Name | Population |
+---------------------------------------+------------+
| Argentina | 37032000 |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Bangladesh | 129155000 |
| Brazil | 170115000 |
...
7. Issue a query that displays a count of the total number of countries in Asia and the number
of Asian countries with populations greater than the average population you determined in
step 5. Display the results in the following format:
+-----------------+-------------------------------+
| Asian Countries | Asian Countries > Average Pop |
+-----------------+-------------------------------+
ble
| ## | ## |
fe r a
+-----------------+-------------------------------+
ans
8. Issue a query that calculates the percentage of all countries in the world with populations
n - t r
o
an
greater than the average you determined in step 5.
9. s
Leave the mysql command-line client open for the next practice.
ha ฺ
r )
ฺb uide
m
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 4
Solution 16-1: Aggregating Data
Solution Steps
1. Connect to the MySQL server by using either the mysql command-line client in a Linux
terminal session or MySQL Workbench, and make world the current database.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following command at the Linux terminal prompt and receive the results shown:
# mysql -uroot -poracle
mysql: [Warning] Using a password on the command line interface can be
insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
...
Enter the following statement at the mysql prompt and receive the results shown:
mysql> USE world
ble
Database changed
fe r a
2. Issue a query that uses an aggregation function to display the number of countries in the
ans
Country table.
n - t r
no
Enter the following statement at the mysql prompt and receive the results shown:
a
mysql> SELECT COUNT(*) FROM Country;
h a s
+----------+
ฺ b r) deฺ
m Gui
| COUNT(*) |
+----------+
c o
rฺ ent
| 239 |
p a
one s Stud
+----------+
1 row in set (#.## sec)
s
3. Use an aggregation functionctoi@
i c t hi query that displays the number of countries in
write a single
e
the Country table that:ฺr
e r t o to us
r o b
• Gained independence
s eearlier than 1945
• Gained (
ci independence n
ce in 1945 or later
i c l i
•R Have no specified independence date
r t o
e In the following format:
b
Ro +-------------------+---------------+---------------+
| Earlier than 1945 | 1945 or Later | Not specified |
+-------------------+---------------+---------------+
| ## | ## | ## |
+-------------------+---------------+---------------+
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT
-> SUM(IndepYear < 1945) AS 'Earlier than 1945',
-> SUM(IndepYear >= 1945) AS '1945 or Later',
-> SUM(IndepYear IS NULL) AS 'Not specified'
-> FROM Country;
+-------------------+---------------+---------------+
| Earlier than 1945 | 1945 or Later | Not specified |
+-------------------+---------------+---------------+
| 70 | 122 | 47 |
+-------------------+---------------+---------------+
1 row in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 5
4. Issue queries that display the name and surface areas of the countries with the smallest
and largest land mass, respectively, in the following format:
Query 1: Country with the smallest surface area:
+-------------------------------+--------------------+
| Smallest Country | Surface Area |
+-------------------------------+--------------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Name of country | ################## |


+-------------------------------+--------------------+
Query 2: Country with the largest surface area:
+-------------------------------+--------------------+
| Largest Country | Surface Area |
+-------------------------------+--------------------+
| Name of country | ################## |
+-------------------------------+--------------------+
ble
Enter the following statements at the mysql prompt and receive the results shown:
fe r a
mysql> SET @minSA = (SELECT MIN(SurfaceArea) FROM Country);
ans
Query OK, 0 rows affected (#.## sec)
n - t r
o
an
mysql> SET @maxSA = (SELECT MAX(SurfaceArea) FROM Country);
s
ha ฺ
Query OK, 0 rows affected (#.## sec)

mysql> SELECT Name AS 'Smallest Country', ฺb r )


o m u ide
-> @minSA AS 'Smallest_SA'
-> FROM Country
a r ฺc nt G
-> WHERE SurfaceArea=@minSA;
o n ep tude
s is| S
+-------------------------------+--------------------+
@
| Smallest Country
c c i t h Surface Area |
i e
ฺr CityusState) | 0.4000000059604645 |
+-------------------------------+--------------------+
o
r t
| Holy See (Vatican
e to
b e
+-------------------------------+--------------------+
o set (#.##
1 row(rin
c i c e ns sec)
c
Rimysql> li
SELECT Name AS 'Largest Country',

e r to -> @maxSA AS 'Surface Area'

R ob -> FROM Country


-> WHERE SurfaceArea=@maxSA;
+--------------------+--------------+
| Largest Country | Surface Area |
+--------------------+--------------+
| Russian Federation | 17075400 |
+--------------------+--------------+
1 row in set (#.## sec)
5. Issue a query that uses aggregation functions to display the average (mean) and total
population of all countries in the following format:
+------------------+--------------------+
| Total Population | Average Population |
+------------------+--------------------+
| ########## | #######.### |
+------------------+--------------------+
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT
-> SUM(Population) AS 'Total Population',
-> AVG(Population) AS 'Average Population'
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 6
-> FROM Country;
+------------------+--------------------+
| Total Population | Average Population |
+------------------+--------------------+
| 6078749450 | 25434098.1172 |
+------------------+--------------------+
1 row in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

6. Issue a query that lists all countries where the population is greater than the average
population you determined in the previous step. Display the results in the following format:
+---------------------------------------+------------+
| Name | Population |
+---------------------------------------+------------+
| Argentina | ######### |
| Bangladesh | ######### |
| Brazil | ######### |
ble
...
fe r a
Enter the following statements at the mysql prompt and receive the results shown:
ans
mysql> SET @avPop = (SELECT AVG(Population) FROM Country);
n - t r
o
an
Query OK, 0 rows affected (#.## sec)

mysql> SELECT s
ha ฺ
-> Name, Population r )
ฺb uide
-> FROM Country
m
-> WHERE Population > @avPop;
a r ฺco nt G
ep tud|e Population |
+---------------------------------------+------------+
| Name
o n
s is S | 37032000 |
+---------------------------------------+------------+
| Argentina
c i @ th
| Bangladesh
ฺ r i c s e | 129155000 |
| Brazil
r t o t o u | 170115000 |
e
rob ense
...

c i (
| Ukraine
c
| 50456000 |
c
Ri| Vietnam
| l i
United States | 278357000 |

e r to | South Africa |
|
40377000 |
79832000 |

R ob +---------------------------------------+------------+
38 rows in set (#.## sec)
7. Issue a query that displays a count of the total number of countries in Asia and the number
of Asian countries with populations greater than the average population you determined in
step 5. Display the results in the following format:
+-----------------+-------------------------------+
| Asian Countries | Asian Countries > Average Pop |
+-----------------+-------------------------------+
| ## | ## |
+-----------------+-------------------------------+
Enter the following statements at the mysql prompt and receive the results shown:
mysql> SELECT SUM(Continent='Asia')
-> AS 'Asian Countries',
-> ( SELECT SUM(Continent='Asia')
-> FROM Country
-> WHERE Population > @avPop
-> ) AS 'Asian Countries > Average Pop'
-> FROM Country;

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 7
+-----------------+-------------------------------+
| Asian Countries | Asian Countries > Average Pop |
+-----------------+-------------------------------+
| 51 | 13 |
+-----------------+-------------------------------+
1 row in set (#.## sec)
8. Issue a query that calculates the percentage of all countries in the world with populations
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

greater than the average you determined in step 5.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT
-> ROUND(100*SUM(Population > @avPop)/COUNT(Code),1)
-> AS '% of Countries With > Average Pop'
-> FROM Country;
+-----------------------------------+
| % of Countries With > Average Pop |
ble
+-----------------------------------+
fe r a
| 15.9 |
ans
+-----------------------------------+
1 row in set (#.## sec) n - t r
o
9. an
Leave the mysql command-line client open for the next practice.
s
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 8
Practice 16-2: Grouping Aggregated Data
Overview
In this practice, you apply grouping expressions to summarize aggregated data.

Duration
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

This practice should take approximately 30 minutes.

Tasks
1. In the mysql command-line prompt, or MySQL Workbench, change the current database to
sakila.
2. Use a GROUP BY expression to list all film categories and the number of films within each
category in the following format:
ble
+-------------+-----------------+
fe r a
| name | Number of Films |
ans
+-------------+-----------------+
| Action | ## | n - t r
| Animation | ## |
a no
| Children | ## |
h a s
...
ฺ b r) tables
d e ฺ to access this
Note: You will need to join the film_category and category
om t Gu i
information.
r ฺ c nfilm table that begin with each
atitles indthe
3. Issue a query that displays the number ofefilmp
n Stu e
letter of the alphabet in the following
s oformat:
c i @ this
ic u| se
+--------------+-------+
| first_letter |ฺrtotal
o
e t
r | t##
+--------------+-------+ o|
o b e
| B i (r n|s ## |
| A

cCc
i|... c e
li | ## |
R
berto
4. Issue a query that lists the ten customers with the largest number of film rentals of seven
Ro days or more, in descending order of the number of rentals, in the following format:
+------------+-----------+--------------+
| first_name | last_name | Long Rentals |
+------------+-----------+--------------+
| FIRSTNAME | LASTNAME | ## |
...
Notes
− You will need to join the customer and rental tables to access this information.
− Use the DATEDIFF() function on the values of the rental_date and
return_date columns to determine the length of each rental.
5. Leave the mysql command-line client or MySQL Workbench open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 9
Solution 16-2: Grouping Aggregated Data
Solution Steps
1. In the mysql command-line prompt, or MySQL Workbench, change the current database to
sakila.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> USE sakila
Database changed
2. Use a GROUP BY expression to list all film categories and the number of films within each
category, in the following format:
+-------------+-----------------+
| name | Number of Films |
+-------------+-----------------+
ble
| Action | ## |
fe r a
| Animation | ## |
ans
| Children
...
| ## |
n - t r
a no
Note: You will need to join the film_category and category tables to access this
information.
h a s
b r) deฺ
Enter the following statement at the mysql prompt and receive the results shown:

c o m Gui
rฺ as
mysql> SELECT category.name,
-> COUNT(film_category.category_id)
p a e n t
'Number of Films'

one s Stud
-> FROM film_category
-> INNER JOIN category s
c i@ thi
-> ON film_category.category_id=category.category_id
c
o ฺ r i se
-> GROUP BY category.category_id;
u
r t to of Films |
+-------------+-----------------+
| name be | Number
(ro cen| s e
c i
+-------------+-----------------+
li |
Ri|c Animation
| Action 64 |

to
66 |
e r | Children | 60 |

R ob | Classics
| Comedy
|
|
57 |
58 |
| Documentary | 68 |
| Drama | 62 |
| Family | 69 |
| Foreign | 73 |
| Games | 61 |
| Horror | 56 |
| Music | 51 |
| New | 63 |
| Sci-Fi | 61 |
| Sports | 74 |
| Travel | 57 |
+-------------+-----------------+
16 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 10
3. Issue a query that displays the number of film titles in the film table that begin with each
letter of the alphabet in the following format:
+--------------+-------+
| first_letter | total |
+--------------+-------+
| A | ## |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| B | ## |
| C | ## |
...
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT LEFT(title, 1) AS first_letter,
-> COUNT(*) AS total
-> FROM film
-> GROUP BY first_letter;
+--------------+-------+
ble
| first_letter | total |
fe r a
+--------------+-------+
ans
| A
| B
|
|
46 |
63 | n - t r
| C | 92 |
a no
| D | 65 |
h a s
r) deฺ
| E | 32 |
...

m Guib
| V
| W
|
|
22 |
43 | c o
rฺ ent
p a
one s Stud
| Y | 3 |
| Z | 3 |
s
+--------------+-------+
c c i@ thi
o ฺ i
25 rows in set (#.## sec)
se with the largest number of film rentals of seven
r ten customers
u
e r t
4. Issue a query that lists the
o of the number of rentals, in the following format:
torder
b
days or more, in descending e
c i (ro cens
R li | last_name | Long Rentals |
i|c first_name
+------------+-----------+--------------+

erto
+------------+-----------+--------------+
b | FIRSTNAME | LASTNAME | ## |
Ro ...
Notes
− You will need to join the customer and rental tables to access this information.
− Use the DATEDIFF() function on the values of the rental_date and
return_date columns to determine the length of each rental.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT customer.first_name, customer.last_name,
-> COUNT(rental.customer_id) AS 'Long Rentals'
-> FROM customer INNER JOIN rental
-> ON customer.customer_id=rental.customer_id
-> WHERE DATEDIFF(rental.return_date, rental.rental_date) > 7
-> GROUP BY customer.first_name, customer.last_name
-> ORDER BY COUNT(rental.customer_id) DESC LIMIT 10;
+------------+-----------+--------------+
| first_name | last_name | Long Rentals |
+------------+-----------+--------------+
| RHONDA | KENNEDY | 15 |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 11
| ELEANOR | HUNT | 15 |
| KARL | SEAL | 15 |
| JUNE | CARROLL | 14 |
| NEIL | RENNER | 14 |
| LENA | JENSEN | 13 |
| PHILIP | CAUSEY | 12 |
| CHERYL | MURPHY | 12 |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| CALVIN | MARTEL | 12 |
| WESLEY | BULL | 12 |
+------------+-----------+--------------+
10 rows in set (#.## sec)
5. Leave the mysql command-line client or MySQL Workbench open for the next practice.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 12
Practice 16-3: Creating a Crosstab Report with a Bar Chart
Overview
In this practice, you execute a SQL script to create and populate a database containing user
login data and display that information in a crosstab report with a bar chart.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately 20 minutes.

Tasks
1. Execute the SQL in the /labs/sql/logins.sql file. This SQL script creates the
logins database and populates the user_logins table.
2. Change the current database to logins and examine the structure of the user_logins
table. ble
fe r a
3. Issue a query that creates a crosstab report, which shows the name of each user and the
ans
number of times they logged in on each weekday. The report should be in the following
format: n - t r
a no
+----------+-----+-----+-----+-----+-----+-----+-----+
| User | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
h a s
+----------+-----+-----+-----+-----+-----+-----+-----+
ฺ b r) deฺ
| Charity | # | # | # | # | # | # |
c o m Gui
# |
| Charlene |
| Derek |
# |
# |
# |
# |
# |
# |
# |
# |
p
# |
a
# |rฺ ent
# |
# |
# |
# |
| Faisal | # | # | # |
s one s Stud
# | # | # | # |

i@ thi
| Felix | # | # | # | # | # | # | # |
| John | # | # |
i c c # | # | # | # | # |
| Ming |
t o ฺ
# | r # |
u
# |se # | # | # | # |
| Nora
b e r| # | # |
to# | # | # | # | # |

(rocolumn e
ntosthe report that displays the total number of logins for each user in
+----------+-----+-----+-----+-----+-----+-----+-----+
i
4. Add ancextra c e
c format,lias follows:
R
bar ichart
berto +----------+-----+-----+-----+-----+-----+-----+-----+------------------+
Ro | User | Mon | Tue | Wed | Thu | Fri | Sat | Sun | Number of Logins |
+----------+-----+-----+-----+-----+-----+-----+-----+------------------+
| Charity | # | # | # | # | # | # | # | *********** |
| Charlene | # | # | # | # | # | # | # | ****** |
...
5. Close the connection to the MySQL server and exit any open Linux terminal prompts.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 13
Solution 16-3: Creating a Crosstab Report with a Bar Chart
Solution Steps
1. Execute the SQL in the /labs/sql/logins.sql file. This SQL script creates the
logins database and populates the user_logins table.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> SOURCE /labs/sql/logins.sql
Query OK, 0 rows affected, 1 warning (#.## sec)

Query OK, 1 row affected (#.## sec)

Database changed
Query OK, 0 rows affected (#.## sec)

ble
Query OK, 100 rows affected (#.## sec)
Records: 100 Duplicates: 0 Warnings: 0 fe r a
ans
mysql>
n - t r
o
2.
an
Change the current database to logins and examine the structure of the user_logins
table. s
r ) ha ฺ
Enter the following statements at the mysql prompt and receive the results shown:
m ฺb uide
ฺco nt G
mysql> USE logins;
Database changed
a r
mysql> SHOW TABLES;
o n ep tude
+------------------+
s is S
+------------------+ ci@ th
| Tables_in_logins |

r i c e
| user_logins
e r toฺ to us
+------------------+
|

o
1 row in set
r b (#.##sesec)
c (
i DESC c e n
Ri c
mysql> l i user_logins;

e r to +-----------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
b
Ro
+-----------+-----------------------+------+-----+---------+----------------+
| id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| LoginDate | varchar(255) | YES | | NULL | |
| User | varchar(255) | YES | | NULL | |
+-----------+-----------------------+------+-----+---------+----------------+
3 rows in set (#.## sec)
− The user_logins table stores usernames and login dates.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 14
3. Issue a query that creates a crosstab report, which shows the name of each user and the
number of times they logged in on each weekday. The report should be in the following
format:
+----------+-----+-----+-----+-----+-----+-----+-----+
| User | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
+----------+-----+-----+-----+-----+-----+-----+-----+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Charity | # | # | # | # | # | # | # |
| Charlene | # | # | # | # | # | # | # |
| Derek | # | # | # | # | # | # | # |
| Faisal | # | # | # | # | # | # | # |
| Felix | # | # | # | # | # | # | # |
| John | # | # | # | # | # | # | # |
| Ming | # | # | # | # | # | # | # |
| Nora | # | # | # | # | # | # | # |
+----------+-----+-----+-----+-----+-----+-----+-----+
Enter the following statement at the mysql prompt and receive the results shown: ble
fe r a
mysql> SELECT User,
ans
->
->
COUNT(IF(WEEKDAY(LoginDate)=0,1,NULL)) AS Mon,
COUNT(IF(WEEKDAY(LoginDate)=1,1,NULL)) AS Tue, n - t r
o
->
->
COUNT(IF(WEEKDAY(LoginDate)=2,1,NULL)) AS Wed,
s
COUNT(IF(WEEKDAY(LoginDate)=3,1,NULL)) AS Thu,an
->
) ha ฺ
COUNT(IF(WEEKDAY(LoginDate)=4,1,NULL)) AS Fri,
r
->
ฺb uide
COUNT(IF(WEEKDAY(LoginDate)=5,1,NULL)) AS Sat,
m
ฺco nt G
-> COUNT(IF(WEEKDAY(LoginDate)=6,1,NULL)) AS Sun
-> FROM user_logins
a r
-> GROUP BY User;
o n ep tude
s is S
+----------+-----+-----+-----+-----+-----+-----+-----+
@
| User
c c i
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
th
i e
+----------+-----+-----+-----+-----+-----+-----+-----+
r
| Charity |
e
| Charlene |r toฺ to us
3 |
4 |
3 |
3 |
2 |
1 |
2 |
3 |
2 |
1 |
0 |
0 |
2 |
1 |

i (
| Derekrob ense
| 1 | 1 | 0 | 1 | 3 | 2 | 2 |
c
| Faisal
lic
| 1 | 2 | 1 | 2 | 2 | 3 | 1 |

to Ric| Felix | 4 | 1 | 1 | 1 | 5 | 1 | 3 |

e r | John | 4 | 1 | 2 | 0 | 1 | 0 | 0 |

R ob | Ming
| Nora
|
|
1 |
3 |
0 |
2 |
3 |
2 |
1 |
3 |
4 |
6 |
0 |
0 |
2 |
0 |
+----------+-----+-----+-----+-----+-----+-----+-----+
8 rows in set (#.## sec)
4. Add an extra column to the report that displays the total number of logins for each user in
bar chart format, as follows:
+----------+-----+-----+-----+-----+-----+-----+-----+------------------+
| User | Mon | Tue | Wed | Thu | Fri | Sat | Sun | Number of Logins |
+----------+-----+-----+-----+-----+-----+-----+-----+------------------+
| Charity | # | # | # | # | # | # | # | *********** |
| Charlene | # | # | # | # | # | # | # | ****** |
...
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT User,
-> COUNT(IF(WEEKDAY(LoginDate)=0,1,NULL)) AS Mon,
-> COUNT(IF(WEEKDAY(LoginDate)=1,1,NULL)) AS Tue,
-> COUNT(IF(WEEKDAY(LoginDate)=2,1,NULL)) AS Wed,
-> COUNT(IF(WEEKDAY(LoginDate)=3,1,NULL)) AS Thu,
-> COUNT(IF(WEEKDAY(LoginDate)=4,1,NULL)) AS Fri,

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 15
-> COUNT(IF(WEEKDAY(LoginDate)=5,1,NULL)) AS Sat,
-> COUNT(IF(WEEKDAY(LoginDate)=6,1,NULL)) AS Sun,
-> REPEAT('*',COUNT(YEAR(LoginDate))) AS 'Number of Logins'
-> FROM user_logins
-> GROUP BY User;
+----------+-----+-----+-----+-----+-----+-----+-----+------------------+
| User | Mon | Tue | Wed | Thu | Fri | Sat | Sun | Number of Logins |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

+----------+-----+-----+-----+-----+-----+-----+-----+------------------+
| Charity | 3 | 3 | 2 | 2 | 2 | 0 | 2 | ************** |
| Charlene | 4 | 3 | 1 | 3 | 1 | 0 | 1 | ************* |
| Derek | 1 | 1 | 0 | 1 | 3 | 2 | 2 | ********** |
| Faisal | 1 | 2 | 1 | 2 | 2 | 3 | 1 | ************ |
| Felix | 4 | 1 | 1 | 1 | 5 | 1 | 3 | **************** |
| John | 4 | 1 | 2 | 0 | 1 | 0 | 0 | ******** |
| Ming | 1 | 0 | 3 | 1 | 4 | 0 | 2 | *********** |
| Nora | 3 | 2 | 2 | 3 | 6 | 0 | 0 | **************** |
+----------+-----+-----+-----+-----+-----+-----+-----+------------------+
8 rows in set (#.## sec)
ble
5. Close the connection to the MySQL server and exit any open Linux terminal prompts. fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 16: Reporting


Chapter 16 - Page 16
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 17:
NoSQL om t Gu i
r ฺ c
a 17den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 1
Practices for Lesson 17: Building NoSQL Applications
Practices Overview
These practices test your knowledge of working with the InnoDB plug-in for memcached and
JSON data in MySQL. They assume that you are using the Linux operating system environment
provided in Oracle classrooms. For non-Oracle classrooms, you might need to make some
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

adjustments to file locations.


Important: The coding practices in this lesson are available in PHP, Java, and Python. Perform
all the practices for this and all future coding activities in only one language, choosing the
language you are most familiar with. If in doubt, perform the PHP activities. Ensure that you
complete all practices that are not language-specific.
For this lesson, perform the following practices:
• Practice 17-1: Configuring the memcached plug-in for InnoDB
ble
• If your chosen programming language is PHP:
fe r a
− Practice 17-2: Using the memcached plug-in for InnoDB with PHP ans
• If your chosen programming language is Java: n - t r
a
− Practice 17-3: Using the memcached plug-in for InnoDB with Java
no
• If your chosen programming language is Python: h a s
ฺ b r) deฺ
c o m Gui
− Practice 17-4: Using the memcached plug-in for InnoDB with Python
• Practice 17-5: Manipulating JSON data
p a rฺ ent
one s Stud
• Practice 17-6: Querying JSON data
s
Assumptions
c c i@ thi
• The /labs/sqlto ฺ i
r contains
directory u se the sensor.sql file.
b e r thetocoding practices in PHP:
• If you are
i ( r o
e n se
completing

R i−ccmemcached_test.php
lic
The /labs/php/cli/activity17-2
file.
directory contains the

e r to − The php-pecl-memcache extension is installed (version 2.27 or later).


R ob • If you are completing the coding practices in Java:
− The /labs/java/cli/activity17-3 directory contains the
MemcachedTest.java file.
− The java_memcached-release_2.6.6.jar and its dependencies are in the
$CATALINA_HOME/lib directory.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 2
• If you are completing the coding practices in Python:
− The /labs/python/cli/activity17-4 directory contains the
memcached_test.py file.
− The python-memcached module (version 1.57 or later) is installed.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 3
Practice 17-1: Configuring the Memcached Plug-in for InnoDB
Overview
In this practice, you configure the memcached plug-in for InnoDB and examine the sample
key/value store it provides.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately 15 minutes to complete.

Tasks
1. Use the mysql command-line client to check to see if the test database exists. If the
test database does not exist, then create it.
2. Run the innodb_memcached_config.sql script. This sets up the tables that the
memcached InnoDB plug-in requires to do its work. The script is in the ble
/usr/share/mysql directory. fe r a
ans
3. Verify the existence of the test and innodb_memcache databases. List the tables in the
n - t r
innodb_memcache database. o
4. s an
Examine the structure and contents of the containers table and answer the following
questions:
r ) ha ฺ
ฺb uide
a. Which database and table does the cache use to store items?
m
a r ฺco nt G
b. Which column contains the keys and which column contains the values?

o n ep tude
c. What do the other columns represent? Use the MySQL Reference Manual to help you
determine their use.
@ s is S
5. c i th
List the contents of the test database’s demo_test table. It contains a single key/value
c
r i e
e r toฺ to us
pair. What is the key and what is its value?

rob ense
6. Delete the contents of the demo_test table.
7. i (
Install the daemon_memcached plug-in on the MySQL server with the libmemcached.so
c
Ric
extension. lic
e r
8. to Open a separate terminal window. Verify that the memcached daemon is running and
R ob listening on the default port 11211 by using netstat -tulpn | grep :11211:.
9. Terminate any mysql command-line client sessions and close all terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 4
Solution 17-1: Configuring the Memcached Plug-in for InnoDB
Tasks
1. Use the mysql command-line client to check to see if the test database exists. If the
test database does not exist, then create it.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Log in to the MySQL server. Enter the following at the shell prompt and receive the
welcome message shown below:
# mysql –uroot –p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
. . .
mysql>
Check to see if the test database exists and if not, create it. Enter the following at the
mysql prompt and receive the results shown below: ble
fe r a
mysql> SHOW DATABASES;
ans
+--------------------+
| Database | n - t r
+--------------------+
a no
| information_schema |
| logins | h a s
| mysql |
ฺ b r) deฺ
| performance_schema |
c o m Gui
| sakila |
p a rฺ ent
one s Stud
| storedroutines |
| sys |
s
| world |
+--------------------+
c c i@ thi
o ฺ r i
8 rows in set (#.## sec)
u se
t
er DATABASE to test;
mysql> o b e
c i
Query (rOK, 1cerownsaffected (#.## sec)
CREATE

li Installer creates an empty test database by default, but administrators


Ri−c The MySQL
e r to often remove it in production environments. If you are working in an Oracle
R ob classroom environment, you must create the test database.
2. Run the innodb_memcached_config.sql script. This sets up the tables that the
memcached InnoDB plug-in requires to do its work. The script is in the
/usr/share/mysql directory.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SOURCE /usr/share/mysql/innodb_memcached_config.sql
Query OK, 1 row affected (#.## sec)

Database changed
Query OK, 0 rows affected (#.## sec)

Query OK, 0 rows affected (#.## sec)

Query OK, 0 rows affected (#.## sec)

Query OK, 1 row affected (#.## sec)

Query OK, 1 row affected (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 5
Query OK, 1 row affected (#.## sec)

Query OK, 1 row affected (#.## sec)

Query OK, 1 row affected, 1 warning (#.## sec)

Database changed
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Query OK, 0 rows affected (#.## sec)

Query OK, 1 row affected (#.## sec)


− The script creates databases called test and innodb_memcache.
3. Verify the existence of the test and innodb_memcache databases. List the tables in the
innodb_memcache database.
Check to see whether the script created the test and innodb_memcache databases.
Enter the following statement at the mysql prompt and receive the results shown:
ble
mysql> SHOW DATABASES;
fe r a
+--------------------+
ans
| Database |
n - t r
+--------------------+
| information_schema | a no
| innodb_memcache |
h a s
| logins |
ฺ b r) deฺ
| mysql |
c o m Gui
| performance_schema |
| sakila |
p a rฺ ent
one s Stud
| storedroutines |
| sys | s
| test |
c c i@ thi
| world
o ฺ
| r i u se
r t
+--------------------+
e to
b e
(roin the ns
10 rows in set (#.## sec)

c i
List thectables
l i c e innodb_memcache database. Enter the following statement at the
i
R prompt and receive the results shown:
mysql
e r t o
b mysql> USE innodb_memcache
Ro . . .
Database changed
mysql> SHOW TABLES;
+---------------------------+
| Tables_in_innodb_memcache |
+---------------------------+
| cache_policies |
| config_options |
| containers |
+---------------------------+
3 rows in set (#.## sec)
− The script has created the innodb_memcache database, which contains three
tables: cache_policies, config_options and containers.
4. Examine the structure and contents of the containers table and answer the following
questions:
a. Which database and table does the cache use to store items?
b. Which column contains the keys and which column contains the values?

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 6
c. What do the other columns represent? Use the MySQL Reference Manual to help you
determine their use.
Examine the structure and contents of the containers table. Enter the following
statement at the mysql prompt and receive the results shown:
mysql> DESCRIBE containers;
+------------------------+--------------+------+-----+---------+-------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Field | Type | Null | Key | Default | Extra |


+------------------------+--------------+------+-----+---------+-------+
| name | varchar(50) | NO | PRI | NULL | |
| db_schema | varchar(250) | NO | | NULL | |
| db_table | varchar(250) | NO | | NULL | |
| key_columns | varchar(250) | NO | | NULL | |
| value_columns | varchar(250) | YES | | NULL | |
| flags | varchar(250) | NO | | 0 | |
| cas_column | varchar(250) | YES | | NULL | |
| expire_time_column | varchar(250) | YES |
| unique_idx_name_on_key | varchar(250) | NO |
| NULL
| NULL
|
|
|
|
ble
+------------------------+--------------+------+-----+---------+-------+
fe r a
9 rows in set (#.## sec)
ans
mysql> SELECT * FROM containers\G n - t r
*************************** 1. row ***************************
a no
name: aaa
h a s
r) deฺ
db_schema: test
db_table: demo_test

m Guib
key_columns: c1
value_columns: c2 c o
rฺ ent
p a
one s Stud
flags: c3
cas_column: c4
s
expire_time_column: c5
c c i@ thi
o ฺ r i u se
unique_idx_name_on_key: PRIMARY

e t
1 row in set (#.## sec)
r and table todoes the cache use to store items?
b
a. Which database e
i (ro The
− cAnswer: c e s uses the database and table defined in the containers
ncache
R li
ic table’s db_schema and db_table columns, respectively. The
ert o innodb_memcached_config.sql script created a demo_test table in the test
b
Ro b.
database to store data items.
Which column contains the keys and which column contains the values?
− Answer: The c1 column in the test.demo_test table contains the keys and the
c2 column contains the values.
c. What do the other columns represent? Use the MySQL Reference Manual to assist
you.
− This information can be found in the MySQL Reference Manual at:
http://dev.mysql.com/doc/mysql/en/innodb-memcached-internals.html
− Answer: The flags column specifies the column in the test.demo_test table
that holds a user-defined numeric value. It can also be used as the column specifier
for some operations (such as incr and prepend) if the memcached value is
mapped to multiple columns.
− Answer: The cas_column and expire_time_column specify the columns in
test.demo_test that hold memcached compare-and-swap and expiration values,
respectively. Unless you want full memcached compliance, you can disregard these
columns.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 7
− Answer: The unique_idx_name_on_key column specifies the name of the index
to use for the key column. It must be a UNIQUE index and it is good practice to enter
PRIMARY in this column to use the table’s primary key.
5. List the contents of the test database’s demo_test table. It contains a single key/value
pair. What is the key and what is its value?
Enter the following statement at the mysql prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

mysql> USE test


. . .
Database changed
mysql> SELECT * FROM demo_test;
+----+--------------+------+------+------+
| c1 | c2 | c3 | c4 | c5 |
+----+--------------+------+------+------+
| AA | HELLO, HELLO | 8 | 0 | 0 |
+----+--------------+------+------+------+ ble
1 row in set (#.## sec)
fe r a
− The key is the entry in the c1 column: AA. Its corresponding value is the entry in the ans
c2 column: HELLO, HELLO n - t r
6. Delete the contents of the demo_test table. a no
h a s
Enter the following statement at the mysql prompt and receive the results shown below:
ฺ b r) deฺ
mysql> DELETE FROM demo_test;
Query OK, 1 row affected (#.## sec)
c o m Gui
p a rฺ ent
one s Stud
mysql> SELECT * FROM demo_test;
Empty set (#.## sec)
s
7. Install the daemon_memcached
i c c e hithe MySQL server with the libmemcached.so
i@plug-inton
extension.
r t o ฺr us
e
b statement
Enter the following t o
e at the mysql prompt and receive the results shown below:
( r o n s
i c ci OK,
mysql>
i ce plugin daemon_memcached soname "libmemcached.so";
install
l
t o R Query 0 rows affected (#.## sec)

be r
8. Open a separate terminal window. Verify that the memcached daemon is running and
Ro listening on the default port 11211 by using netstat -tulpn | grep :11211:
Enter the following command at the shell prompt and receive results similar to those shown
below:
# netstat -tulpn | grep :11211
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 1751/mysqld
tcp 0 0 :::11211 :::* LISTEN 1751/mysqld
udp 0 0 0.0.0.0:11211 0.0.0.0:* 1751/mysqld
udp 0 0 :::11211 :::* 1751/mysqld
− The memcached plug-in for InnoDB is now running and listening on the default port
11211.
9. Terminate any mysql command-line client sessions and close all terminal windows.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 8
Practice 17-2: Using the Memcached Plug-in for InnoDB with PHP
Overview
In this practice, you test the memcached plug-in for InnoDB using the sample PHP program
provided.
Note: This practice uses two Linux terminal windows. The instructions refer to the terminal
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

windows as T1 and T2.

Duration
This practice should take approximately 15 minutes to complete.

Tasks
1. Examine the source code in the memcached_test.php file in
/labs/php/cli/activity17-2 and answer the following questions: ble
fe r a
a. What command-line parameters does the program accept?
ans
b. Which statement writes a value to the cache?
n - t r
c. Which statement reads a value from the cache?
a no
d. Does the program use SQL to achieve either of these operations?
h a s
2. r) deฺ
Open a new Linux terminal window. These practice instructions refer to this terminal
ฺ b
window as T1.
c o m Gui
3. rฺ ent
Open another Linux terminal window and log in to the mysql command-line client. These
p a
one s Stud
practice instructions refer to this terminal window as T2.
4. s
In terminal window T1, execute the memcached_test.php program with the following
c c i@ thi
options to write a key/value pair to the cache.
o ฺ r i u e mysql 0001
sSET
r t
# php memcached_test.php
e to window T2, verify that the demo_test table in the test
b e
5. At the mysql
c i (ro caerecord
prompt
ns for the key/value pair you added to the cache in the previous
in terminal
database
R ic
step.
li
contains

be6.rtoIn terminal window T1, execute the memcached_test.php program with the following
Ro options. This uses the key to retrieve the value you set in step 4 from the cache.
# php memcached_test.php GET mysql
7. In terminal window T2, exit the mysql client.
8. In terminal window T2, shut down the MySQL server by using the following command:
# service mysqld stop
9. In terminal window T1, execute the memcached_test.php program with the following
options to attempt to write a new value to the cache:
# php memcached_test.php SET XYZ 4321
10. In terminal window T2, check to see whether the memcached plug-in for InnoDB is still
listening on port 11211 by issuing the following Linux command:
# netstat -tulpn | grep :11211
11. In terminal window T2, start the MySQL server with the following command at the shell
prompt:
# service mysqld start

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 9
12. In terminal window T2, log in to the MySQL server with the mysql command-line client.
13. In terminal window T2, list the contents of the test database’s demo_test table to verify
that the item you added in step 4 is still there.
14. In terminal window T1, execute the memcached_test.php program with the following
options to write a new value to the cache:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# php memcached_test.php SET XYZ 4321


15. In terminal window T1, use the memcached_test.php Java program to verify that the new
item you added in the previous step is stored in the cache by executing the following
command:
# php memcached_test.php GET XYZ
16. Close terminal window T1.
17. In terminal window T2, exit the mysql client, but leave the Linux terminal window open for
the next practice. ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 10
Solution 17-2: Using the Memcached Plug-in for InnoDB with PHP
Solution Steps
1. Examine the source code in the memcached_test.php file in
/labs/php/cli/activity17-2 and answer the following questions:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

a. What command-line parameters does the program accept?


b. Which statement writes a value to the cache?
c. Which statement reads a value from the cache?
d. Does the program use SQL to achieve either of these operations?
The contents of the memcached_test.php file are as follows:
<?php

$memcache = new Memcache;


ble
$memcache->connect('localhost', 11211) or die ("Could not
fe r a
connect\n");
t r a ns
/* Parse the arguments passed into the program, which should
o n - be in
the format
s an
ha ฺ
GET <key>
or
SET <key> <value> r )
ฺb uide
m
*/
$op = strtoupper($argv[1]);
a r ฺco nt G
e
ep (strcmp($op,
if ((strcmp($op, 'GET')so !=n0) &&S tud 'SET') != 0)) {
die ("Missing action.
c i @ The
t h i s
first parameter must be GET or SET.\n");
ฺr i c e
us
}

e r t o t o
o b
if ((strcmp($op,
r s e 'GET') == 0) && count($argv) != 3) {

c} i (
die
ce n
("Incorrect number of arguments. Expected GET <key>\n");

R i c l i
e r to
ob
if ((strcmp($op, 'SET') == 0) && count($argv) != 4) {
R die ("Incorrect number of arguments. Expected SET <key>
<value>\n");
}

// SET with correct number of arguments

if ((strcmp($op, 'SET') == 0)) {


$key = $argv[2];
$value = $argv[3];
echo ('SET KEY: ' . $key . ', VALUE: ' . $value . "\n");
$status = $memcache->set($key, $value);
echo ("SET RESULT: " . ($status == 0 ? "false" : "true") . "\n");
}

// GET with correct number of arguments

if ((strcmp($op, 'GET') == 0)) {


$key = $argv[2];
$status = $memcache->get($key);

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 11
echo ('GET KEY: ' . $key . "\n");
echo ('GET VALUE: ' . $status . "\n");
}
?>
The answers to the questions are as follows:
a. Answer: The program accepts SET <key> <value> to store an item, and GET
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

<key> to retrieve an item.


b. Answer: The $memcache->set($key, $value) statement writes a key/value pair
to the cache.
c. Answer: The $memcache->get($key) statement reads a value from the cache
using its key.
d. Answer: The program does not use SQL to read or write values to the cache.
2. Open a new Linux terminal window. These practice instructions refer to this terminal
window as T1. ble
fe r a
3. Open another Linux terminal window and log in to the mysql command-line client. These
ans
practice instructions refer to this terminal window as T2.
n - t r
no
Enter the following command at the T2 Linux terminal prompt and receive the results
a
shown:
h a s
# mysql -uroot -p
ฺ b r) deฺ
Enter password: oracle
o m i
end withu; or \g.
Welcome to the MySQL monitor. Commands
. . .
c G
arฺ detontclear the current input
Type 'help;' or '\h' for help.ep
on s Stu
Type '\c'
statement. s
c c i@ thi
mysql>
o ฺ r i u se
4. In terminal window e t
rT1, execute to the
b
ro ens e program with the following
c i (write
/labs/php/cli/activity17-2/memcached_test.php
c
options
R
to li
a key/value
i#c php memcached_test.php pair to the cache.

erto
SET mysql 0001
b Enter the following command at the T1 Linux terminal prompt and receive the results
Ro shown:
# cd /labs/php/cli/activity17-2/
# php memcached_test.php SET mysql 0001
SET KEY: mysql, VALUE: 0001
SET RESULT: true
− The program executes and confirms the successful addition of the item to the
cache.
5. At the mysql prompt in terminal window T2, verify that the demo_test table in the test
database contains a record for the key/value pair you added to the cache in the previous
step.
Enter the following statements at the mysql prompt in terminal window T2 and receive the
results shown:
mysql> USE test
Database changed

mysql> SELECT * FROM demo_test;


+-------+------+------+------+------+
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 12
| c1 | c2 | c3 | c4 | c5 |
+-------+------+------+------+------+
| mysql | 0001 | 0 | 1 | 0 |
+-------+------+------+------+------+
1 row in set (#.## sec)
− Unlike stand-alone memcached systems that hold values in memory, the plug-in
stores the cache data in a database table, which you can query with SQL.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

6. In terminal window T1, execute the memcached_test.php program with the following
options. This uses the key to retrieve the value you set in step 4 from the cache.
# php memcached_test.php GET mysql
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# php memcached_test.php GET mysql
GET KEY: mysql
ble
GET VALUE: 0001
fe r a
− The program executes and displays the value associated with the key mysql.
ans
7. In terminal window T2, exit the mysql client. n - t r
a no
Enter the following statement at the mysql prompt in terminal window T2 and receive the
results shown:
h a s
mysql> EXIT
ฺ b r) deฺ
Bye
c o m Gui
#
p a rฺ ent
s o ne server
8. In terminal window T2, shut down the MySQL
S tudby using the following command:
# service mysqld stop
c i @ this

Enter the following command
t o ric at the
u e Linux terminal prompt and receive the results
sT2
shown:
b e r to
(ro mysqld:
# service mysqld e
ns stop
c i li c e
R ic
Stopping [ OK ]

erto
9. In terminal window T1, execute the memcached_test.php program with the following
b options to attempt to write a new value to the cache:
Ro # php memcached_test.php SET XYZ 4321
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# php memcached_test.php SET XYZ 4321
PHP Notice: Memcache::connect(): Server localhost (tcp 11211, udp 0)
failed with: Connection refused (111) in /labs/php/cli/activity17-
2/memcached_test.php on line 4
PHP Warning: Memcache::connect(): Can't connect to localhost:11211,
Connection refused (111) in /labs/php/cli/activity17-
2/memcached_test.php on line 4
Could not connect
− The operation fails, because the memcached plug-in is no longer running.
10. In terminal window T2, check to see whether the memcached plug-in for InnoDB is still
listening on port 11211 by issuing the following Linux command:
# netstat -tulpn | grep :11211

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 13
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# netstat -tulpn | grep :11211
#
− There are no processes listening on port 11211.
11. In terminal window T2, start the MySQL server with the following command at the shell
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

prompt:
# service mysqld start
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# service mysqld start
Starting mysqld: [ OK ]
#
ble
12. In terminal window T2, log in to the MySQL server with the mysql command-line client.
fe r a
Enter the following command at the T2 Linux terminal prompt and receive the results
an s
shown:
n - t r
# mysql -uroot -p
a no
Enter password: oracle
h a s
. . . ฺ b r) deฺ
Welcome to the MySQL monitor. Commands end with ; or \g.

o m Gui
Type 'help;' or '\h' for help. Type '\c' to clear the current input
c
statement.
p a rฺ ent
mysql>
s one s Stud
13. In terminal window T2, list thec @ tofhthe
icontents i test database’s demo_test table to verify
i c e
that the item you addedฺrin step 4 issstill there.
e
Enter the following r to toatuthe mysql prompt in terminal window T2 and receive the
statements
(
results shown:
i rob ense
R cc USElictest
imysql>
erto ...
Reading table information
b
Ro Database changed

mysql> SELECT * FROM demo_test;


+-------+------+------+------+------+
| c1 | c2 | c3 | c4 | c5 |
+-------+------+------+------+------+
| mysql | 0001 | 0 | 1 | 0 |
+-------+------+------+------+------+
1 row in set (#.## sec)
− Even though you shut down the MySQL server, disabling the memcached plug-in,
the item you stored earlier is still in the table.
− Note: The values for c3, c4, and c5 might be different on your system.
14. In terminal window T1, execute the memcached_test.php program with the following
options to write a new value to the cache:
# php memcached_test.php SET XYZ 4321

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 14
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# php memcached_test.php SET XYZ 4321
SET KEY: XYZ, VALUE: 4321
SET RESULT: true
− This time the operation is successful.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

15. In terminal window T1, use the memcached_test.php Java program to verify that the new
item you added in the previous step is stored in the cache by executing the following
command:
# php memcached_test.php GET XYZ
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# php memcached_test.php GET XYZ
ble
GET KEY: XYZ
GET VALUE: 4321 fe r a
− The program executes and displays the value associated with the new key XYZ. ans
n - t r
16. Close terminal window T1.
Enter the following command at the T1 Linux terminal prompt: a no
h a s
# exit
ฺ b r) deฺ
17. In terminal window T2, exit the mysql client, but leave
o m Guterminal
the Linux i window open for
the next practice.
a c
rฺ ent
p
ne prompt
Enter the following statement at the mysql d receive the results shown:
uand
s o S t
mysql> EXIT
c i @ this
Bye
#
t o ฺ ric use
b e r to
(ro cens e
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 15
Practice 17-3: Using the Memcached Plug-in for InnoDB with Java
Overview
In this practice, you test the memcached plug-in for InnoDB by using the sample Java program
provided.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Note: This practice uses two Linux terminal windows. The instructions refer to the terminal
windows as T1 and T2.

Duration
This practice should take approximately 15 minutes to complete.

Tasks
1. Examine the source code in the MemcachedTest.java file in e
/labs/java/cli/activity17-3 and answer the following questions: r a bl
a. What command-line parameters does the program accept? s fe
b. Which statement writes a value to the cache? - t r an
on
c. Which statement reads a value from the cache?
s an
2. r ha ฺ
d. Does the program use SQL to achieve either of these operations?
)
Open a new Linux terminal window. These practice instructions refer to this terminal
window as T1. m ฺb uide
3. a r ฺco nt G
Open another Linux terminal window and log in to the mysql command-line client. These
n ep tude
practice instructions refer to this terminal window as T2.
o
4. @ s is S
In terminal window T1, compile the test program from the source code in the
c c i th
i e
MemcachedTest.java file in /labs/java/cli/Practice17-3 by using the following
r
statement:
e r toฺ to us
b se
roMemcachedTest.java
# cd /labs/java/cli/activity17-3
c i ( e n
5.
# javac
Ric lic
In terminal window T1, execute the MemcachedTest.java program with the following
e r tooptions to write a key/value pair to the cache:
b
Ro # java MemcachedTest SET mysql 0001
6. At the mysql prompt in terminal window T2, verify that the demo_test table in the test
database contains a record for the key/value pair you added to the cache in the previous
step.
7. In terminal window T1, execute the MemcachedTest.java program with the following
options. This uses the key to retrieve the value you set in step 5 from the cache.
# java MemcachedTest GET mysql
8. In terminal window T2, exit the mysql client.
9. In terminal window T2, shut down the MySQL server by using the following command:
# service mysqld stop
10. In terminal window T1, execute the MemcachedTest.java program with the following
options to attempt to write a new value to the cache:
# java MemcachedTest SET XYZ 4321

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 16
11. In terminal window T2, check to see if the memcached plug-in for InnoDB is still listening on
port 11211 by issuing the following Linux command:
# netstat -tulpn | grep :11211
12. In terminal window T2, start the MySQL server with the following command at the shell
prompt:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# service mysqld start


13. In terminal window T2, log in to the MySQL server with the mysql command-line client.
14. In terminal window T2, list the contents of the test database’s demo_test table to verify
that the item you added in step 5 is still there.
15. In terminal window T1, execute the MemcachedTest Java program with the following
options to write a new value to the cache:
# java MemcachedTest SET XYZ 4321
ble
16. In terminal window T1, use the MemcachedTest Java program to verify that the new item
fe r a
you added in the previous step is stored in the cache by executing the following command:
ans
# java MemcachedTest GET XYZ
n - t r
17. Close terminal window T1.
a no
18. In terminal window T2, exit the mysql client, but leave the Linux a
h s window open for
terminal
the next practice.
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 17
Solution 17-3: Using the Memcached Plug-in for InnoDB with Java
Tasks
1. Examine the source code in the MemcachedTest.java file in
/labs/java/cli/activity17-3 and answer the following questions:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

a. What command-line parameters does the program accept?


b. Which statement writes a value to the cache?
c. Which statement reads a value from the cache?
d. Does the program use SQL to achieve either of these operations?
The contents of the MemcachedTest.java file are as follows:
import java.util.HashMap;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
ble
fe r a
public class MemcachedTest {
ans
protected static MemCachedClient mcc = new MemCachedClient();
n - t r
no
static
{
s a
String[] servers = { "localhost:11211" };
h a
Integer[] weights = { 1 };
ฺ b r) deฺ
SockIOPool pool = SockIOPool.getInstance();
pool.setServers( servers );
c o m Gui
a
pool.setWeights( weights );
p rฺ ent
one s Stud
pool.initialize();
s
MemCachedClient mcc = new MemCachedClient();
}
c c i@ thi
o ฺ i se
r void umain(String[]
e r t
public static
Parse ttheo
args) {

bebin these
/* arguments passed into the program, which
shouldro
c i ( e n
c or <key>
format

R i c l i GET

e r to SET <key> <value>

R ob */
String key = "";
String value = "";
if (! ( (args[0].toUpperCase().equals("GET")) ||
(args[0].toUpperCase().equals("SET")) ) ) {
System.out.println("Missing action. The first
parameter must be GET or SET");
System.exit(0);
}
if ( (args[0].toUpperCase().equals("GET")) && (args.length
!=2) ) {
System.out.println("Incorrect number of arguments.
Expected GET <key>");
System.exit(0);
}
if ( (args[0].toUpperCase().equals("SET")) && (args.length
!=3) ) {
System.out.println("Incorrect number of arguments.
Expected SET <key> <value>");
System.exit(0);
}
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 18
// SET with correct number of arguments
if (args[0].toUpperCase().equals("SET")) {
key = args[1];
value = args[2];
System.out.println("SET KEY: " + key + ", VALUE: "
+value);
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

try {
System.out.println("SET RESULT: " +
mcc.set(key, value));
}
catch (Throwable t)
{
System.out.println("SET operation exception.
Error message : " + t.getMessage());
t.printStackTrace();
} ble
}
fe r a
// GET with correct number of arguments
ans
if (args[0].toUpperCase().equals("GET")) {
n - t r
key = args[1]; o
an
System.out.println("GET KEY: " + key);
s
try {
r ) ha ฺ
System.out.println("GET VALUE: " +
mcc.get(key));
m ฺb uide
}
a
catch (Throwable t) r ฺco nt G
{
o n ep tude
s is S
System.out.println("GET operation exception.
@
i th
Error message : " + t.getMessage());
c c
r i e
toฺ to us
t.printStackTrace();

e r }

rob ense
}

c i (
}

Ric
}
lic
e r to The answers to the questions are as follows:

R ob a. Answer: The program accepts SET <key> <value> to store an item, and GET
<key> to retrieve an item.
b. Answer: The mcc.set(key, value) statement writes a key/value pair to the cache.
c. Answer: The mcc.get(key) statement reads a value from the cache by using its
key.
d. Answer: The program does not use SQL to read or write values to the cache.
2. Open a new Linux terminal window. These practice instructions refer to this terminal
window as T1.
3. Open another Linux terminal window and log in to the mysql command-line client. These
practice instructions refer to this terminal window as T2.
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# mysql -uroot -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
. . .

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 19
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.

mysql>
4. In terminal window T1, compile the test program from the source code in the
MemcachedTest.java file in /labs/java/cli/Practice17-3 by using the following
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

statement:
# cd /labs/java/cli/activity17-3
# javac MemcachedTest.java
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# cd /labs/java/cli/activity17-3
# javac MemcachedTest.java
#
ble
5. In terminal window T1, execute the MemcachedTest.java program with the following fe r a
options to write a key/value pair to the cache:
ans
n - t r
no
# java MemcachedTest SET mysql 0001
a
Enter the following command at the T1 Linux terminal prompt and receive the results
s
shown: h a
ฺ b r) deฺ
# java MemcachedTest SET mysql 0001
SET KEY: mysql, VALUE: 0001
c o m Gui
SET RESULT: true
p a rฺ ent
− The program executes and confirms
cache: s tud addition of the item to the
one stheSsuccessful
c c i@windowthT2,i verify that the demo_test table in the test
o ฺ
database contains atrecord
i
6. At the mysql prompt in terminal e
r for theuskey/value pair you added to the cache in the previous
e r t o
rob estatement
se at the mysql prompt in terminal window T2 and receive the
step.
(
Enter thei following n
iccshown: lic
results
R
berto mysql> USE test
Ro Database changed

mysql> SELECT * FROM demo_test;


+-------+------+------+------+------+
| c1 | c2 | c3 | c4 | c5 |
+-------+------+------+------+------+
| mysql | 0001 | 0 | 1 | 0 |
+-------+------+------+------+------+
1 row in set (#.## sec)
− Unlike stand-alone memcached systems that hold values in memory, the plug-in
stores the cache data in a database table, which you can query with SQL.
− Note: The values for c3, c4, and c5 might be different on your system.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 20
7. In terminal window T1, execute the MemcachedTest.java program with the following
options. This uses the key to retrieve the value you set in step 5 from the cache.
# java MemcachedTest GET mysql
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# java MemcachedTest GET mysql


GET KEY: mysql
GET VALUE: 0001
− The program executes and displays the value associated with the key mysql.
8. In terminal window T2, exit the mysql client.
Enter the following statement at the mysql prompt in terminal window T2 and receive the
results shown:
mysql> EXIT
ble
Bye
fe r a
#
ans
9. In terminal window T2, shut down the MySQL server by using the following command:
n - t r
# service mysqld stop
a no
Enter the following command at the T2 Linux terminal prompt and h a s
receive the results
shown: ฺ b r) deฺ
c o m Gui
rฺ ent
# service mysqld stop
Stopping mysqld:
p a [ OK ]

o ne Stud
10. In terminal window T1, execute the MemcachedTest.java
s program with the following
options to attempt to write a new
c i@ thi
value to s
the cache:
# java MemcachedTest
ฺ i c
r SETusXYZ e 4321
Enter the followinge t o
rcommandtoat the T1 Linux terminal prompt and receive the results
shown: (ro
b se
i e n
R ccjava MemcachedTest
i#SET lic SET XYZ 4321

erto SET RESULT: false


KEY: XYZ, VALUE: 4321
b
Ro − The operation fails, because the memcached plug-in is no longer running.
11. In terminal window T2, check to see if the memcached plug-in for InnoDB is still listening on
port 11211 by issuing the following Linux command:
# netstat -tulpn | grep :11211
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# netstat -tulpn | grep :11211
#
− There are no processes listening on port 11211.
12. In terminal window T2, start the MySQL server with the following command at the shell
prompt:
# service mysqld start

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 21
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# service mysqld start
Starting mysqld: [ OK ]
#
13. In terminal window T2, log in to the MySQL server with the mysql command-line client.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# mysql -uroot -p
Enter password: oracle
Welcome to the MySQL monitor. Commands end with ; or \g.
. . .
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
ble
mysql> fe r a
an s
14. In terminal window T2, list the contents of the test database’s demo_test table to verify
n - t r
that the item you added in step 5 is still there. o
an
Enter the following statements at the mysql prompt in terminal window T2 and receive the
s
results shown:
r ) ha ฺ
mysql> USE test
m ฺb uide
Reading table information
... a r ฺco nt G
Database changed
o n ep tude
@ s is S
mysql> SELECT * FROM idemo_test;
r i c c e th
| c2 to|ฺ c3 s | c5 |
+-------+------+------+------+------+
|uc4
| c1
e r t o
ro|b0001 |se 0 |
+-------+------+------+------+------+

c i (
| mysql
c e n 1 | 0 |
li (#.## sec)
Ri1c row in set
+-------+------+------+------+------+

e r to − Even though you shut down the MySQL server, disabling the memcached plug-in,
R ob the item you stored earlier is still in the table.
− Note: The values for c3, c4, and c5 might be different on your system.
15. In terminal window T1, execute the MemcachedTest Java program with the following
options to write a new value to the cache:
# java MemcachedTest SET XYZ 4321
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# java MemcachedTest SET XYZ 4321
SET KEY: XYZ, VALUE: 4321
SET RESULT: true
− This time the operation is successful.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 22
16. In terminal window T1, use the MemcachedTest Java program to verify that the new item
you added in the previous step is stored in the cache by executing the following command:
# java MemcachedTest GET XYZ
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# java MemcachedTest GET XYZ


GET KEY: XYZ
GET VALUE: 4321
− The program executes and displays the value associated with the new key XYZ.
17. Close terminal window T1.
Enter the following command at the Linux terminal prompt T1:
# exit
18. In terminal window T2, exit the mysql client, but leave the Linux terminal window open for ble
the next practice. fe r a
Enter the following statement at the mysql prompt and receive the results shown: ans
n - t r
o
an
mysql> EXIT
Bye
# s
ha ฺ
r )
ฺb uide
m
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 23
Practice 17-4: Using the Memcached Plug-in for InnoDB with Python
Overview
In this practice, you test the memcached plug-in for InnoDB by using the sample Python
program provided.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Note: This practice uses two Linux terminal windows. The instructions refer to the terminal
windows as T1 and T2.

Duration
This practice should take approximately 15 minutes to complete.

Tasks
1. Examine the source code in the memcached_test.py file in e
/labs/python/cli/activity17-4 and answer the following questions: r a bl
a. What command-line parameters does the program accept? s fe
b. Which statement writes a value to the cache? - t r an
c. Which statement reads a value from the cache? no n
s a
a
d. Does the program use SQL to achieve either of these operations?
h
2. r) deฺ
Open a new Linux terminal window. These practice instructions refer to this terminal
ฺ b
window as T1.
c o m Gui
3. a rฺ ent
Open another Linux terminal window and log in to the mysql command-line client. These
p
s o ne Stud
practice instructions refer to this terminal window as T2.
4. @ this
In terminal window T1, make the memcached_test.py program executable by executing
c i
t o ฺ ric use
the following commands at the Linux terminal prompt:

e r to
# cd /labs/python/cli/activity17-4/
b
(ro cens
# chmod +x e
memcached_test.py
c i li T1, execute the memcached_test.py program with the following
ic window
5. In terminal
R
erto
options to write a key/value pair to the cache.
b
Ro
# python memcached_test.py SET mysql 0001
6. At the mysql prompt in terminal window T2, verify that the demo_test table in the test
database contains a record for the key/value pair you added to the cache in the previous
step.
7. In terminal window T1, execute the memcached_test.py program with the following
options. This uses the key to retrieve the value you set in step 4 from the cache.
# python memcached_test.py GET mysql
8. In terminal window T2, exit the mysql client.
9. In terminal window T2, shut down the MySQL server by using the following command:
# service mysqld stop
10. In terminal window T1, execute the memcached_test.py program with the following
options to attempt to write a new value to the cache:
# python memcached_test.py SET XYZ 4321

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 24
11. In terminal window T2, check to see whether the memcached plug-in for InnoDB is still
listening on port 11211 by issuing the following Linux command:
# netstat -tulpn | grep :11211
12. In terminal window T2, start the MySQL server with the following command at the shell
prompt:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# service mysqld start


13. In terminal window T2, log in to the MySQL server with the mysql command-line client.
14. In terminal window T2, list the contents of the test database’s demo_test table to verify
that the item you added in step 4 is still there.
15. In terminal window T1, execute the memcached_test.py program with the following
options to write a new value to the cache:
# python memcached_test.py SET XYZ 4321
ble
16. In terminal window T1, use the memcached_test.py program to verify that the new item
fe r a
you added in the previous step is stored in the cache by executing the following command:
ans
# python memcached_test.py GET XYZ
n - t r
17. Close terminal window T1.
a no
18. In terminal window T2, exit the mysql client, but leave the Linux a
h s window open for
terminal
the next practice.
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 25
Solution 17-4: Using the Memcached Plug-in for InnoDB with Python
Solution Steps
1. Examine the source code in the memcached_test.py file in
/labs/python/cli/activity17-4 and answer the following questions:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

a. What command-line parameters does the program accept?


b. Which statement writes a value to the cache?
c. Which statement reads a value from the cache?
d. Does the program use SQL to achieve either of these operations?
The memcached_test.py file contains the following:
import sys
#import mysql.connector
import memcache
ble
fe r a
memc = memcache.Client(['127.0.0.1:11211'], debug=1);
ans
n - t r
no
'''
a
Parse the arguments passed into the program, which should be in the
s
format
h a
GET <key>
or ฺ b r) deฺ
SET <key> <value>
c o m Gui
'''
p a rฺ ent
one s Stud
# First element is program name and can be ignored.
op = sys.argv[1].upper()
s
if (op != "GET" and
i c cop
e t hi
i@!= "SET"):
print "Missing
r t o ฺraction.usThe first parameter must be GET or SET"
b e
sys.exit()
e to
i (ro== "GET"
ifc(op c e nsand (len(sys.argv) != 3)):
li
Ric print "Incorrect number of arguments. Expected GET <key>"

e r to sys.exit()

R ob if (op == "SET" and (len(sys.argv) != 4)):


print "Incorrect number of arguments. Expected SET <key> <value>"
sys.exit()

# SET with correct number of arguments


if op == "SET":
key = sys.argv[2]
value = sys.argv[3]
status = memc.set(key, value)
if status == 0:
status = 'False'
print "SET KEY: %s, VALUE: %s" % (key, value)
print "SET RESULT: %s" % (status)

# GET with correct number of arguments


if op == "GET":
key = sys.argv[2]
value = memc.get(key)
print "GET KEY: %s" % (key)
print "GET VALUE: %s" % (value)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 26
The answers to the questions are as follows:
a. Answer: The program accepts SET <key> <value> to store an item, and GET
<key> to retrieve an item.
b. Answer: The memc->set(key, value) statement writes a key/value pair to the
cache.
c. Answer: The memc->get(key) statement reads a value from the cache by using its
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

key.
d. Answer: The program does not use SQL to read or write values to the cache.
2. Open a new Linux terminal window. These practice instructions refer to this terminal
window as T1.
3. Open another Linux terminal window and log in to the mysql command-line client. These
practice instructions refer to this terminal window as T2.
Enter the following command at the T2 Linux terminal prompt and receive the results
ble
shown:
fe r a
ans
# mysql -uroot -p
Enter password: oracle
n - t r
Welcome to the MySQL monitor. Commands end with ; or \g.
a no
. . .
h a s
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
ฺ b r) deฺ
c o m Gui
mysql>
p a rฺ ent
4. In terminal window T1, make the memcached_test.py
o n e tud program executable by executing
the following commands at the Linux terminal S
s is prompt:
i @ h
i cc se t
# cd /labs/python/cli/activity17-4/
ฺ r
e r to to u
# chmod +x memcached_test.py

i
optionscto
roba key/value
5. In terminal window
(write T1, s
e n e the memcached_test.py program with the following
execute

i c l i c pair to the cache.

t o R # python memcached_test.py SET mysql 0001


be r Enter the following command at the T1 Linux terminal prompt and receive the results
Ro shown:
# python memcached_test.py SET mysql 0001
SET KEY: mysql, VALUE: 0001
SET RESULT: True
− The program executes and confirms the successful addition of the item to the
cache.
6. At the mysql prompt in terminal window T2, verify that the demo_test table in the test
database contains a record for the key/value pair you added to the cache in the previous
step.
Enter the following statements at the mysql prompt in terminal window T2 and receive the
results shown:
mysql> USE test
Database changed

mysql> SELECT * FROM demo_test;


+-------+------+------+------+------+
| c1 | c2 | c3 | c4 | c5 |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 27
+-------+------+------+------+------+
| mysql | 0001 | 0 | 1 | 0 |
+-------+------+------+------+------+
1 row in set (#.## sec)
− Unlike stand-alone memcached systems that hold values in memory, the plug-in
stores the cache data in a database table, which you can query with SQL.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

− Note: The values for c3, c4, and c5 might be different on your system.
7. In terminal window T1, execute the memcached_test.py program with the following
options. This uses the key to retrieve the value you set in step 5 from the cache.
# python memcached_test.py GET mysql
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# python memcached_test.py GET mysql
ble
GET KEY: mysql
GET VALUE: 0001
fe r a
− The program executes and displays the value associated with the key mysql. ans
n - t r
8. In terminal window T2, exit the mysql client.
n o
Enter the following statement at the mysql prompt in terminal window a
s T2 and receive the
results shown: h a
ฺ b r) deฺ
mysql> EXIT
c o m Gui
Bye
#
p a rฺ ent
ne server
9. In terminal window T2, shut down theoMySQL
s S tudby using the following command:
# service mysqld stop c i @ this
o ฺ
Enter the following command
t ric at the
u e Linux terminal prompt and receive the results
sT2
shown: b e r to
(ro mysqld e
ns stop
c i
# service
c li c e
R iStopping mysqld: [ OK ]

b rtoIn terminal window T1, execute the memcached_test.py program with the following
e10.
Ro options to attempt to write a new value to the cache:
# python memcached_test.py SET XYZ 4321
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# python memcached_test.py SET XYZ 4321
MemCached: MemCache: inet:127.0.0.1:11211: connect: [Errno 111]
Connection refused. Marking dead.
SET KEY: XYZ, VALUE: 4321
SET RESULT: False
− The operation fails, because the memcached plug-in is no longer running.
11. In terminal window T2, check to see whether the memcached plug-in for InnoDB is still
listening on port 11211 by issuing the following Linux command:
# netstat -tulpn | grep :11211

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 28
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# netstat -tulpn | grep :11211
#
− There are no processes listening on port 11211.
12. In terminal window T2, start the MySQL server with the following command at the shell
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

prompt:
# service mysqld start
Enter the following command at the T2 Linux terminal prompt and receive the results
shown:
# service mysqld start
Starting mysqld: [ OK ]
#
ble
13. In terminal window T2, log in to the MySQL server with the mysql command-line client.
fe r a
Enter the following command at the T2 Linux terminal prompt and receive the results
an s
shown:
n - t r
# mysql -uroot -p
a no
Enter password: oracle
h a s
. . . ฺ b r) deฺ
Welcome to the MySQL monitor. Commands end with ; or \g.

o m Gui
Type 'help;' or '\h' for help. Type '\c' to clear the current input
c
statement.
p a rฺ ent
mysql>
s one s Stud
14. In terminal window T2, list thec @ tofhthe
icontents i test database’s demo_test table to verify
i c e
that the item you addedฺrin step 4 issstill there.
e
Enter the following r to toatuthe mysql prompt in terminal window T2 and receive the
statements
(
results shown:
i rob ense
R cc USElictest
imysql>
erto ...
Reading table information
b
Ro Database changed

mysql> SELECT * FROM demo_test;


+-------+------+------+------+------+
| c1 | c2 | c3 | c4 | c5 |
+-------+------+------+------+------+
| mysql | 0001 | 0 | 1 | 0 |
+-------+------+------+------+------+
1 row in set (#.## sec)
− Even though you shut down the MySQL server, disabling the memcached plug-in,
the item you stored earlier is still in the table.
− Note: The values for c3, c4, and c5 might be different on your system.
15. In terminal window T1, execute the memcached_test.py program with the following
options to write a new value to the cache:
# python memcached_test.py SET XYZ 4321

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 29
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# python memcached_test.py SET XYZ 4321
SET KEY: XYZ, VALUE: 4321
SET RESULT: True
− This time the operation is successful.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

16. In terminal window T1, use the memcached_test.py program to verify that the new item
you added in the previous step is stored in the cache by executing the following command:
# python memcached_test.py GET XYZ
Enter the following command at the T1 Linux terminal prompt and receive the results
shown:
# python memcached_test.py GET XYZ
GET KEY: XYZ
ble
GET VALUE: 4321
− The program executes and displays the value associated with the new key XYZ. fe r a
ans
17. Close terminal window T1.
n - t r
Enter the following command at the T1 Linux terminal prompt:
a no
# exit
h a s
ฺ r) terminal
18. In terminal window T2, exit the mysql client, but leave thebLinux
d e ฺ window open for
the next practice.
om t Gu i
r ฺ
a and
Enter the following statement at the mysql prompt
c n the results shown:
receive
e p d e
mysql> EXIT
s on s Stu
Bye
c c i@ thi
#
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 30
Practice 17-5: Manipulating JSON Data
Overview
In this practice, you use MySQL functions to add and remove fields in JSON documents and
generate indexes into JSON data by using generated columns.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
You have a Linux terminal window open from the preceding practice.

Duration
This practice should take approximately 15 minutes to complete.

Tasks
ble
1. Examine the /labs/sql/sensor.sql file in your favorite text editor or MySQL
fe r a
Workbench. This SQL script creates a database called sensor with a single table called
ans
sensor_status. The sensor_status table contains a single column called status of
n - t r
a no
JSON data type. The JSON data represents sensor equipment with the ability to record
temperature, pressure, or both and the last readings and the time they were taken.
The following is an extract from the sensor.sql file: h a s
ฺ b r) deฺ
DROP DATABASE IF EXISTS sensor;
CREATE DATABASE sensor;
c o m Gui
USE sensor;
CREATE TABLE sensor_status ( ep
arฺ dent
status JSON NOT NULL
s on s Stu
);
i c c e t hi
i@ (status)
r t o ฺr
INSERT INTO sensor_status
us
VALUES
b e
( '{"device_id":
e
1001,t o "measurement_date": 1460592000, "last_temp":
i r o
( cen),
54, "last_pressure": s 27.8, "capabilities": ["temperature",
c li
Ri(c '{"device_id":
"pressure"]}'
1001, "measurement_date": 1460678400, "last_temp":
e r to 53, "last_pressure": 28.2, "capabilities": ["temperature",

R ob "pressure"]}' ),
( '{"device_id": 1001, "measurement_date": 1460764800, "last_temp":
60, "last_pressure": 30.1, "capabilities": ["temperature",
"pressure"]}' ),
...
2. Execute the labs/sql/sensor.sql script to create and populate the sensor database.
3. The sensor manufacturer adds the capability to power the sensor on and off. Add a new
field called on to the JSON data in the sensor column that describes this state and set its
initial value to a JSON “null”. Verify the change to the table data.
Hint: Use the JSON_INSERT(json_doc, path, val[, path, val] ...) function to
add data to JSON documents without overwriting existing data.
4. The sensor manufacturer removes this capability. Remove the on field from the JSON
document.
Hint: Use the JSON_REMOVE(json_doc, path[, path] ...) function for this
operation.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 31
5. Device 1001 now receives humidity data. Add “humidity” to the capabilities array for this
device.
Hint: Use the JSON_EXTRACT(json_doc, path[, path] ...) function in the WHERE
clause to identify the correct device and use the
JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...) function to
modify the capabilities of that device.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

6. Add a new field called last_humidity to store the humidity readings for device 1001.
7. Add a new virtual generated column to the sensor_status table called device_id that
contains the “device_id” value from the JSON document. You will use this generated
column as an index in the next step.
8. Create an index on the sensor_status table’s device_id generated column called
sensor_idx and use an EXPLAIN statement to verify that the new index is available to the
MySQL optimizer.
ble
9. Leave the mysql command-line client open for the next practice.
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 32
Solution 17-5: Manipulating JSON Data
Solution Steps
1. Examine the /labs/sql/sensor.sql file in your favorite text editor or MySQL
Workbench. This SQL script creates a database called sensor with a single table called
sensor_status. The sensor_status table contains a single column called status of
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

JSON data type. The JSON data represents sensor equipment with the ability to record
temperature, pressure, or both and the last readings and the time they were taken.
The following is an extract from the sensor.sql file:
DROP DATABASE IF EXISTS sensor;
CREATE DATABASE sensor;
USE sensor;
CREATE TABLE sensor_status (
status JSON NOT NULL
ble
);
fe r a
INSERT INTO sensor_status (status)
VALUES
t r a ns
( '{"device_id": 1001, "measurement_date": n -
1460592000, "last_temp":
o
54, "last_pressure": 27.8, "capabilities":
"pressure"]}' ), an
["temperature",
s
( '{"device_id": 1001, "measurement_date":
) h a "last_temp":
1460678400,
53, "last_pressure": 28.2, "capabilities":
ฺ b r e ฺ
["temperature",
d
"pressure"]}' ), u i
om 1460764800,
( '{"device_id": 1001, "measurement_date":
a r ฺ c n t G "last_temp":

o n ep tude
60, "last_pressure": 30.1, "capabilities": ["temperature",
"pressure"]}' ),
@ s is S
...
c c i th to create and populate the sensor database.
r i
2. Execute the labs/sql/sensor.sql s e script
Enter the followinge r toฺ toatuthe
statements Linux terminal prompt and mysql command-line client
and receive r o
thebresults sshown:
e
c i ( -uroot c e n
R c
i...
# mysql l i -poracle

berto Welcome to the MySQL monitor. Commands end with ; or \g.


Ro ...

mysql> SOURCE /labs/sql/sensor.sql


Query OK, 1 row affected (#.## sec)

Query OK, 1 row affected (#.## sec)

Database changed
Query OK, 0 rows affected (#.## sec)

Query OK, 24 rows affected (#.## sec)


Records: 24 Duplicates: 0 Warnings: 0

mysql> SHOW DATABASES;


+--------------------+
| Database |
+--------------------+
| information_schema |
| innodb_memcache |
| logins |
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 33
| mysql |
| performance_schema |
| sakila |
| sensor |
| storedroutines |
| sys |
| test |
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| world |
+--------------------+
11 rows in set (#.## sec)
3. The sensor manufacturer adds the capability to power the sensor on and off. Add a new
field called on to the JSON data in the sensor column that describes this state and set its
initial value to a JSON “null”. Verify the change to the table data.
Hint: Use the JSON_INSERT(json_doc, path, val[, path, val] ...) function to
add data to JSON documents without overwriting existing data.
ble
Enter the following statements at the mysql prompt and receive the results shown:
fe r a
ans
mysql> UPDATE sensor_status
-> SET status = JSON_INSERT(status, '$.on', CAST(NULL AS JSON));
n - t r
o
an
Query OK, 24 rows affected (#.## sec)
Rows matched: 24 Changed: 24 Warnings: 0
ha ฺs
mysql> SELECT * FROM sensor_status; r )
ฺb uide
m
+------------------------------------------------------+
| status
a r ฺco nt G |

| {"on": null, "device_id": n


o 1001, t de
ep "last_temp":
+------------------------------------------------------+
u 54, ... |
s 1001, S
| {"on": null, "device_id":
c i @ 1001,
t h is "last_temp": 60, ... |
"last_temp": 53, ... |

ฺ ic use 1002, "last_temp": 51, ... |


| {"on": null, "device_id":
r
| {"on": null, "device_id":
o
| {"on": null,
e t
r "device_id":
to 1002, "last_temp": 58, ... |
| {"on": b e
i ( r o null,
n s
"device_id": 1002, "last_temp": 61, ... |

c c
| ...
l i c e |

to Ri24 rows in set (#.## sec)


+------------------------------------------------------+

e r
R ob Note: You must cast the SQL NULL to its JSON equivalent in the JSON_INSERT()
function; otherwise, it evaluates to NULL.
4. The sensor manufacturer removes this capability. Remove the on field from the JSON
document.
Hint: Use the JSON_REMOVE(json_doc, path[, path] ...) function for this
operation.
Enter the following statements at the mysql prompt and receive the results shown:
mysql> UPDATE sensor_status
-> SET status = JSON_REMOVE(status, '$.on');
Query OK, 24 rows affected (#.## sec)
Rows matched: 24 Changed: 24 Warnings: 0

mysql> SELECT * FROM sensor_status;


+-----------------------------------------------------+
| status |
+-----------------------------------------------------+
| {"device_id": 1001, "last_temp": 54, ... |
| {"device_id": 1001, "last_temp": 53, ... |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 34
| {"device_id": 1001, "last_temp": 60, ... |
| {"device_id": 1002, "last_temp": 51, ... |
| {"device_id": 1002, "last_temp": 58, ... |
| {"device_id": 1002, "last_temp": 61, ... |
| ... |
+-----------------------------------------------------+
24 rows in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

5. Device 1001 now receives humidity data. Add “humidity” to the capabilities array for this
device.
Hint: Use the JSON_EXTRACT(json_doc, path[, path] ...) function in the WHERE
clause to identify the correct device and use the
JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...) function to
modify the capabilities of that device.
Enter the following statements at the mysql prompt and receive the results shown:
ble
mysql> UPDATE sensor_status
fe r a
-> SET status = JSON_ARRAY_APPEND(
ans
->
-> )
status, '$.capabilities', "humidity"
n - t r
-> WHERE JSON_EXTRACT(status, '$.device_id') = 1001;
a no
Query OK, 3 rows affected (#.## sec)
Rows matched: 3 Changed: 3 Warnings: 0 h a s
ฺ b r) deฺ
mysql> SELECT * FROM sensor_status;
c o m Gui
| status
p rฺ ent
+---------------------------------------------------------------------------+
a |
e
on s [... d
tu"pressure",
+---------------------------------------------------------------------------+

s
| {"device_id": 1001, ... "capabilities":
S "humidity"], ... |

c @ thi [... "pressure", "humidity"], ... |


| {"device_id": 1001, ... i"capabilities":
| {"device_id": 1001, ... "capabilities": [... "pressure", "humidity"], ... |

| {"device_id": 1002,
ฺ i c
...
se
r ... "capabilities":
"capabilities": ["temperature"], ... |

r t o
| {"device_id": 1002,
t o u ["temperature"], ... |

o b e
| {"device_id":
e
1002, ... "capabilities": ["temperature"], ... |
| ...
r
i ( inlisete n s |

c c
+---------------------------------------------------------------------------+
c
Ri
24 rows (#.## sec)

e r
6. toAdd a new field called last_humidity to store the humidity readings for device 1001.
R ob Enter the following statements at the mysql prompt and receive the results shown:
mysql> UPDATE sensor_status
-> SET status = JSON_INSERT(status, '$.last_humidity', 0)
-> WHERE JSON_EXTRACT(status, '$.device_id') = 1001;
Query OK, 3 rows affected (#.## sec)
Rows matched: 3 Changed: 3 Warnings: 0

mysql> SELECT * FROM sensor_status;


+-------------------------------------------------+
| status |
+-------------------------------------------------+
| {"device_id": 1001, ... "last_humidity": 0, ... |
| {"device_id": 1001, ... "last_humidity": 0, ... |
| {"device_id": 1001, ... "last_humidity": 0, ... |
| {"device_id": 1002, ... |
| {"device_id": 1002, ... |
| {"device_id": 1002, ... |
| ... |
+-------------------------------------------------+
6 rows in set (#.## sec)
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 35
7. Add a new virtual generated column to the sensor_status table called device_id that
contains the “device_id” value from the JSON document. You will use this generated
column as an index in the next step.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> ALTER TABLE sensor_status ADD device_id INT
-> AS (JSON_EXTRACT(status, '$.device_id'));
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Query OK, 0 rows affected (#.## sec)


Records: 0 Duplicates: 0 Warnings: 0

mysql> SELECT (JSON_EXTRACT(status, '$.device_id')) AS json_device,


-> device_id
-> FROM sensor_status;
+-------------+-----------+
| json_device | device_id |
+-------------+-----------+
ble
| 1001
| 1001
|
|
1001 |
1001 |
fe r a
| 1001 | 1001 |
ans
| 1002 | 1002 |
n - t r
| 1002
| 1002
|
|
1002 |
1002 | a no
...
h a s
24 rows in set (#.## sec)
ฺ b r) deฺ
8. Create an index on the sensor_status table’s device_id o m Ggeneratedu i column called
sensor_idx and use an EXPLAIN statement a r
to ฺ c
verify t
that
n the new index is available to the
p e
MySQL optimizer.
s ne prompt
omysql S tudand receive the results shown:
Enter the following statements at the
c i @ t h is
mysql> CREATE INDEX
o ฺ ic sensor_idx
raffected
u se(#.##ONsec)
sensor_status (device_id);
Query OK, 0 rows
Records: b
t
0erDuplicates:to 0 Warnings: 0
(roEXPLAIN s e
nSELECT
c i c e
li device_id*=FROM
R ic -> WHERE
mysql> sensor_status
1003\G

berto *************************** 1. row ***************************


Ro
id: 1
select_type: SIMPLE
table: sensor_status
partitions: NULL
type: ref
possible_keys: sensor_idx
key: sensor_idx
key_len: 5
ref: const
rows: 3
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (#.## sec)
9. Leave the mysql command-line client open for the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 36
Practice 17-6: Querying JSON Data
Overview
In this practice, you use MySQL JSON functions to retrieve data from JSON documents.

Assumptions
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

You have a Linux terminal window open from the preceding practice.

Duration
This practice should take approximately 30 minutes to complete.

Tasks
1. Use the JSON_LENGTH(json_doc[, path]) function to determine the different number
of elements that appear in the status field’s JSON documents. ble
fe r a
2. Use the JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)
ans
function to verify that both the “last_humidity” and “on” paths exist in the status field’s
n - t r
3.
JSON documents. Explain the result.
a no
Use the column->path shorthand syntax for JSON_EXTRACT() to list the device IDs of
those devices that last reported a temperature of 61. h a s
4. ฺ b r) deฺ
List the device IDs of all devices that contain “temperature”, “pressure”, and “humidity” in
the “capabilities” array. c o m Gui
p a rฺ ent
Hint: Use the JSON_CONTAINS(json_doc, val[, path]) function where val uses a
one s Stud
call to JSON_ARRAY([val[, val] ...] to match the required array values.
s
5. i@ thi
List the device IDs that contain “pressure” in the “capabilities” array and the path to that
c c
o ฺ r i
element in the JSON document.
u se
e r t to
Hint: Use the JSON_SEARCH(json_doc, one_or_all, search_str[,
b e
c i (ro cens
escape_char[, path] ...]) function to return the path.
6. Useic li
R the JSON_TYPE(json_val) function to return the JSON data type of both the

e r to “capabilities” array and its first element for each row in the sensor_status table.

R ob 7. List the different keys that appear in the status column’s JSON documents.
Hint: Use the JSON_KEYS(json_doc) function to return the keys.
8. List the device ID and the capabilities (without the surrounding quotation marks) of the
device with a last pressure reading of 29.7 in the following format:
+--------+-------------+-------------+-------------+
| device | capability1 | capability2 | capability3 |
+--------+-------------+-------------+-------------+
| 1003 | temperature | pressure | |
+--------+-------------+-------------+-------------+
Hints: Use the JSON_UNQUOTE(json_val) function to remove the quotation marks
around the string values in the “capabilities” array. Use the MySQL function
COALESCE(value, "") to remove any null values from the display output.
9. Exit all open mysql command-line sessions and Linux terminal prompts.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 37
Solution 17-6: Querying JSON Data
Solution Steps
1. Use the JSON_LENGTH(json_doc[, path]) function to determine the different number
of elements that appear in the status field’s JSON documents.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT DISTINCT JSON_LENGTH(status) FROM sensor_status;
+---------------------+
| JSON_LENGTH(status) |
+---------------------+
| 6 |
| 4 |
| 5 |
+---------------------+
ble
3 rows in set (#.## sec)
fe r a
2. Use the JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)
ans
function to verify that both the “last_humidity” and “on” paths exist in the status field’s
n - t r
JSON documents. Explain the result. o
s an
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT JSON_CONTAINS_PATH
r ) ha ฺ
-> (status, 'all', '$.last_humidity', ฺ'$.on')
m b ide
-> FROM sensor_status;
r ฺ c o t Gu
+-------------------------------------------+
e p a den
| JSON_CONTAINS_PATH
(status, 'all', '$.last_humidity', s tu
on s S'$.on') |
@
ci e th i
+-------------------------------------------+
|
ฺ r i c s 0 |
|
r t o t o u 0 |
|
o b e e 0 |
|
i ( r e n s 0 |
c li c
Ri|c
| 0 |

to
0 |
e r | 0 |

R ob ...
+-------------------------------------------+
24 rows in set (#.## sec)
− Answer: The function call returns zero (false) because only the “last_humidity” field
appears in the JSON document and you used the “all” modifier. If you used the
“one” modifier, then the result would be one (true) because at least one of the
supplied fields is present in the JSON document.
3. Use the column->path shorthand syntax for JSON_EXTRACT() to list the device IDs of
those devices that last reported a temperature of 61.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT status->'$.device_id'
-> FROM sensor_status
-> WHERE status->'$.last_temp' = 61;
+-----------------------+
| status->'$.device_id' |
+-----------------------+
| 1002 |
| 1003 |

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 38
| 1007 |
+-----------------------+
3 rows in set (#.## sec)
4. List the device IDs of all devices that contain “temperature,” “pressure,” and “humidity” in
the “capabilities” array.
Hint: Use the JSON_CONTAINS(json_doc, val[, path]) function where val uses a
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

call to JSON_ARRAY([val[, val] ...] to match the required array values.


Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT DISTINCT status->'$.device_id'
-> FROM sensor_status
-> WHERE JSON_CONTAINS(status, JSON_ARRAY('temperature',
'pressure', 'humidity'), '$.capabilities');
+-----------------------+
| status->'$.device_id' |
ble
+-----------------------+
| 1001 | fe r a
+-----------------------+
ans
1 rows in set (#.## sec)
n - t r
5. no
List the device IDs that contain “pressure” in the “capabilities” array and the path to that
a
element in the JSON document.
h a s
ฺ b r) deฺ
Hint: Use the JSON_SEARCH(json_doc, one_or_all, search_str[,

c o m Gui
escape_char[, path] ...]) function to return the path.

p a rฺ ent
Enter the following statement at the mysql prompt and receive the results shown:

s tud null, '$.capabilities') AS path


one'pressure',
mysql> SELECT status->'$.device_id' AS device,
S
-> JSON_SEARCH(status, 'one',
c
-> FROM sensor_statusi is IS NOT NULL;
@HAVINGthpath
| device | rpatht o ฺric use |
+---------+---------------------+

b e e to
(ro ||ce"$.capabilities[1]"
+---------+---------------------+
i
| 1001
c ns |
c
| 1001 l i
Ri| 1001 | "$.capabilities[1]" |
"$.capabilities[1]" |

e r to | 1003 | "$.capabilities[1]" |

R ob | 1003
| 1003
| "$.capabilities[1]" |
| "$.capabilities[1]" |
| 1005 | "$.capabilities[1]" |
| 1005 | "$.capabilities[1]" |
| 1005 | "$.capabilities[1]" |
| 1007 | "$.capabilities[1]" |
| 1007 | "$.capabilities[1]" |
| 1007 | "$.capabilities[1]" |
+---------+---------------------+
12 rows in set (#.## sec)
6. Use the JSON_TYPE(json_val) function to return the JSON data type of both the
“capabilities” array and its first element for each row in the sensor_status table.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT JSON_TYPE(status->'$.capabilities') AS capabilities,
-> JSON_TYPE(status->'$.capabilities[0]') AS first_element
-> FROM sensor_status;
+--------------+---------------+
| capabilities | first_element |
+--------------+---------------+
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 39
| ARRAY | STRING |
| ARRAY | STRING |
| ARRAY | STRING |
| ARRAY | STRING |
| ARRAY | STRING |
...
+--------------+---------------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

24 rows in set (#.## sec)


7. List the different keys that appear in the status column’s JSON documents.
Hint: Use the JSON_KEYS(json_doc) function to return the keys.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT DISTINCT JSON_KEYS(status)
-> AS json_keys
-> FROM sensor_status;
+--------------------------------------------------------------------------------------------------+
ble
| json_keys |
+--------------------------------------------------------------------------------------------------+
fe r a
| ["device_id", "last_temp", "capabilities", "last_humidity", "last_pressure", "measurement_date"] |
| ["device_id", "last_temp", "capabilities", "measurement_date"] |
ans
| ["device_id", "last_temp", "capabilities", "last_pressure", "measurement_date"]

n
|
+--------------------------------------------------------------------------------------------------+
- t r
no
3 rows in set (#.## sec)

8. a
List the device ID and the capabilities (without the surrounding quotation marks) of the
s
h a
device with a last pressure reading of 29.7 in the following format:
ฺ b r) deฺ
+--------+-------------+-------------+-------------+
| device | capability1 | capability2 |ocapability3
c m Gui |
a rฺ ent
+--------+-------------+-------------+-------------+
p
| 1003 | temperature | pressure
o n e tu| d |
s is S
+--------+-------------+-------------+-------------+
@
c i
Hints: Use the JSON_UNQUOTE(json_val)
c th function to remove the quotation marks
around the string values r i e
us any nullarray.
ฺ in the “capabilities” Use the MySQL function
e r to"") o
totremove values from the display output.
COALESCE(value,
b
roCOALESCE()se returns the first non-NULL value in the parameter list, or NULL
i
− Note:( e n
R iccif there are
licno non-NULL values.
bertoEnter the following statement at the mysql prompt and receive the results shown:
Ro mysql> SELECT DISTINCT status->'$.device_id' AS device,
-> COALESCE(JSON_UNQUOTE(status->'$.capabilities[0]'),"")
-> AS capability1,
-> COALESCE(JSON_UNQUOTE(status->'$.capabilities[1]'),"")
-> AS capability2,
-> COALESCE(JSON_UNQUOTE(status->'$.capabilities[2]'),"")
-> AS capability3
-> FROM sensor_status
-> WHERE status->'$.last_pressure' = 29.7;
+--------+-------------+-------------+-------------+
| device | capability1 | capability2 | capability3 |
+--------+-------------+-------------+-------------+
| 1003 | temperature | pressure | |
+--------+-------------+-------------+-------------+
8 rows in set (#.## sec)

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 40
9. Exit all open mysql command-line sessions and Linux terminal prompts.
Enter the following statements at the mysql prompt and Linux terminal windows:
mysql> EXIT
Bye
# exit
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 41
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 17: NoSQL


Chapter 17 - Page 42
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 18:
Spatial omDataGu i
a r ฺ c n t
p e
one s Stud
Chapter 18
s
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 1
Practices for 18: Spatial Data
Practices Overview
These practices test your knowledge of working with spatial data in MySQL. They assume that
you are using the Linux operating system environment provided in Oracle classrooms. For
non-Oracle classrooms, you might need to make some adjustments to file locations.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Assumptions
None

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 2
Practice 18-1: Creating Spatial Data
Overview
In this practice, you create a table with a GEOMETRY column to contain spatial data that
represents the location of fictitious restaurants in the city of Malaga in Spain.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take approximately 20 minutes to complete.

Tasks
1. At a Linux terminal prompt, log in to the mysql client as root (password: oracle).
2. Create a new database named malaga.
3. In the malaga database, create a new table called restaurant with the following columns
ble
and attributes:
fe r a
• name: VARCHAR(25), NOT NULL
ans
• g: GEOMETRY, NOT NULL n - t r
4. Populate the restaurant table with the following row data: a no
• Name: “Las Iguanas”, Location: (-4.433, 36.73) h a s
• Name: “Picassos”, Location: (-4.421, 36.729) ฺ b r) deฺ
c o m Gui
• Name: “La Tasca”, Location: (-4.430, 36.720)
p a rฺ ent
• Name: “El Pirata”, Location: (-4.434,
• Name: “Alquima”, Location: (-4.406, s one36.724) tud
36.726)
S
c i @(-4.414,
t h is
• Name: “Amantia”, Location:
t o ฺ ric u(-4.424,
se 36.718)
36.731)
• Name: “El Metro”,
b e r to spatial function to encode the point coordinate data in a
Location:

(risosuitable
Note: Use an appropriate e
nfors storage in a MySQL GEOMETRY column.
MySQL
formatc i
that c e
li query that displays the name and coordinate data of all rows in the
R ic a suitable
5. oExecute
b e rt restaurant table.
R o Note: Use a suitable MySQL function to convert the values stored in the GEOMETRY column
g into readable coordinates.
6. Keep the Linux terminal window open and connected to the mysql command-line client for
the next practice.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 3
Solution 18-1: Creating Spatial Data
Solution Steps
1. At a Linux terminal prompt, log in to the mysql client as root (password: oracle)
Enter the following command at the Linux terminal prompt and receive the results shown:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

# mysql -uroot -poracle


Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql>
2. Create a new database named malaga.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> CREATE DATABASE malaga;
Query OK, 1 row affected (#.## sec)
bl e
3. In the malaga database, create a new table called restaurant with the following columns
fe r a
and attributes: n s
• name: VARCHAR(25), NOT NULL n - tra
• g: GEOMETRY, NOT NULL a no
Enter the following statements at the mysql prompt and receive h a
the
sresults shown:
ฺ b r) deฺ
mysql> USE malaga
c o m Gui
Database changed
p a rฺ ent
mysql> CREATE TABLE restaurante(
name VARCHAR(25)so
n Stud
@NULL this
-> NOT NULL,
->
c
g GEOMETRY NOTi
-> );
o ic use
ฺraffected
Query OK, 0 rrows
e t t o (#.## sec)
4. Populate the b
rorestaurantse table with the following row data:
i ( e n
cc “LasliIguanas”,
• iName:
R
c Location: (-4.433, 36.73)

erto
• Name: “Picassos”, Location: (-4.421, 36.729)
b
Ro • Name: “La Tasca”, Location: (-4.430, 36.720)
• Name: “El Pirata”, Location: (-4.434, 36.726)
• Name: “Alquima”, Location: (-4.406, 36.724)
• Name: “Amantia”, Location: (-4.414, 36.731)
• Name: “El Metro”, Location: (-4.424, 36.718)
Note: Use an appropriate MySQL spatial function to encode the point coordinate data in a
format that is suitable for storage in a MySQL GEOMETRY column.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> INSERT INTO restaurant (name, g)
-> VALUES
-> ("Las Iguanas", ST_GeomFromText('POINT(-4.433 36.734)')),
-> ("Picassos", ST_GeomFromText('POINT(-4.421 36.729)')),
-> ("La Tasca", ST_GeomFromText('POINT(-4.430 36.720)')),
-> ("El Pirata", ST_GeomFromText('POINT(-4.434 36.726)')),
-> ("Alquima", ST_GeomFromText('POINT(-4.406 36.724)')),
-> ("Almantia", ST_GeomFromText('POINT(-4.414 36.731)')),
-> ("El Metro", ST_GeomFromText('POINT(-4.424 36.718)'));

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 4
Query OK, 7 rows affected (#.## sec)
Records: 7 Duplicates: 0 Warnings: 0
5. Execute a suitable query that displays the name and coordinate data of all rows in the
restaurant table.
Note: Use a suitable MySQL function to convert the values stored in the GEOMETRY column
g into readable coordinates.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT name, ST_AsText(g) FROM restaurant;
+-------------+----------------------+
| name | ST_AsText(g) |
+-------------+----------------------+
| Las Iguanas | POINT(-4.433 36.734) |
| Picassos | POINT(-4.421 36.729) |
| La Tasca | POINT(-4.43 36.72) |
ble
| El Pirata | POINT(-4.434 36.726) |
fe r a
| Alquima
| Almantia
| POINT(-4.406 36.724) |
| POINT(-4.414 36.731) |
ans
| El Metro | POINT(-4.424 36.718) |
n - t r
+-------------+----------------------+
a no
7 rows in set (#.## sec)
h a s
the next practice. ฺ b r) dcommand-line
6. Keep the Linux terminal window open and connected to the mysql
e ฺ client for

c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
R ic li
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 5
Practice 18-2: Using Spatial Indexes for Analysis
Overview
In this practice, you create a spatial index on the GEOMETRY column in the restaurant table
that you created in the previous practice and use it to locate all restaurants in a specific area.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Duration
This practice should take you approximately 25 minutes to complete.

Tasks

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob 1. The map above shows the location of the restaurants in the restaurant table and a
polygon with the following coordinates:
• -4.422, 36.732
• -4.440, 36.723
• -4.427, 36.718
• -4.411, 36.733
• -4.422, 36.732
Note: The beginning and end coordinates of the polygon are identical, effectively “closing”
the polygon.
Create a variable called @poly to store the polygon coordinates in Well-Known Text (WKT)
format.
2. Create a spatial index on the GEOMETRY column g in the restaurant table.
3. Execute a query that uses the MySQL ST_Contains(g1, g2) function to list all
restaurants that are located within the polygon defined in the @poly variable. The first

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 6
parameter to the ST_Contains() function is the polygon and the second parameter is the
location of the restaurant stored in the GEOMETRY column g.
Note: Use a suitable MySQL function to encode the Well-Known Text (WKT) that is stored
in the @poly variable in MySQL GEOMETRY format.
4. Refer to the map at the beginning of this practice to ensure that the restaurants retrieved by
your query are located within the polygon of interest.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

5. The following coordinates describe the route taken by a road called the Calle Mármoles (not
identified on the map diagrams), which can be described in MySQL as a LINESTRING.
-4.44000, 36.72148
-4.43579, 36.72150
-4.43262, 36.72153
-4.43007, 36.72151
-4.42680, 36.72172
-4.42530, 36.72176
ble
Execute spatial queries that answer the following questions:
fe r a
a. Does the route taken by the Calle Mármoles fall completely within the polygon that you
ans
defined in step 1?
n - t r
o
step 1? s an
b. Does the route taken by the Calle Mármoles intersect the polygon that you defined in

r ) ha ฺ
c. What is the distance between the start and end points of the Calle Mármoles?
m ฺb uide
Note: For information about the correct spatial functions to use, refer to the MySQL
r ฺco nt G
Reference Manual at: https://dev.mysql.com/doc/mysql/en/spatial-relation-functions-object-
a
shapes.html#function_st-within.
o n ep tude
6. s is S
Exit the mysql client and close the Linux terminal window.
@
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 7
Solution 18-2: Using Spatial Indexes for Analysis
Solution Steps
1. The map shows the location of the restaurants in the restaurant table and a polygon with
the following coordinates:
• -4.422, 36.732
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

• -4.440, 36.723
• -4.427, 36.718
• -4.411, 36.733
• -4.422, 36.732
Note: The beginning and end coordinates of the polygon are identical, effectively “closing”
the polygon.
ble
Create a variable called @poly to store the polygon coordinates in Well-Known Text (WKT)
format. fe r a
ans
Enter the following statement at the mysql prompt and receive the results shown:
n - t r
mysql> SET @poly = 'Polygon((-4.422 36.732, -4.440 36.723, -
a no
4.427 36.718, -4.411 36.733, -4.422 36.732))';
h a s
br) ideฺtable.
Query OK, 0 rows affected (#.## sec)
2. Create a spatial index on the GEOMETRY column g in m theฺrestaurant
u
r ฺ c oand receive
t G
Enter the following statement at the mysql prompt
p a e n the results shown:
mysql> ALTER TABLE restaurant
-> ADD SPATIAL INDEX s one s Stud
hi sec)
(g);
Query OK, 0 rows affected
c c i@ (#.##
t
o
Records: 0 Duplicates: ฺr i u e
0s Warnings: 0
r t o
ethat usesethet MySQL ST_Contains(g1, g2) function to list all
3. Execute a query
o b
restaurants
c i r
( that are
c e ns within the polygon defined in the @poly variable. The first
located
ic to theliST_Contains() function is the polygon and the second parameter is the
parameter
R
erto
location of the restaurant stored in the GEOMETRY column g.
b
Ro
Note: Use a suitable MySQL function to encode the Well-Known Text (WKT) that is stored
in the @poly variable in MySQL GEOMETRY format.
Enter the following statement at the mysql prompt and receive the results shown:
mysql> SELECT name, ST_AsText(g) FROM restaurant
-> WHERE ST_Contains(ST_GeometryFromText(@poly), g);
+----------+----------------------+
| name | ST_AsText(g) |
+----------+----------------------+
| Picassos | POINT(-4.421 36.729) |
| La Tasca | POINT(-4.43 36.72) |
| Almantia | POINT(-4.414 36.731) |
+----------+----------------------+
3 rows in set (#.## sec)
4. Refer to the map at the beginning of this practice to ensure that the restaurants retrieved by
your query are located within the polygon of interest.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 8
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
5. The following coordinates describe the routep a rฺ a nroad
taken by e
t called the Calle Mármoles (not
identified on the map diagrams), which
s S tud in MySQL as a LINESTRING.
e be described
oncan
-4.44000, 36.72148
c i @ this
-4.43579, 36.72150
t o ฺ ric use
r
-4.43262, 36.72153
-4.43007,be to
(ro 36.72172
36.72151
ns e
c i
-4.42680,
li c e
R ic
-4.42530, 36.72176

erto
Execute spatial queries that answer the following questions:
b
Ro
a. Does the route taken by the Calle Mármoles fall completely within the polygon that you
defined in step 1?
b. Does the route taken by the Calle Mármoles intersect the polygon that you defined in
step 1?
c. What is the distance between the start and end points of the Calle Mármoles?
Note: For information about the correct spatial functions to use, refer to the MySQL
Reference Manual at: https://dev.mysql.com/doc/mysql/en/spatial-relation-functions-object-
shapes.html#function_st-within.
a. Is the route taken by the Calle Mármoles completely within the polygon that you
defined in step 1?
− Enter the following statements at the mysql prompt and receive the results shown:
mysql> SET @route = 'LINESTRING(
'> -4.44000 36.72148,
'> -4.43579 36.72150,
'> -4.43262 36.72153,
'> -4.43007 36.72151,
'> -4.42680 36.72172,

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 9
'> -4.42530 36.72176
'> )';
Query OK, 0 rows affected (#.## sec)

mysql> SELECT ST_Within(ST_GeometryFromText(@route),


-> ST_GeometryFromText(@poly)) AS Within;
+--------+
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

| Within |
+--------+
| 0 |
+--------+
1 row in set (#.## sec)
− Answer: The ST_Within() function returns zero, so the route is not completely
within the polygon.
b. Does the route taken by the Calle Mármoles intersect the polygon that you defined in
step 1? ble
fe r a
− Enter the following statement at the mysql prompt and receive the results shown:
ans
mysql> SELECT ST_Intersects(ST_GeometryFromText(@route),
n - t r
-> ST_GeometryFromText(@poly)) AS Intersect;
a no
+-----------+
| Intersect | h a s
+-----------+
ฺ b r) deฺ
| 1 |
c o m Gui
+-----------+
p a rฺ ent
one s Stud
1 row in set (#.## sec)
s
− Answer: The ST_Intersects() function returns one, so the route intersects the
polygon.
c c i@ thi
c. o ฺ r i u se
What is the distance between the start and end points of the Calle Mármoles in the
e r t to
b
default units for the Spatial Reference System being used?
e
i (rothe following
− Enter
c c e ns statements at the mysql prompt and receive the results shown:
R c
imysql> li
SET @start = POINT(-4.44000, 36.72148);

berto Query OK, 0 rows affected (#.## sec)


Ro mysql> SET @end = POINT(-4.42530, 36.72176);
Query OK, 0 rows affected (#.## sec)

mysql> SELECT ST_Distance(@start, @end);


+---------------------------+
| ST_Distance(@start, @end) |
+---------------------------+
| 0.014702666424836456 |
+---------------------------+
1 row in set (#.## sec)
− Answer: Approximately 0.015
− Note: The ST_Distance() function returns the distance using the units defined by
the Spatial Reference System that is used to specify the coordinates in these
practices (SRID=4326). These are degrees of latitude and longitude, which are not
helpful for displaying distances. For a more useful representation, use the
ST_Distance_Sphere() function, which returns the minimum distance between
two points on a sphere in meters:

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 10
mysql> SELECT ST_Distance_Sphere(@start, @end);
+----------------------------------+
| ST_Distance_Sphere(@start, @end) |
+----------------------------------+
| 1310.5530427618276 |
+----------------------------------+
1 row in set (#.## sec)
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

6. Exit the mysql client and close the Linux terminal window.
Enter the following statement at the mysql and Linux terminal prompt and receive the
results shown:
mysql> EXIT
Bye
# exit

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 11
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 18: Spatial Data


Chapter 18 - Page 12
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
Practices bfor
ฺ r) Lesson
d e ฺ 19:
Conclusionom t Gu i
r ฺ c
a 19den
e p
Chapter
s on s Stu
c c i@ thi
o ฺ r i u se
e r t to
b e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 19: Conclusion


Chapter 19 - Page 1
Practices for Lesson 19: Conclusion

There are no practices for this lesson.


Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Practices for Lesson 19: Conclusion


Chapter 19 - Page 2
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
AppendixbA: r ) ha ฺ
Sample
Databases m ฺ uide
r o
ฺc nt G
a
p u20de
eChapter
s o n S t
c i@ thi s
ฺ r i c se
r t o to u
b e e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 1
world Schema Data Model
The world database contains three tables: City, Country, and CountryLanguage.
For each country, the database stores information including:
• Name, continent, and region within that continent
• Population, surface area, gross national product (GNP), and historical GNP
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

• Government form and head of state


• Languages spoken
o Languages are named in the linked CountryLanguage table, along with the
percentage of the population who speak that language, and whether it is an
official language.
• Capital city
For each city, the database contains: ble
• Name, district, population, and its associated country fe r a
ans
Note: The information in the world database is presented for instructional purposes and is not
current. n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 2
sakila Schema Data Model

The sakila database contains 16 tables and 7 views, along with stored procedures, functions,
and triggers.

To more easily understand their function, the tables in the sakila database can be categorized
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

into three groups:


• Customer Data information
• Business information
• Inventory information

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 3
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 4
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 5
Inventory
For each inventory item, the database stores:
• The stock item, which is a film
• Title, Release year, rating, replacement cost, rental duration, and rate of the film
• Actors
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

• Categories (Family, Horror, Animation, and so on)


• Long text description
• Languages (Original and Overdubbed)

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 6
Customer Data
The database stores each customer’s contact details in the customer table, including:
• First and last name
• Email
• Address
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 7
Business
To run the business, the database contains the following tables:
• staff, linked to their addresses
• store, linked to addresses
• rental and payment tables, linking the business to the inventory items and customers
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix A: Sample Databases


Chapter 20 - Page 8
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
AppendixbB: r ) ha ฺ
MySQL
Workbench m ฺ uide
r o
ฺc nt G
a
p u21de
eChapter
s o n S t
c i@ thi s
ฺ r i c se
r t o to u
b e e
c i (ro cens
Ric li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 1
Appendix B: MySQL Workbench
Overview
This appendix contains a brief introduction to some of the server administration and SQL
development features of the MySQL Workbench tool.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 2
Introduction
MySQL Workbench is a graphical tool for working with MySQL servers and databases. It
provides data modeling, SQL development, and comprehensive administration tools for server
configuration, user administration, backup, and other critical tasks. MySQL Workbench is
available on Windows, Linux, and Mac OS X.
The MySQL Workbench visual toolset helps database architects, developers, and DBAs in
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

many aspects of database development:


• Design: Design, model, generate, and manage databases in a visual environment.
MySQL Workbench contains everything a database modeler needs to create
complex entity relationship diagrams, forward and reverse engineer databases
and deal with change management and documentation tasks.
• Development: Create, execute, and optimize database queries. The SQL Editor
provides color syntax highlighting, automatic statement completion, the ability to store
and reuse SQL snippets, and a statement execution history. The Database Connections ble
Panel enables developers to easily manage database connections. The Object Browser fe r a
provides instant access to database entities.
ans
• Administration: Connect to and configure servers, monitor database health, execute n - t r
backup and recovery operations, manage users, and inspect audit data.
a no
a s
• Database Migration: Migrate data from other relational databases, such as Microsoft
h
ฺ b r) deฺ
SQL Server, Sybase ASE, PostgreSQL and others, as well as from earlier versions of

c o m Gui
MySQL. Easily convert existing applications to run on MySQL on Windows and other
platforms.
p a rฺ ent
MySQL Workbench is available in community
s S tud editions. The community edition
oneands commercial
is free. Commercial editions provide
c i@ t i
additional features,
hgraphical such as database documentation
generation, schema and model
ฺ r i c s e
validation, and interfaces to other MySQL Enterprise
tools, at low cost. r t o to u
b e e
c i (ro cens
R ic li
e r to
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 3
MySQL Server Administration
Overview
The following steps guide you through setting up an administrative connection to a MySQL
server, and performing basic system administration functions.
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

Tasks
1. Launch MySQL Workbench by clicking Applications > Programming > MySQL Workbench.
2. On the MySQL Workbench home page, click the + (plus) symbol next to “MySQL
Connections” (shown below).

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 4
3. The “Setup New Connection” dialog box appears:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
4. In the Connection Name textcfield,
i for the connection.
i@entertha name
i c e
ฺris root,uand
s click the “Store in Keychain” button.
5.
e r t
Verify that the usernameo t o
6.
i ( r ob nforsConnection”
The “Store Password e dialog box appears. Enter oracle and press OK.
7. c to enter
If prompted e
lic a password for the default keyring, use oracle again.
8. Ric
toMySQL server sets the current database to sakila. This is equivalent to executing the
Enter sakila in the Default Schema text field. When you establish the connection, the
e r
R ob following statement at the mysql command-line prompt:
mysql> USE sakila;
9. Leave all other values at their default settings. The default values create a TCP/IP
connection to a MySQL server instance running on localhost (127.0.0.1).
10. Click the Test Connection button. If all settings are correct, the following message appears:

11. Click OK to close the Test Connection dialog box.


The following steps collect more details about your server instance so that MySQL Workbench
can provide the correct configuration preset for the connection.
12. Click the Configure Server Management button.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 5
13. The Configure Local Management Wizard opens and displays an introductory message.
Click Next to proceed.
14. The wizard performs a connection test and returns basic information about the server
instance which you will fine-tune in the next step. Click Next.
15. Select the operating system and type of database installation that has the closest
resemblance to your server instance. For best results in the Oracle classroom environment,
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

select the default values (shown below):


• Operating System: Linux
• MySQL Installation Type: Generic Linux (MySQL tar package)
Click Next.
16. MySQL Workbench connects to the host machine and checks some configuration settings.
When you receive the message “Testing host machine settings is done,” click Next.

ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
to Ric
e r
R ob

17. The Review Settings dialog box appears and displays a message telling you that the
connection and configuration settings are correct for your new server instance. Click
Continue.
18. The wizard closes. In the Setup New Connection dialog box, click OK.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 6
19. On the MySQL Workbench home page, note the new connection under MySQL
Connections:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ
20. Double-click the new connection.r i u se
21. A new tab appears e t
rin MySQLtoWorkbench, with the same name as the connection. Note the
b se
o SQL ndevelopment),
r(for
Query pane
c i ( c e Action Output pane (for server messages), and options

R c
iscreen.
for Server Status,l i Client Connections, Data Import/Export, and so on down the left side of
the
berto
22. Click the twin-headed arrow icon next in the SCHEMAS section on the left. This puts the
Ro schema information into its own tab and separates it from the management options. MySQL
Workbench allows you to customize many aspects of the interface in this way.
23. Click Server Status on the Management tab. This page provides a summary of the active
server instance, including graphs displaying real-time statistics:
• Load
• Connections
• Traffic
• Key Efficiency
• Queries per Second
• InnoDB Buffer Usage
• InnoDB Reads per Second
• InnoDB Writes per Second

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 7
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
24. On the Management tab, click Startup/Shutdown.
25. A new Administration tab appears,
i c c e t hi that the server instance is running. Click Stop
i@ confirming
Server. If prompted, enter
r t o ฺr the password
u s oracle.
b
26. If the server fails eto stop, echecko
t the Startup Message Log area on the Administration tab,
i r o n s
and see if (the server generates messages similar to the following:
c c l i c e
i2013-09-10 07:51:38 - Checked server status: Server is running.
o R
ert
Could not open error log file: sudo: sorry, you must have a tty to run
b sudo
Ro 2013-09-10 07:51:45 - Stopping server...
2013-09-10 07:51:45 - Executing '/etc/init.d/mysql stop'
2013-09-10 07:51:45 - Stop server: sudo: sorry, you must have a tty to
run sudo
If the server does not stop running and the log shows the sudo: sorry you must have
a tty to run sudo message, perform the following steps:
a. At a Linux terminal prompt, enter the following command:
# visudo
b. Use the arrow keys to move to the beginning of the following line (Defaults
requiretty).
# You have to run “ssh –t hostname sudo <cmd>”.
#
Defaults requiretty
c. Press the i key. This changes the vi editor mode to INSERT.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 8
d. Enter the # symbol. The entry shown above now looks like the following:
# You have to run “ssh –t hostname sudo <cmd>”.
#
#Defaults requiretty
e. Enter :wq! to save your changes to the /etc/sudoers file and return to the Linux
shell as shown in the following:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

:wq!
#
− visudo is a utility command that helps you safely edit the /etc/sudoers file in
your Linux installation.
f. Exit the Linux terminal prompt:
# exit
g. On the MySQL Workbench Administration tab, click the Stop Server button.
ble
27. When the server has stopped running, click the Start Server button. If prompted, enter the
fe r a
password oracle.
ans
28. On the Management tab, select the “Status and System Variables” option. n - t r
o
29. an
On the Status Variables tab, enter InnoDB in the search box. Note the InnoDB status
s
30.
variables that appear.
On the Management tab, select Options File. r ) ha ฺ
m ฺb uide
31.
that it is /etc/my.cnf. a r ฺco nt G
View the location of the configuration file at the bottom of the Administration tab, and note

32. n ep tude
Click the InnoDB tab and examine the options available.
o
33. @ s is S
In the “Locate option” search box, enter autocommit and click Find. Select the
c c i th
i
autocommit option to enable it.
r e
34. Click Apply. e r toฺ to us
35. rob ense
In the “Apply Changes to MySQL Configuration File” dialog box, examine the changes and
i (
c
click Apply. lic
to
36. Ric
Using a Linux terminal, view the contents of the /etc/my.cnf file by entering:
e r
R ob # cat /etc/my.cnf
− Note the addition of the autocommit setting.
37. Repeat the previous steps to disable the “autocommit” setting in the option file and verify
the change.
38. Examine the other options available on the Management tab.
39. Close the Administration tab.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 9
SQL Development in MySQL Workbench
Overview

The following steps provide a brief overview of some of the MySQL Workbench features that
assist in SQL development. This tutorial builds on the steps in the lesson titled “MySQL Clients”
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

and covers features of the SQL Development module not covered in that lesson.

Tasks
1. On the MySQL home page, double-click the new connection that you created in the
previous section.
2. A new tab displays with the same name as your connection.
3. Click the Schemas tab. Note that the sakila database is displayed in bold. This is
because the connection that you created previously sets sakila as the default database:
ble
fe r a
ans
n - t r
o
s an
r ) ha ฺ
m ฺb uide
a r ฺco nt G
o n ep tude
@ s is S
c c i th
r i e
e r toฺ to us
i ( rob ense
c lic
4. Ric
Click sakila on the Schemas tab and drill down through the hierarchy of database entities
tofor the sakila database until you find the film table.
b e r
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 10
5. Right-click the film table and select “Select Rows – Limit 1000” from the shortcut menu.
− MySQL Workbench generates the equivalent SQL statement on a “film” query tab and
the results of the query appear below it:
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

ble
fe r a
ans
n - t r
a no
h a s
ฺ b r) deฺ
c o m Gui
p a rฺ ent
s one s Stud
c c i@ thi
o ฺ r i u se
e r t to
b e
6.
c (ro button
Click thei Export
c e nsabove the query results. The Export Resultset dialog box appears.
Ric li
e r to
R ob

7. Enter the name FilmOutput, and note the default format “CSV.” Click Save. This creates
a comma-delimited text file called FilmOut.csv in the root user’s home folder.
8. Change the contents of the film query tab to read:
SELECT * FROM sakila.film
where description like '%database%';
9. Execute the current statement by pressing Ctrl + Enter.

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 11
10. Select the Tools > Utilities > Reformat SQL Query menu option. Note the changed
appearance of the SQL statement on the film query tab.
11. Select the Tools > Utilities > “Make keywords in query uppercase” menu option. Note the
changed appearance of the SQL statement in the film query tab.
12. Locate the Snippets tab.
Note: You may have to resize the film query pane to see the Snippet and Context Help tabs
Unauthorized reproduction or distribution prohibitedฺ Copyright© 2018, Oracle and/or its affiliatesฺ

properly.
13. On the Snippets tab, click the Add button, which has a star-shaped icon. This adds the
contents of the editor pane to the Snippets tab.
14. Close the main tab (with the same name as your connection) to return to the MySQL
Workbench home tab.
15. Double-click your connection to activate it.
16. On the Snippets tab, right-click the snippet and select “Execute snippet” from the context
menu. ble
fe r a
− The previous SQL statement that you saved as a snippet, executes without you having
ans
to retype it.
n - t r
17. Delete the entire SQL statement on the Query 1 tab.
a no
18. Activate the Context Help tab by clicking it.
h a s
ฺ b r) deฺ
19. Enter select on the Query 1 tab and use the cursor to highlight the word “select.” Note

c o m Gui
how MySQL Workbench provides context-sensitive help for the SELECT statement.

arฺ dent
20. Continue typing to create the following SQL statement:
select count(*) from actor; ep
s n Stu
oyou
21. Note how MySQL Workbench assists
c i @ thby isproviding valid options for statements and
22. Close the Connection t o ric use
database entities as you type.

tab.
b e r to Ctrl + Q.
(ro cens
23. Exit MySQL Workbench e
by pressing
c i li
R ic
berto
Ro

Copyright © 2016, Oracle and/or its affiliates. All rights reserved.

Appendix B: MySQL Workbench


Chapter 21 - Page 12

Vous aimerez peut-être aussi