Oracle SQL Notes - Bharath
Oracle SQL Notes - Bharath
Contents
Chapter 1: Introduction 8
1. Introduction 8
What is SQL 8
SQL Statements 8
SQL Working Tools 9
The HR schema 9
CHAPTER 2: Retrieve Data from Database Tables 11
1. Selecting Data Using Basic SELECT Statement 11
Basic SELECT statement 11
Expressions instead of column names 11
Use of column alias 12
BS
NULL values in columns 13
Use of text concatenation operator (||) 13
Use of DISTINCT keyword for removing duplicate column values 14
Use of DESCRIBE statement 14
Practice 2.1 15
LA
2. SELECT Statement with WHERE clause 15
Use of WHERE clause in SELECT Statement 15
Comparison operators in Oracle 16
Range condition using BETWEEN operator 17
Use of IN operator to match the column value against a set of values 17
Joining multiple conditions in WHERE clause 18
ML
Page 1
Chapter 3: Use of Oracle Single Row Functions 24
1. Character Functions 24
Case conversion functions 24
Character manipulation functions 25
Practice 3.1 26
2. Number functions 27
ROUND, TRUNC, and MOD functions 27
Practice 3.2 28
3. Date functions 28
Use of SYSDATE function 28
Date arithmetic 28
Date manipulation functions 29
Practice 3.3 30
4. Functions for manipulating NULL values 30
NVL function 30
Practice 3.4 31
5. Data Type Conversion Functions 31
Page 3
Chapter 7: Set operations 56
1. Performing Set Operations 56
Set operators 56
UNION and UNION ALL operators 57
INTERSECT operator 57
MINUS operator 58
Use of conversion functions in set operations 58
Practice 7.1 59
2. More Practice Problems 59
Chapter 8: Data Manipulation Language (DML) 60
DML Statements 60
1. Inserting Data into Table 60
INSERT statement 60
Inserting rows without column names unspecified 60
Inserting rows with NULL values for some columns 61
Inserting Date type values 61
Inserting rows from another table 62
Some Common Mistakes of INSERT statements 62
2. Changing Data in a Table 63
UPDATE Statement 63
Use of sub-query in UPDATE statement 63
Practice 8.2 64
3. Deleting Rows from a Table 64
DELETE Statement 64
Use of sub-query in the DELETE statement 65
4.
BSPractice 8.3
Database Transaction Controls Using COMMIT, ROLLBACK
Database Transactions
COMMIT statement
65
66
66
66
LA
ROLLBACK Statement 67
5. Practice Problems 67
Chapter 9: Data Definition Language (DDL) Statements 68
Page 4
DDL Statements 68
1. Creating Tables 68
ML
BSWhat is an Index
CREATE INDEX statement
When to create indexes?
4. More Practice Problems
81
81
82
82
LA
Page 5
Chapter 11: Introduction to PL/SQL 83
1. Anonymous PL/SQL blocks 83
General structure of Anonymous blocks 83
Execute an anonymous block 84
Use of variables in PL/SQL 84
ML
7.
BS
Problem Example 3
Page 6
Drop a trigger from database
More Practice Problems
110
111
111
LA
ML
Chapter 1: Introduction
1. Introduction
What is SQL
Structured Query Language (SQL) is the language used to interaction with a database management
system. The language defines the statements for retrieving data from the database, updating data in
the database, inserting data into the database, and more similar things.
SQL is the way by which all programs and users access data in an Oracle database. SQL
provides statements for a variety of tasks including:
●
BS Querying data
All SQL statements supported by Oracle database can be grouped in several categories as
illustrated in following table:
Page 8
SQL Working Tools
There are two primary tools that can be used for SQL. They are:
● SQL * PLUS – This is a command line tool and is the most popular tool
● SQL Developer – This is a graphical tool used by Oracle users to interact with Oracle database.
● Navicat – This is a third party tool that is used to connect to several databases such as
Oracle, MySQL, etc. This is one of the most popular GUI tools to interact with database.
The HR schema
The Human Resource (HR) schema is a part of Oracle sample database that can be installed with
Oracle. This course uses the tables in HR schema for all practice and homework sessions. The
schema contains the following tables:
● REGIONS – contain rows that represent a region such as America, Asia, and so on.
●BS COUNTRIES – contain rows for countries each of which is associated with a region
● EMPLOYEES – contain detail about each employee working for a department. Some
employees may not be assigned to any department.
● JOBS – contain the job types that can be held by each employee.
department within a job, or changes a job within a department, a new row is inserted in this
table with the earlier job information of the employee.
The following table shows the column names for all tables in HR schema.
Page 9
STATE_PROVINCE, COUNTRY_ID
BS
LA
ML
Page 10
CHAPTER 2: Retrieve Data from Database Tables
The SELECT statement is used to retrieve data from database tables. The very basic general form of
the SELECT statement is given below:
For example, the following SELECT statement retrieves some data from EMPLOYEES table.
BS
The above SELECT statement –
LA
● Will retrieve all rows from the EMPLOYEES table
If you want select values of all columns you can either specify all column names or specify a
‘*’ as follows:
ML
You can also use expressions instead of direct column names in the SELECT clause as shown below.
The query will multiply values of SALARY column by 12, and then will display the results.
Page 11
You can use arithmetic expressions involving addition, subtraction, multiplication, and division as
shown in following SELECT statements.
BS
You will notice that, when you execute the first SELECT query above with expressions instead of
column names, the displayed column header in the result is SALARY*12. These headers sometime
become misleading and unreadable. Using alias, i.e., naming the expression, will solve the problem.
You can give meaning names to expressions in this way. The following example illustrates this and
LA
gives the expression a name ANNSAL. The query results will be displayed with ANNSAL as the
column header.
ML
The column alias should be double quoted if it contains spaces as shown below:
● All SQL statements have a terminator, i.e., semicolon (;) at the end
● SQL Keywords are not case-sensitive, e.g., SELECT, Select, and select are all same.
Page 12
NULL values in columns
● NULL value is not same as zero value or some other specific value, it is simply unknown
Execute the following SELECT statement and search through the values of COMMISSION_PCT
column in the output. You will notice that there are many NULL, i.e., empty values there.
BS
The following example illustrate that when a column value is NULL, then arithmetic expression
also outputs NULL. You will notice that SALCOMM column in the output is null in those rows
where either SALARY value is NULL or COMMISSION_PCT value is NULL.
LA
Use of text concatenation operator (||)
The concatenation operation, || is used to join multiple text values. For example, the following query
ML
outputs employee’s first name and last name joined together and separated by a space. The output
column header is also given a new name FULLNAME. Although, the parenthesis is not necessary, it
improves readable of the statement.
You can also add additional texts with the column values as the following statement does.
Page 13
Note the use of single quotes in the above statement. The single quote is used to mean text values.
This is necessary and without the single quote, Oracle will think the text as a column name, which is
definitely wrong in this case. So, you must use single quote around text values (not around column
names).
However, no quote is used for numeric values, e.g., 350, and 7777.
BS
You will notice that, the output contains similar, i.e., duplicate values since several rows
(employees) have the same JOB_ID in the EMPLOYEES table. You can remove the duplicate
outputs by using the DISTINCT keyword as shown below.
LA
In the above SELECT, output will contain unique values of JOB_ID therefore removing duplicate
outputs. The DISTINCT Keyword works on all columns specified in the SELECT and outputs
ML
You can use the DESCRIBE statement to view the structure, i.e., column names and data types of
different columns of a table. The following example will output all column names, their data types,
and all constraints of the EMPLOYEES table.
Page 14
The basic data types used in Oracle are given in following table.
BS DATE
Practice 2.1
the number of characters
Used for storing date values
LA
a. Write an SQL query to retrieve all country
titles.
d. Write an SQL query to retrieve all city names. Remove duplicate outputs.
ML
The WHERE clause is used with one or more conditions to limit rows in the output. The general
syntax of the SELECT statement with WHERE clause is given below.
Page 15
For example, the following SELECT retrieves last names and salaries of those employees only
whose DEPARTMENT_ID column value is 80.
The following example shows conditions involving text and date values.
BS
LA
Note that use of single quotes around text data and date data (’01-JAN-1995’). The date text given in
ML
the query is in default format. Until, you learn TO_DATE conversion function in later chapters, you
will need to enter data values in this way in default format. Otherwise, Oracle may generate error
messages.
The condition in the above WHERE clause uses the equal (‘=’) operator to compare
DEPARTMENT_ID values. This is a comparison operator available in Oracle. The most commonly
used comparison operators are:
Operator Description
= Equal to
Page 16
> Greater than
>= Greater than or equal to
< Less than
<= Less than or equal to
<> Not equal to
BETWEEN value1 AND Between value1 and value2 (inclusive)
value
IN (value1, value2, …) Equal to value1 or value 2 or …
LIKE Pattern matching for text
IS NULL Is a NULL value
BS
You can check whether a value is in the given range by using the BETWEEN operator. The
following statements illustrate this.
LA
Use of IN operator to match the column value against a set of values
ML
The IN operator can be used to check whether a column value is equal to a set of values. The
following examples illustrate this.
Page 17
Joining multiple conditions in WHERE clause
You can join two or more conditions using AND, OR, and NOT operators. You may need to
use parenthesis to enforce operation execution order.
The following example shows the use of AND, OR and NOT operators.
BS
Three or more conditions can be joined. In such cases, parenthesis should be used to clarify the
LA
execution order and combination of the conditions.
ML
Note the difference in outputs of the above two statements. The use of parenthesis change the
order of execution of the operators, therefore changes meaning and output of the SELECT
statements.
Page 18
Pattern matching in texts using LIKE operator
The LIKE operator is used for pattern matching in texts. Suppose, you want to retrieve those
employee records whose last names contain the character, ‘s’. This type of condition is expressed
using LIKE operators and two special symbols (‘%’ and ‘_’). For example, the following statement
will retrieve all retrieve records of those employees whose last name column contain at least one
‘s’.
Note the use of special symbol (‘%’) above. The ‘%’ means zero or more characters. A ‘%’
before ‘s’ means zero or more characters can precede the ‘s’, a ‘%’ after ‘s’ means zero or more
characters can follow ‘s’. To understand the position of ‘%’ and resultant effect, observe the
BS
outputs of the following queries.
LA
ML
If you execute the above three statements and observe the output, you will note that-
● The first statement retrieves those rows where LAST_NAME starts with a ‘S’. Any
number of any characters can follow after the ‘S’. Note that text match is case-sensitive,
hence ‘S%’ and ‘s%’ are not same.
● The second statement retrieves those rows where LAST_NAME ends with ‘s’. Any
number of any characters can precede the ‘s’. Only the last character must be ‘s’.
● The third statement retrieves those rows where LAST_NAME is exactly ‘s’ (like the ‘=’
operator)
Page 19
Like the ‘%’ special symbol, the ‘_’ special symbol is used to match exactly one character. For
example, execute the following statements and observe the outputs.
●
BS
If you execute the above three statements and observe the output, you will note that-
The first statement retrieves those rows where LAST_NAME contains exactly two
characters where the first character must be ‘a’, e.g., ‘ab’, ‘ak’, and ‘ac’.
The second statement retrieves those rows where LAST_NAME contains exactly three
characters in which the last one must be ‘b’
LA
● The third statement retrieves those rows where LAST_NAME contains at least one character,
i.e., last name cannot be empty text
The above statement retrieves records of those employees whose COMMISSION_PCT value is less than
0.20. The query should retrieve those rows that have NULL values in COMMISSION_PCT column,
Page 20
because NULL should mean a 0 value in most cases. However, Oracle would not retrieve those
rows. This is because; comparison with NULL is regarded as FALSE (not matched). If you want
to retrieve records with NULL values also, then you have to use IS NULL comparison operator as
shown below.
A common mistake is using equality (=) operator to retrieve records with NULL values as shown
below. But, the query will retrieve no rows as the equality comparison fails due to NULL value.
BS
Practice 2.2
a. Select names of all employees who have joined before January 01, 1998.
b. Select all locations in the following countries: Canada, Germany, United Kingdom.
LA
c. Select first names of all employees who do not get any commission.
d. Select first names of employees whose last name starts with an 'a'.
e. Select first names of employees whose last name starts with an 's' and ends with an 'n'.
g. Select all names of employees whose job type is 'AD_PRES' and whose salary is at
least 23000.
h. Select names of all employees whose last name do not contain the character 's'.
i. Select names and COMMISSION_PCT of all employees whose commission is at most 0.30.
j. Select names of all employees who have joined after January 01, 1998.
k. Select names of all employees who have joined in the year 1998.
Page 21
3. Sorting Rows in the Output
ORDER BY Clause
You can use the ORDER BY clause with the SELECT statement to sort the rows in the results.
The general syntax is given below:
The ORDER BY clause is used after the WHERE clause to specify sorting order. The following
statement retrieves records of employees and sorts the output in descending order of SALARY values.
BS
LA
Outputs can be sorted based on multiple columns. So, if the first column is equal for multiple rows,
then the rows are sorted according to the second column. If the second column is also same, then
rows are sorted based on third column, and so on. The following statement illustrates such queries.
ML
You can use column alias in ordering results. The following examples illustrate this.
Page 22
Practice 2.3
a. Select names, salary, and commissions of all employees of job type 'AD_PRES'. Sort
the result in ascending order of commission and then descending order of salary.
In class.
BS
LA
ML
Page 23
Chapter 3: Use of Oracle Single Row Functions
1. Character Functions
The case conversion functions are used to convert case of text characters. The most commonly
used Oracle functions for this purpose are given below:
Function Description
LOWER (text) Converts the text to all lowercase. Here, text can be column name or an
expression.
UPPER (text) Converts the text to all uppercase. Here, text can be column name or an
expression.
BS INITCAP (text) Converts the first character of the text to uppercase. Here, text can be
column name or an expression.
The following table shows the outputs of applying case conversion functions on the text ‘hello
WORLD’.
LA
Function Output
LOWER(‘hello WORLD’) hello world
UPPER(‘hello WORLD’) HELLO WORLD
INITCAP(‘hello WORLD’) Hello world
ML
The following statement shows the use case-conversion functions in SELECT statements.
Note the use of three functions in the above statement. The column aliases are good ways to
redefine column headers.
Page 24
Case conversion functions are frequently used in WHERE clause to match specific texts. For
example, if you want to retrieve records of those departments which contain the text SALE in its
name, then you may write the following statement.
Any of the above two statements will retrieve the required records successfully. However, if no
functions were used, then the query may not retrieve all records due to case differences. For
examples, if there were two departments named as ‘Sales Office’ and ‘Whole sale’, then comparing
BS
without functions may not be able to retrieve both records simultaneously.
The most commonly used functions in this category are given below:
LA
Function Description
CONCAT (Column1, Column2) Concatenates, i.e., joins the texts of two columns.
SUBSTR(Column, m [, n]) Extracts n characters from the Column, starting from m-th
position. If n is omitted, the all characters from the starting
position are extracted.
INSTR(Column, ‘text’) Returns the numeric position of the ‘text’ in Column if found.
Otherwise, returns 0.
LPAD(Column, n, ‘text’) Returns a left-padded text of n characters, padded with ‘text’.
RPAD(Column, n, ‘text’) Returns a right-padded text of n characters, padded with ‘text’
TRIM(Column) Trims, i.e., removes whitespace characters from left and right.
REPLACE(Column,’text1’,’text2’) Searches for ‘text1’ in Column, and if found, replaces with
‘text2’.
Page 25
Function Output
CONCAT(‘Hello’, ‘ world’) Hello world
SUBSTR(‘Hello world’, 7) World
SUBSTR(‘Hello world’, 1, 5) Hello
INSTR(‘Hello world’, ‘world’) 7
LPAD(‘12345’, 10, ’*’) *****12345
RPAD(‘12345’, 10, ’*’) 12345*****
TRIM(‘ Hello world ‘) Hello world
REPLACE(‘Hesso worsd’, ‘s’, ‘l’) Hello world
The following statements show the use of the above functions in SELECT query.
BS
LA
The first query retrieves name and job id of all employees whose job id field contains the word
‘CLERK’. The second query outputs the abbreviation of all employee names. The third query prints
ML
Practice 3.1
a. Print the first three characters and last three characters of all country names. Print in
capital letters.
b. Print all employee full names (first name followed by a space then followed by last
name). All names should be printed in width of 60 characters and left padded with '*'
symbol for names less than 60 characters.
Page 26
c. Print all job titles that contain the text 'manager'.
2. Number functions
There are three number functions most commonly used in Oracle. They are given below.
Function Description
ROUND (Column, n) Rounds the value in Column up-to n decimal places after the
decimal point. If n is 0, then rounding occurs in the digit
before the decimal point.
TRUNC (Column, n) Truncates the value up-to n decimal places after the decimal
point. If n is 0, the truncation occurs up-to the digit before
the decimal point.
BS
The following table shows the results of applying numeric functions.
Function
ROUND(45.923, 2)
Output
45.92
LA
ROUND(45.926, 2) 45.93
ROUND(45.926, 0) 46
TRUNC(45.923, 2) 45.92
TRUNC(45.926, 2) 45.92
TRUNC(45.926, 0) 45
ML
MOD(23, 5) 3
Page 27
Practice 3.2
a. Print employee last name and number of days employed. Print the second
information rounded up to 2 decimal places.
b. Print employee last name and number of years employed. Print the second
information truncated up to 3 decimal place.
3. Date functions
BS
Use of SYSDATE function
The SYSDATE function returns the current database server date and time. You can use this
function as follows in SELECT query.
LA
Note the use of double quotes around “WEEKS EMPLOYED”. It is necessary as the aliasing text
contains spaces. The SYSDATE is used here to find the number of days an employee has worked,
ML
and then this number is divided by 7 to find the number of weeks, the employee passed in the
company.
Date arithmetic
You can use arithmetic operators to subtract dates, add some numeric value with dates, etc. In the
previous query, you subtracted SYSDATE from HIRE_DATE, and the result is the number of days
between these two dates. The following table explains the outcomes of different arithmetic operators
that can be applied on DATE type values.
Page 28
DATE + number DATE value. Adds the number of days with the
given DATE value.
DATE – number DATE value. Subtracts the number of days with from
the given DATE value.
DATE – DATE Outcome is a numeric value specifying the number of
days between these two dates.
DATE + DATE Invalid operation
Suppose the value of HIRE_DATE column for an employee is ‘05-FEB-1995’. Then, the following
table shows the use date arithmetic operations.
Operation Outcome
HIRE_DATE + 7 ’12-FEB-1995’ which will be a DATE type value
BSHIRE_DATE – 4
SYSDATE – HIRE_DATE
Function Outcome
MONTHS_BETWEEN(date1, date2) Number of months between date1 and date2.
ADD_MONTHS(date1, n) Adds n months with the date. Result is another
date after addition of the months.
ML
ROUND(date, ‘MONTH’) Rounds the date to the nearest month. This results
date corresponding to either 1st day of the next
month or 1st day of the same month.
ROUND(date, ‘YEAR’) Rounds the date to the nearest year. This results
date corresponding to either 1st day of the next
yearor 1st day of the same year.
TRUNC(date, ‘MONTH’) Truncates the date to the start of the month.
TRUNC(date, ‘YEAR’) Truncates the date to the start of the year.
Page 29
If we assume SYSDATE = ’20-MAR-14’ then the following table illustrates some outputs of the
date functions.
Expression Outcome
ADD_MONTHS(SYSDATE, 5) 20-AUG-14
ROUND(SYSDATE, ‘MONTH’) 01-APR-14
ROUND(date, ‘YEAR’) 01-MAR-14
TRUNC(date, ‘MONTH’) 01-JAN-14
TRUNC(date, ‘YEAR’) 01-JAN-14
BS
Practice 3.3
a. For all employees, find the number of years employed. Print first names and number of
years employed for each employee.
LA
b. Suppose you need to find the number of days each employee worked during the first
month of his joining. Write an SQL query to find this information for all employees.
NVL function
ML
The NVL function works on a column and outputs a specific value whenever the column value is
NULL. The general syntax of this function is given below:
If expr1 evaluated to NULL, the NVL function outputs expr2, otherwise, output is expr1.
Page 30
The NVL function can also be used in where to check if a column contains NULL value. For example,
the following statement selects all employee records, whose COMMISSION_PCT value is NULL. We
assume that, usually COMMISSION_PCT value is not negative.
A better use of the NVL function is shown below where total annual salary is calculated for all
employees. Without the NVL function, the expression SALARY*12 +
BS
SALARY*12*COMMMISSION_PCT would result in NULL whenever COMMISSION_PCT is
NULL.
LA
Practice 3.4
a. Print the commission_pct values of all employees whose commission is at least 20%.
Use NVL function.
ML
b. Print the total salary of an employee for 5 years and 6 months period. Print all employee
last names along with this salary information. Use NVL function assuming that salary
may contain NULL values.
Page 31
● Convert a NUMBER value to VARCHAR2 value if used in text operations
such as concatenation.
● Convert a DATE value to VARCHAR2 value (in default date format). This conversion is
applied in most operations like comparison, concatenation, etc.
● Convert a VARCHAR2 value to a date value provided that VARCHAR2 text is in a default
date format. Otherwise, automatic conversion fails. The default date format in Oracle is
‘DD-MON- YY’ or ‘DD-MON-YYYY’.
Operation Description
BS
MOD(‘25’, 3)
ADD_MONTHS(’31-JAN-2011’, 5)
Works fine. Although, ‘25’ is a text, Oracle
automatically convert the text to a number
before applying the MOD
Works fine. Converts the text ’01-JAN-2011’
automatically to a DATE value, then adds 5
LA
months. Result will be ’30-JUN-2011’
ADD_MONTHS(’JAN/31/2011’, 5) Fails! The text is not in default format, so Oracle
cannot automatically convert the text to DATE
before ADD_MONTHS works.
Page 32
So, whenever, default conversion does not work, we need to use manual conversion functions.
The TO_CHAR function is used to convert DATE value to VARCHAR2 value. The general syntax of
the function is given below:
The format string specifies how to convert the DATE value to VARCHAR2 value. The following
table illustrates the format texts that are most commonly applied to DATE value. Assume that, the
value of HIRE_DATE is ’31-JAN-1995’.
BS
TO_CHAR(HIRE_DATE, ‘MONTH DD, YYYY’)
TO_CHAR(HIRE_DATE, ‘MONTH DD, YEAR’)
The last example in above table shows that, TO_CHAR function can applied to numeric values also.
The TO_NUMBER function converts any text of VARCHAR2 to a numeric value. This is very much
essential when computing arithmetical operations on two or more columns where all columns were
defined of type VARCHAR2. In such cases, we must explicitly convert them to number before
operation.
Consider the following query that retrieves all locations in ascending order of POSTAL_CODE.
Page 33
However, the above query may not give correct ordering because POSTAL_CODE column is of
type VARCHAR2. So, Oracle will do the ordering lexicographically (‘1000’ will come before
‘999’). To do numerical order, you can use the following query instead.
The TO_DATE function converts VARCHAR2 type text strings to DATE type value. The general
syntax of the function expression is given below.
BS
The following table illustrates the use of TO_DATE function with examples.
Expression
TO_DATE(‘DEC 31 1995’, ‘MON DD YYYY’)
TO_DATE(‘31/12/1995’, ‘DD/MM/YYYY’)
Output (a DATE type value)
Works fine.
Works fine.
LA
TO_DATE(‘1995-12-31’, ‘YYY-MM-DD’) Works fine.
TO_DATE(‘1995-12-31’, ‘YYY-DD-MM’) Fails! Format does not match with
the given text.
You are always encouraged to use explicit date conversions in comparison operations. Otherwise,
ML
you query may bring unexpected results. For example, the following query finds all employee last
names who was hired before 1st January 1997.
Page 34
Practice 3.5
In class.
BS
LA
ML
Page 35
Chapter 4: Aggregate Functions
Group functions
In previous chapter, we have studied single-row functions. Those functions operates on one single row
and outputs something based on the input columns of the row. The group functions operate on a group
of rows and outputs a value such as total, average, etc. These functions report only summary
information per group, rather than per row.
The group functions result in only one row per group of rows in the output. The most commonly
used group functions are given below.
BS
Function
SUM (Column)
MAX(Column)
MIN(Column)
Description
Finds the total, i.e., summation of values in Column for all rows
in the group
Finds the maximum value in Column for all rows in the group
Finds the minimum value in Column for all rows in the group
LA
AVG(Column) Finds the average value in Column for all rows in the group
COUNT(Column) Count the number of non-NULL values in Column for all rows
in the group
The group functions given above discard NULL values during their computation.
ML
The group functions are used in the SELECT statement to retrieve information by groups. The groups
are identified by GROUP BY clause. The general syntax is given below. These queries are called
GROUP BY queries and are very important to database for generating various types of reports.
Page 36
In the above statement, Oracle will first create several groups based on <Column1, Column2,…>.
Every unique combination of these columns will denote a group and all rows in the table that have
these combinations of values will be in the group. Note that, only the columns in the GROUP BY
clause can be selected along with group function expressions.
For example, suppose, you want to create a report showing the total salary paid by the company to
each departments. This requires a GROUP BY query and group function as shown below.
For another example, suppose, you want to know the maximum salary, minimum salary and
average salary the company pays in different job types. The following GROUP BY query will
retrieve the required information.
BS
LA
Note that, you cannot select a column that is not present in GROUP BY clause. For example,
the following query would return an error.
ML
For the third example, suppose you want to know the number of employees working in each
department. As you may recall, this requires creating a group based on DEPARTMENT_ID column,
then count the number of rows in each group, and then output the information. So, you may think,
the following query will output the information.
Page 37
In the above statement, counting the LAST_NAME column is similar to counting any other
columns. However, COUNT(LAST_NAME) will ignore the NULL values in LAST_NAME field,
therefore not counting rows that contain NULL values in LAST_NAME field. The correct query
should be the following.
In the above, COUNT(*) counts number of rows (NULL and non-NULL) and therefore will give
the correct result.
You can omit the GROUP BY clause in group function query. In such cases, the entire table will
BS
form a single group, and summary information will be calculated for whole table as one group only.
The following statements find the maximum, minimum, and average salary for the entire table,
i.e., all employees of the company. The second statement finds the number of rows in
EMPLOYEE table.
LA
ML
In a GROUP BY statement, the WHERE clause can be used for filtering rows before grouping is
applied. The general syntax of such statements is given below.
Page 38
The following statement finds the maximum and minimum salary for each job types for only
the employees working in the department no. 80.
In a GROUP BY statement, ORDER BY clause can be used to sort the final group results
based on grouping column. The following example sorts the final results based on JOB_ID
value.
BS
LA
Practice 4.1
a. For all managers, find the number of employees he/she manages. Print the
MANAGER_ID and total number of such employees.
b. For all departments, find the number of employees who get more than 30k salary. Print
the DEPARTMENT_ID and total number of such employees.
ML
c. Find the minimum, maximum, and average salary of all departments except
DEPARTMENT_ID 80. Print DEPARTMENT_ID, minimum, maximum, and average
salary. Sort the results in descending order of average salary first, then maximum salary,
then minimum salary. Use column alias to rename column names in output for better
display.
Page 39
2. DISTINCT and HAVING in GROUP BY queries
You can use DISTINCT keyword inside the group functions as given below. In this case, group
functions consider only unique rows, and discards duplicate values. So, duplicate value is counted
only once for calculation.
BS
Note that, the use of DISTINCT does not change the result of MAX and MIN group function But, it
does change the outcomes of SUM, and COUNT functions.
You can use the HAVING clause to remove some group information from the final results. Suppose,
LA
you want to retrieve the maximum and minimum salaries of each department except the department
no. 80.
The following GROUP BY statement will retrieve the required information. The information for
group no. 80 are removed using a HAVING clause. HAVING works like WHERE except that
HAVING works on groups.
ML
Note that, the HAVING condition is applied after group information is calculated unlike
WHERE condition is applied before grouping.
Page 40
The first statement above outputs maximum and minimum salary for each job types. However, only
those results are printed where group maximum is greater than 5000. The second query retrieves
average salary of each job type. This time, only those group results are printed for which average
salary is less than or equal to 5000. Results are sorted in descending order of average salary.
BS
Practice 4.2
a. Find for each department, the average salary of the department. Print only
those DEPARTMENT_ID and average salary whose average salary is at
LA
most 50k.
You can use expressions in group by clause. Expressions help you to retrieve more complex
ML
The following query finds the total employees hired in each year.
The following query finds the total number of employees whose name starts with the same character.
The query reports the first character and total employees.
Page 41
More than one column in GROUP BY clause
Sometimes you will need to use multiple columns in group by. For example, the following query finds
the number of employees for each department and for each job type. One column would not be
sufficient to find this group information.
BS
An important reason for adding more than one column in a GROUP BY clause is to select more
columns. Consider the following query that finds the number of employees for each job type.
LA
Now, if we want to print job titles along with job id in the above query, we has to put the job title
column in the GROUP BY clause, because Oracle does not allow to select columns in the SELECT
clause that are not present in the GROUP BY clause.
ML
Practice 4.3
a. Find number of employees in each salary group. Salary groups are considered as
follows. Group 1: 0k to <5K, 5k to <10k, 10k to <15k, and so on.
Page 42
b. Find the number of employees that were hired in each year in each job type. Print year,
job id, and total employees hired.
In class.
BS
LA
ML
Page 43
Chapter 5: Query Multiple Tables – Joins
All queries used in previous chapters fetched data from one table only. Sometimes, we need to
retrieve data from multiple tables. For example, suppose you want to create a report containing last
names of employee, salary, and name of the department employee works in. The first two fields are
available in EMPLOYEES table (LAST_NAME and SALARY column). But, the third field is
available in DEPARTMENTS table. To know in which department an employee works, we need to
join rows from EMPLOYEES table with rows from DEPARTMENT table based on the
DEPARTMENT_ID field. This type of joins is done by join queries.
BS
By join operation, rows of two or more tables are joined together to form larger rows. The rows of
different tables are joined together based on some columns that may be present in both tables.
Rows from two tables can be joined together by USING clause. The general syntax of this query is
LA
given below.
ML
The following example statement joins EMPLOYEES and DEPARTENT tables based on the
values of DEPARTMENT_ID column. A row from EMPLOYEES table is joined with a row from
DEPARTMENTS table where both rows have the same DEPARTMENT_ID value.
Page 44
Note the use of table aliases in the above statement. The table aliases are used in SELECT clause to
choose columns from the tables. However, you cannot alias the column, i.e., DEPARTMENT_ID
which is used in the USING clause. Otherwise, Oracle will generate error message. The following
query clarifies this by not aliasing the DEPARTMENT_ID column in the SELECT clause.
Two tables can be joined using the ON clause which is more general than USING. The ON clause
specifies an explicit condition on which rows will be joined together. In case of USING, rows are
joined based on same values (an equality condition) in join column. But, in case of ON clause, the
condition can be specified explicitly allowing equality and non-equality conditions for join.
BS
The following statement shows the same join as before but using ON clause.
LA
The more general nature of the ON clause will be clear if you observer the following statements.
A table can be joined with itself using ON clause which is called self-join. This is very useful in
many cases. Suppose you want to know the last name of manager for each employee. Each row in the
ML
EMPLOYEES table has a MANAGER_ID column which is actually an EMPLOYEE_ID of the same
table since the manager is also an employee. To retrieve the last name of the manager for each
employee, we need to join two copies of EMPLOYEES table based on MANAGER_ID field.
Page 45
Joins using non-quality condition
Tables can be joined by non-equality condition by ON clause. The following statement shows such a
join operation. Assume that there is table named JOB_GRADES that has LOWEST_SAL,
HIGHEST_SAL, and GRADE_LEVEL columns. We want to retrieve an employee’s grade based on
his salary. In this case, we need to join EMPLOYEES table with JOB_GRADES table. However, a
row from the EMPLOYEES table should join with that row from the JOB_GRADES table whose
LOWEST_SAL and HIGHEST_SAL contains the SALARY value of the employee.
Self-join allows many interesting queries. Suppose you want to create a report showing last name of
an employee and a number which is the number of employees getting higher salary than the
BS
employee. This type of results can be calculated using joins and groupings. The following statement
computes this.
LA
Observe that in the above query, the E1.LAST_NAME column was not required to be put in the
GROUP BY clause unless it was selected in SELECT clause.
ML
Three or more tables can also be joined using ON clause. The following statement shows such a
query that joins three tables.
Page 46
Oracle left outer join and right outer join
The general JOIN operation keeps rows that are found matched in both tables based on join
condition. In some cases, we need to keep the rows of first table (or second table or both) in the
output that does not meet join criteria. The normal JOIN operation would not keep such rows. In
such cases, we need to use LEFT OUTER JOIN and RIGHT OUTER JOIN syntax.
The LEFT OUTER JOIN keeps rows of the left table that did not have any match with rows of right
table based on join criteria.
The RIGHT OUTER JOIN keeps rows of the right table that did not have any match with rows of the
left table based on join criteria.
The application of such syntax is illustrated in the following query. The query finds the number of
BS
employees managed by each employee. If an employee does not mange anyone, then the output
displays 0.
LA
If you replace COUNT(E2.EMPLOYEE_ID) by COUNT(*) in the above query, then the query would
not output correct results! Find the reason yourself! Morever, E1.LAST_NAME does not any effect
on grouping. It was included in the grouping clause so that it can be selected in the output.
ML
Practice 5.1
a. For each employee print last name, salary, and job title.
b. For each department, print department name and country name it is situated in.
c. For each country, finds total number of departments situated in the country.
d. For each employee, finds the number of job switches of the employee.
e. For each department and job types, find the total number of employees working.
Print department names, job titles, and total employees working.
Page 47
f. For each employee, finds the total number of employees those were hired before
him/her. Print employee last name and total employees.
g. For each employee, finds the total number of employees those were hired before him/her
and those were hired after him/her. Print employee last name, total employees hired
before him, and total employees hired after him.
h. Find the employees having salaries greater than at least three other employees
i. For each employee, find his rank, i.e., position with respect to salary. The highest salaried
employee should get rank 1 and lowest salaried employee should get the last rank.
Employees with same salary should get same rank value. Print employee last names and
his/he rank.
j. Finds the names of employees and their salaries for the top three highest salaried
employees. The number of employees in your output should be more than three if there
are employees with same salary.
BS
LA
ML
Page 48
Chapter 6: Query Multiple Tables – Sub-query
What is a sub-query
A sub-query is a SELECT statement which is used inside another SELECT statement. The sub-query
can be place in FROM clause, WHERE clause, HAVING clause, etc. The use of sub-query in the
WHERE clause makes SELECT statements easier and powerful for retrieving information.
There are special comparison operators when sub-queries are used in WHERE clause. They are
ANY, ALL. The general syntax of sub-query in a WHERE clause is given below.
BS
The sub-query executes before the main query and results of sub-query are used in main query.
Sub-query can result in one row or multiple rows. In the above statement, sub-query is first executed,
and SALARY value of Abel is retrieved. Then, this value is used in the main query.
Page 49
The following is another example where the main query retrieves information of those employees
whose JOB_ID is same as the employee numbered 141.
The following statement shows the use of multiple sub-queries in single statement. The
BS
statement retrieves records of those employees whose JOB_ID is same as employee numbered
114 and whose SALARY is greater than Abel’s SALARY.
LA
ML
Suppose you want to retrieve the name of the employee who gets highest salary among all
employees. The following statement retrieves the information using sub-query.
Page 50
Sub-query returns more than one row
In case sub-query returns more than one row, usual comparison operators must be used with ANY or
ALL keyword. Their meanings are
● ANY – If used with comparison operation, the outcome will be true if operator evaluates to
true for any of the sub-query values
BS ALL – if used with comparison operator, the outcome will be true only if operator
evaluates to true for all values returned by the sub-query
To understand the use of ANY and ALL, examine the following statement. The query retrieves
those employee records (working in other than ‘IT_PROG’ department) whose SALARY is less
than at least one employee of ‘IT_PROG’.
LA
ML
In the query below, ALL is used instead of ANY. This query retrieves those employee records
whose SALARY is less than all employees of ‘IT_PROG’.
Page 51
Practice 6.1
a. Find the last names of all employees that work in the SALES department.
b. Find the last names and salaries of those employees who get higher salary than at least
one employee of SALES department.
c. Find the last names and salaries of those employees whose salary is higher than all
employees of SALES department.
BS d. Find the last names and salaries of those employees whose salary is within ± 5k
of the average salary of SALES department.
2. Advanced Sub-query
LA
Correlated Sub-query
In a correlated sub-query, we use row references of the main query to in the sub-query. Suppose, you
need to retrieve those employees whose salary is higher than at least three other employees. To write
this query using sub-query, we need to do the following:
ML
In the above query, the sub-query in the WHERE clause retrieve those rows form EMPLOYEES
table who earn less salary than the salary of the current employee. The current is determined by the
execution
Page 52
of this query by Oracle. Oracle retrieves all records of the main query first. Then for each row (say X)
of this main query (outer query), Oracle executes the sub-query by setting E1.SAL value to the salary
value of row X. Then sub-query results are retrieved, conditions are evaluated, and then X goes to
final output if condition becomes true. If main query returns 𝑁 rows, then the inner sub-query will be
executed 𝑁 times.
The EXISTS operator checks whether any row is found. A sub-query is used as an operand of
EXISTS operation. The operator would then return true if some rows were retrieved by the
sub-query. Otherwise, it would return false.
The following query illustrate the behavior of EXISTS operator. The query retrieves those
departments which have at least one employee having JOB_ID as ‘IT_PROG’.
BS
LA
The following query uses NOT EXISTS to find those employees whose earns the maximum
salary in his/her department.
ML
Page 53
Sub-query in SELECT Clause
You can use sub-query in SELECT Clause. For example, you could have re-written the previous
query by writing a sub-query in the SELECT clause to display names of departments instead of
department id. The following query shows that.
BS
Sub-query in FROM clause
We can also sue sub-query in FROM clause. If a sub-query is placed in a FROM clause, the
sub-query results will form a temporary table. The rest of the query will work the same as before
LA
such as join, grouping, etc.
To illustrate this, suppose we need to show the last name and salary of each employee along with the
minimum salary and maximum salary of his/her department. This query can easily be solved using a
self- join as shown below.
ML
The above query can be solve by placing a sub-query in the FROM clause as shown below.
Page 54
The sub-query in the FROM clause above creates temporary table whose schema is D(DEPT, MINSAL,
MAXSAL). Then Oracle joins E with D and rest of the query executes as usual.
Practice 6.2
a. Find those employees whose salary is higher than at least three other employees. Print
last names and salary of each employee. You cannot use join in the main query. Use
BS sub-query in WHERE clause only. You can use join in the sub-queries.
b. Find those departments whose average salary is greater than the minimum salary of all
other departments. Print department names. Use sub-query. You can use join in the
sub-queries.
c. Find those department names which have the highest number of employees in service.
LA
Print department names. Use sub-query. You can use join in the sub-queries.
d. Find those employees who worked in more than one department in the company. Print
employee last names. You cannot use join in the main query. Use sub-query. You can use
join in the sub-queries.
e. For each employee, find the minimum and maximum salary of his/her department.
ML
Print employee last name, minimum salary, and maximum salary. Do not use
sub-query in WHERE clause. Use sub-query in FROM clause.
f. For each job type, find the employee who gets the highest salary. Print job title and last
name of the employee. Assume that there is one and only one such employee for every
job type.
Page 55
Chapter 7: Set operations
Set operators
●
BS
The following must be met for the sub-query to be successful-
Page 56
UNION and UNION ALL operators
The following statement shows the use of UNION operator. The query does not keep duplicate values.
The UNION ALL operator combines results of two queries and keeps duplicate values.
BS
LA
INTERSECT operator
The intersect operator performs the set intersection. Rows that are common in both queries are
retrieved in the output. The following statement finds the employees whose current job title is same
as one of their previous job titles.
ML
Page 57
MINUS operator
The MINUS operator performs set minus operation. Rows of first query that are not in the second
query will be retrieved for output. The following query finds the employees who have not changed
their jobs even once.
BS
In case of set operators, it is mandatory that data types of the columns in both queries must match. In
that case, we may need to use type conversion functions to explicitly match data types. For example,
assume, there is an EMPLOYEES2 table in which JOB_ID was defined as a numeric value. Now, if
you want to find the employee records (LAST_NAME, JOB_ID, SALARY of both tables
(EMPLOYEES and EMPLOYEEES2), you may issue the following statement.
LA
ML
But, the above statement would generate an error message as the JOB_ID fields of the two tables
have different data types. So, in order to match the data types explicitly, you will require
converting the data type of the second query to VARCHAR2 as follows.
Page 58
Practice 7.1
a. Find EMPLOYEE_ID of those employees who are not managers. Use minus
operator to perform this.
b. Find last names of those employees who are not managers. Use minus operator to
perform this.
BS
In class.
LA
ML
Page 59
Chapter 8: Data Manipulation Language (DML)
DML Statements
INSERT statement
BS
The INSERT statement is used to insert new row in a table. INSERT statement allows you to insert
one or more rows to the table. The general syntax of the INSERT statement is given below:
LA
For example, the following statement inserts a new row in the DEPARTMENTS table.
You can insert values in a table without column names unspecified in the insert statement.
However, in this case, you have to ensure the following:
● Values are given in the default order of the columns as defined in the table creation
statements. For example, the following statement would successfully insert a row in the
DEPARTMENTS table.
Page 60
However, the following insert statement would not work and will generate an Oracle error message.
The reason is that, the DEPARTMENTS table has four columns, but in the statement only values are
specified for two columns only.
The following insert statement will also fail. Even though, all values are specified, they are not in
correct order as defined in the original table definition.
You can insert rows in a table with NULL values in some columns. In this case, you have to specify
BS
the column names of the table explicitly as shown in the following query.
LA
In the above INSERT statement, rows will successfully be inserted. Since, values for MANAGER_ID
and LOCATION_ID columns were not specified; they will be filled with NULL. Note that, this will
work only if these columns satisfy the following conditions:
If the column is of DATE type, then you may use the TO_DATE conversion function to convert a
text to DATE type value. The following examples show such a conversion to insert a new employee
in the EMPLOYEES table.
Page 61
However, if you specify the text in default date format, i.e, ‘DD-MON-YYYY’, then TO_DATE
function is not required as shown in the following statement. Oracle will automatically convert the
text to DATE type value. However, it is a good practice to always use the TO_DATE function to
explicitly convert to DATE values.
You can insert several rows from a table directly into another table. The following statement copies
all rows from EMPLOYEES table into another table named EMPLOYEES2. Note that, VALUES
keyword is not required in the statement.
BS
You can also use sub-query and where condition to copy some specific rows as shown in the
following statement.
LA
ML
The oracle server automatically enforces all data types, data ranges, and data integrity
constraints. Common errors that may occur during INSERT statements are following:
Page 62
2. Changing Data in a Table
UPDATE Statement
The UPDATE statement is used to change data in a table. The general syntax of the UPDATE
statement is given below. The statement can be used to change data in one or more columns. The
WHERE clause can be used to change data for some particular rows and is optional.
BS
To change the DEPARTMENT_ID of all employees, i.e., all rows in the table, omit the WHERE
clause as shown below:
LA
You can update multiple column values as shown below.
ML
You can use a sub-query in the UPDATE statement to fetch date from other tables. For example,
the following statement updates job and salary of employee numbered 113 to match those of
employee number 205.
Page 63
Practice 8.2
b. Update salary of all employees to the maximum salary of the department in which
he/she works.
BS d. Update the hiring dates of all employees to the first day of the same year. Do not change
this for those employees who joined on or after year 2000.
The DELETE statement is used to remove rows from a table. The general syntax of the DELETE
statement is given below. The WHERE condition is required to delete only some specified values. If
the WHERE condition is omitted, then all rows are deleted from the table.
ML
The following statement removes the Finance department row from the DEPARTMENTS table.
Actually, it will not remove any row due to violation of constraints!
Page 64
The following statement removes two rows from the DEPARTMENT table. Actually, it will not
remove any row due to violation of constraints!
Note that, the following statement will remove all rows from the DEPARTMENTS table as there
is no WHERE condition. Actually, it will not remove any row due to violation of constraints!
You can use sub-query to delete rows from a table based on information from another table. The
BS
following statement removes all employees from the EMPLOYEES table who are working in the
Finance department. Actually, it will not remove any row due to violation of constraints!
LA
Note that use of UPPER function in the above query. The UPPER function ensures that, the
statement will work even in department names are stored in lower case or upper case letters.
ML
Practice 8.3
c. Delete those employees from the EMPLOYEES table who joined before the year 1997.
Page 65
4. Database Transaction Controls Using COMMIT, ROLLBACK
Database Transactions
A transaction means one or more SQL statements which together make a unit of work. All SQL
statements should successfully execute or fail together. In Oracle database, a transaction is
automatically started with the first DML statement use executes. The already-started transactions will
end whenever one of the following events occurs:
BS (automatic ROLLBACK).
After one transaction ends, another transaction will start with the execution of next DML statement.
COMMIT statement
The COMMIT statement saves results of DML operations of the current transaction
LA
permanently in database. It also ends the ongoing transaction.
The following statements show the use of COMMIT to store data permanently to database. One
row is deleted from the EMPLOYEES table and a row is added to the DEPARTMENTS table.
Finally, COMMIT saves this changed permanently into database.
ML
Page 66
ROLLBACK Statement
The ROLLBACK statement undoes the results of all DML operations executed in the current
transaction. It also ends the current transaction. The state of the tables will be restored in the previous
values before the current transaction started.
The following statements when executed will not store the new row in the DEPARTMENTS table
and will not remove the row from the EMPLOYEES table. The ROLLBACK statement will undo
all the changes done by the DELETE and INSERT statements.
BS
5. Practice Problems
In class.
LA
ML
Page 67
Chapter 9: Data Definition Language (DDL) Statements
DDL Statements
1. Creating Tables
BS
The CREATE TABLE statement is used to create new tables in database. The general syntax of
the statement is given below:
LA
For example, the following example creates a new table in the database:
ML
The above statement will create a table named PERSON in database. The table PERSON will have
three columns which are:
Page 68
● NAME – Data type if VARCHAR2, maximum length 50 characters
Naming rules
● Must not duplicate the name of another object of the same user
BS
DEFAULT option in CREATE TABLE
You can specify a DEFAULT option in column definition to specify default value for the column as
given below:
LA
ML
The PERSON table created above will have a default value, i.e., SYSDATE for the BDATE column.
So, if user does not specify any value for this parameter, then the default value will be used for the
column. For example, the following INSERT statement does not specify value for the BDATE
column. The value of SYSDATE will be used by default for the BDATE column.
Page 69
Data Types of Columns
When you are creating tables, you have to specify data type for the columns. The following
commonly used data types are available in Oracle:
BS CLOB
BLOB
Used to store variable length text data (Up-to 4GB)
Used to store binary data (Up-to 4GB)
For example, the following statement creates a table DEPT80 with a sub-query.
Page 70
The DEPT80 table created above –
● The data types of the three columns are inherited from the EMPLOYEES table. So, the data
types of the three columns reflect the same as in the EMPLOYEES table.
● The newly created table will inherit all constraints that are defined on the
EMPLOYEE_ID, LAST_NAME columns in the EMPLOYEE table.
● The newly created table will contain all data rows of employees whose
DEPARTMENT_ID column value is 80.
● Note that, the column alias ANNSAL for the expression SALARY*12 is necessary
here. Otherwise, Oracle will generate an error message.
BS
Constraints
Constraints are used in table definitions to specify rules so that invalid data is not entered in
database. Usually, constraints do the following:
● Enforce rules on the data. Whenever, a row is inserted, updated, or deleted, these rules
LA
are checked against the data. Constraints must be satisfied for the operation to be
successful.
● Constraints prevent the deletion of important rows from a table, which may have
dependencies in other tables
Constraint Description
ML
NOT NULL Specify that the column can not contain NULL values
PRIMARY KEY This constraint is used for a column that uniquely identifies each
row of a table. Column values must be unique and cannot be NULL.
So, this is equivalent to NOT NULL and UNIQUE constraints
together.
Page 71
one table must have similar values in a column of another table.
CHECK This specifies a condition which must be true for all rows.
Defining constraints
Constraints can be defined in column-level and table-level. The general syntax of column-level
constraint definition is as follows:
BS
The general syntax of table-level constraint definition is given below:
LA
ML
Page 72
● Creates PERSON table with two column-level constraints
● NID column is the PRIMARY KEY of the table. So, NID will uniquely specify each row of
the table. Moreover, NID cannot be NULL for any row inserted in the table.
● The PRIMARY KEY constraint of NID column has been given a name, i.e., PERSON_PK
● NAME column cannot have NULL values. This constraint is not given any name.
The following statement creates the same constraints, but this time, constraints are defined in
table-level with no difference.
BS
In some cases, two columns together may uniquely identify each row of a table. So, PRIMARY
KEY is composed of two column values rather than a single column. This type of constraints
LA
cannot be defined using column-level constraints. They must be defined using table-level
constraints as shown below:
ML
In the above PERSON table, the PRIMARY KEY is composed of two columns, COUNTRYID,
and PERSONID.
Page 73
FOREIGN KEY constraint
A FOREIGN KEY constraint establishes a relationship between columns in one table with another
column (which is a PRIMARKY KEY) of another table. Consider the PERSON table created
below:
BS
Now, consider the following ADDRESS table, which stores the address of each person. This person
must be a valid row of the PERSON table.
LA
ML
The PID column in the PERSON_ADDRESS table is defined as the PRIMARY KEY of the table.
Moreover, this column is also specified as a FOREIGN KEY constraint which is linked (by
REFERENCES Keyword) to NID column of PERSON table. This link will ensure that if a value is
inserted in the PID column of PERSON_ADDRESS table, the same value must also be present in the
NID column of a row in the PERSON table. Otherwise, the insertion will fail. The PERSON table
will be called parent table and PERSON_ADDRESS table will be called a child table.
The FOREIGN KEY constraints create a problem during deletion of rows from the parent table. If a
row is to be deleted from the parent table, but the child table have some rows which are dependent
(because of
Page 74
the FOREIGN KEY constraint) on that row, then Oracle will not allow deletion of the row. All
dependent rows in the child table must be deleted manually before the deletion of a row in the parent
table.
However, there are two solutions available in Oracle. The FOREIGN KEY constraints can have
following optional keywords at the end of the constraint definition –
● ON DELETE CASCADE – When a row is deleted from the parent table, the dependent
rows are also deleted from the child table automatically by Oracle.
● ON DELETE SET NULL – When a row is deleted from the parent table, the dependent
rows are set to NULL values in the child table automatically by Oracle.
CHECK constraints
The CHECK constraints define one or more conditions that must be satisfied by the column values
of a row. These constraints can be defined as column-level or table-level. The general syntax of the
BS
CHECK constraint is given below:
LA
For example, the following table definition contains a CHECK constraint in column-level which
ensure that, the SALARY value cannot be negative.
ML
● Is defined in column-level
Page 75
3. Deleting Tables from Database
The DROP table statement is used for removing tables from database. The general syntax of the
statement is given below:
For example, the following statement removes the EMPLOYEES2 table from the database.
Note that, the table structure is deleted and all rows are deleted. But, the space used by the table is
BS
not released. To release the storage used by the table, you need to specify PURGE option at the
end of the DROP TABLE statements as shown below:
LA
4. Add or Remove Table Columns
You can add new column to an existing table using the ALTER TABLE SQL command. For
example, suppose we want to add a new column BDATE to our EMPLOYEES table whose type
will be of date. The following command will add the column.
ML
To delete a column from a table, use the ALTER TABLE DROP command like below.
In class.
Page 76
Chapter 10: Creating Views, Sequences, and Indexes
Database objects
The database contains different kinds of objects, among which most common are:
● Views – stores sub set of data from tables, created with CREATE VIEW statement.
1. Creating Views
What is a View
●
BS
A view –
Contains no data of its own, and contain no data at the physical level.
LA
● When user executes query on the view, the view sub-query gets executed and view data
are fetched dynamically
A view is created by the CREATE VIEW statement. The general syntax of the statement is given below:
ML
Page 77
The above created view DEPTV80 –
● The view does not contain any physical records at the time of creation.
● The sub-query is not executed. It will be executed later when view data are required by
another query on the view.
● OR REPLACE clause is optional and if it is specified, then the view is created even
though a view with the same name already exists. The old view is deleted.
● The column alias ANNSAL is necessary here, otherwise Oracle will generate an error
message. You can issue SQL SELECT statements on the created view to retrieve data as follows:
BS
The following shows another example of CREATE VIEW statement.
LA
The above created view –
ML
● The column aliases in the sub-query are necessary; otherwise Oracle will generate
error messages.
● Since, the view sub-query contains JOIN and GROUP BY clause, DEPT_SUMMARY will
be a complex view. In complex view, no DML operations are allowed unlike the simple
views where DML operations are allowed.
Page 78
Advantages of view over tables
There are some advantages of creating views over tables which are –
● Views give different view of the same table to different users of the database.
● Views do not contain any record of its own which saves a lot of space of the database
than copying a table multiple times.
You can remove views from the database by DROP VIEW statement. The following example
removes the DEPTV80 view from the database. Note that, no data is deleted from database since
view does not contain any physical data.
BS
2. Creating Sequences
LA
What is a Sequence
A sequence is a database objects that create numeric (integer) values. The sequence is usually
used to create values for a table column, e.g., PID column in the PERSON table defined in
previous chapters.
To create a sequence CREATE SEQUENCE statement is used. The general syntax of this
statement is given below:
Remember the PERSON table created in previous chapter with the following statement.
Page 79
Now, the following statement creates a sequence named PERSON_NID_SEQ to be used for
inserting rows in PERSON table.
●
BS
The above created sequence –
● The NOCYLE option ensures that after the maximum value is generated, the sequence will
stop generating value. If you want the sequence to generate values again from the starting
value, use the CYCLE option instead of NOCYCLE option.
The created sequence PERSON_NID_SEQ will be used for inserting data in the PERSON table.
The sequence will provide sequential numbers for the NID column of the PERSON table. The
NEXTVAL is used to retrieve next sequential number from the sequence as shown by the following
INSERT statements:
Page 80
You can view the current value of the sequence by the following query:
3. Creating Indexes
What is an Index
An index –
● Provides fast access to the table data using the column on which index is defined
Are automatically managed by the Oracle server after user creates the index.
For example, the following statement creates an index on the NAME column of the PERSON table
defined above. This will enable faster access of data based on NAME column. That means, if the
NAME column is used in WHERE clause of a query, then Oracle can retrieve query results more
quickly than if no index was present.
You can drop an index using DROP INDEX statement as shown below:
Page 81
When to create indexes?
In general, you should create an index on a column only when one or more of the following conditions
are satisfied –
● The table is large and most queries are expected to retrieve only less than 2% to 4% rows.
BS
In class.
LA
ML
Page 82
Chapter 11: Introduction to PL/SQL
BS
The different sections of PL/SQL block are summarized below:
LA
● Declarative (after DECLARE) – Contains declaration of variables, constants, etc. This
is an optional section.
● Executable (after BEGIN) – Contains SELECT statements to retrieve data from tables
and contain PL/SQL statements to manipulate those data. This is a mandatory section.
codes. The following statement shows an anonymous block that outputs ‘Hello world’.
Page 83
Execute an anonymous block
To execute the anonymous block written above, you need to copy paste the entire code into
SQL*PLUS. Do not forget to copy the forward slash (/) also. At first, you may not see any output.
To view PL/SQL outputs in the SQL*PLUS, you need to issue following command before executing
For programming, you will need to declare variables to store temporary values. The following
script declares a variable named ENAME. The SQL query in the executive section retrieves full
name of the employee numbered 100. Then, output the result.
BS
LA
Note that use INTO keyword to store value from SELECT statement into PL/SQL variable (ENAME).
You can use SQL functions in PL/SQL statements. The following statement outputs the
number of months employee 100 worked in the company.
Page 84
Note that, the assignment operator in PL/SQL is colon-equal (≔). The equal (=) operator is the
equality comparison operator and cannot be used as an assignment operator. Do not give space
between the colon (:) and equal (=) of the colon-equal (≔) operator, otherwise it will generate an
error.
In case, your PL/SQL block contains a syntactic error, Oracle will generate and show an error-code
rather than showing the errors. To view the errors along with their line numbers, you need to run the
BS
following command:
Oracle will not compile the erroneous blocks. You must correct the errors and re-run the corrected code.
LA
Use of IF-ELSE conditional statement
The IF-ELSE statement processes conditional statements. The general structure of IF-ELSE
statement is given below.
ML
The following example shows the use of IF-ELSE in PL/SQL. The script finds whether
employee numbered 100 worked for more than 10 years in the company.
Page 85
The following example shows another use of IF-ELSE statement to find the grade level of
employee numbered 100.
BS
LA
ML
Do not forget to use THEN after each ELSIF clause. This is a common mistake everyone does.
Page 86
Comments in PL/SQL blocks
You can put single-line comments and multi-line comments in a PL/SQL block. The syntax of
both comments is given below.
Handling exceptions
BS
An Oracle statement can throw exceptions. For example, in our previous two blocks, the first
SELECT statement can throw exception if not data is found in database for the given employee id.
When an Oracle statement throws an exception, the PL/SQL block immediately exits discarding later
statements in the block. To examine this behavior, just run the above two blocks by modifying the
employee id from 100 to 10000. Since, there is no employee numbered 10000 in the EMPLOYEES
LA
table, the SELECT statement would throw an exception and PL/SQL block would exit.
Sometimes, we need to show meaningful messages to the user when such an exception occurs. In
this case, we will need somehow to handle the exception ourselves and generate those messages.
In Oracle PL/SQL, we can handle an exception by writing an EXCEPTION section before the
END statement of the block. The following example shows how to do this.
ML
Page 87
The general syntax of handling exception codes is following:
BS
LA
ML
● In our example above, we used two pre-defined exception names: NO_DATA_FOUND and
OTHERS. There are many pre-defined exception names in Oracle. You must have the
knowledge
Page 88
of these exception names as Oracle throws such exceptions for several types of errors
while processing a statement.
BS
ZERO_DIVIDE
Practice 11.2
error occurs.
When an attempt is made to divide a number by zero.
LA
a. Extend the above block by handing the following exception: TOO_MANY_ROWS.
Print an appropriate message when such an exception occurs.
b. Write an example PL/SQL block that inserts a new arbitrary row to the COUNTRIES
table. The block should handle the exception DUP_VAL_ON_INDEX and OTHERS.
Run the block for different COUNTRY_ID and observe the cases when above
exception occurs.
ML
There are several types of loop statements in PL/SQL such as FOR loops, WHITE loops,
and unconditional loops. These are described below.
Page 89
The following for loop prints the numbers from 1 to 100.
BS
LA
The following example prints the numbers from 1 to 100 using WHILE loop.
ML
Page 90
There is a type of loop called unconditional-loop in Oracle PL/SQL. The following example shows
how to write the unconditional loop to print the numbers from 1 to 100.
BS
Note the statement EXIT WHEN to exit the unconditional loop. This is a must in an unconditional
loop otherwise the loop will run for-over. Also note that EXIT WHEN statement can also be used
inside a WHILE loop or FOR loop to exit at any time.
The general structure of writing a loop (a FOR loop) in PL/SQL is given below.
ML
The following example augments our previous code of finding employees working for more
than 10 years. This time, the script counts the number of employees who worked 10 years or
more in the company. Then, it displays the count.
Page 91
BS
In the above script, a special variable R is used which is called a cursor-variable. Details of cursor are
out of scope of this book. In summary –
● Only those columns are available that are retrieved in the SELECT statement
(R.LAST_NAME is invalid as LAST_NAME is not retrieved in SELECT)
ML
The following PL/SQL block increases salary of each employee X by 15% who have worked in
the company for 10 years or more.
Page 92
BS
Practice 11.1
a. Write a PL/SQL block that will print ‘Happy Anniversary X’ for each employee X
whose hiring date is today. Use cursor FOR loop for the task.
LA
4. PL/SQL Procedures
PL/SQL procedures and functions (to be discussed in later section) are like PL/SQL blocks except
the following:
ML
● Unlike PL/SQL (anonymous) blocks, a PL/SQL procedure or function has a name and
zero or more parameters. The parameters are used to give inputs to the procedure or
function. The function can even return values.
● When a procedure or function code is run in the SQL command line, the procedure or
function codes are not executed. The codes are just stored in the database. To execute the
procedure, we
Page 93
will need to call it from the command line using EXEC PROC_NAME statement. To execute
the function, we need to call it in a select statement or from inside a PL/SQL block.
Wring a procedure
● BS
Note the following regarding procedure parameters:
Let us re-write our PL/SQL block to find whether employee numbered 100 has worked10 years or
more. Let us call this procedure IS_SENIOR_EMPLOYEE. The following code shows the
procedure.
ML
Page 94
If you run the above code, then the procedure is saved in the database. Later you can execute
the procedure form the SQL*PLUS command line as follows.
You can also execute the procedure inside a PL/SQL block, inside another procedure or
function as shown below.
BS
Use of procedure parameters
LA
Procedure parameters can be utilized to send inputs to the procedure. Let us re-write our previous
procedure IS_SENIOR_EMPLOYEE so that the employee id is not kept fixed in the code rather we
can send the employee id as a parameter to the procedure during run-time. The modified version of
the procedure is given below.
ML
Page 95
The greatest advantage of this modified parameterized version is that we can now run the same
procedure for several employees as shown below.
BS
We can handle exceptions in a PL/SQL procedure like we did in PL/SQL (anonymous) block.
In all practical tasks, handling exception is a must.
Although, we did not handle any exception in the above blocks, a good programmer should
handle all required exceptions and show meaning messages to the user. The following code
illustrates this.
LA
ML
Page 96
After handling exceptions as above, run the following block to understand the effect.
BS
Let us re-write above procedure so that it stores the resulting message in an output variable rather
than printing the message itself. The following code shows how to do this.
LA
ML
Page 97
The following code now tests the re-written procedure. It uses a new variable MESSAGE to retrieve
the output of the procedure. Then it prints the MESSAGE.
BS
5. PL/SQL Functions
A PL/SQL function is like a PL/SQL procedure except that it must return a value. The general syntax
of a PL/SQL function is slightly different than a PL/SQL procedure. It only has an RETURN
<DATATYPE> clause at the end of the CREATE OR REPLACE statement.
LA
ML
The effect of the RETURN statement is that a value is return after successful execution of the
function. That value will be used in the calling section.
Page 98
Let us re-write the same procedure used before as a function. In this task, the MSG variable used in
the procedure to output the message will be done by return statement. The following code shows the
function how to do this.
BS
LA
ML
● A function must return a value of desired value from the BEGIN section
● A function must also return a value of desired type from the EXCEPTION section.
Page 99
Why function when procedure can output value?
We have seen that a procedure can output values. So why should one write a function? The most
important application of writing a function is that it can be used in a SELECT query unlike a
procedure which can’t be used. The beautiful effect of a function can then be best understood like
other SQL functions we have seen and used before in various queries.
Let us write the following SQL query and see the output.
BS
Nested PL/SQL blocks
LA
PL/SQL blocks can be nested. This means we can write a PL/SQL block inside a PL/SQL block. We
will go into too much details of nesting. We will just illustrate the nesting by re-writing the function
we created above.
Let us re-write the above function as follows. In this case, before retrieving the HIRE_DATE of the
employee, we will first check whether such an employee occurs in database. After it is found that
ML
such an employee occurs, we will retrieve its HIRE_DATE and continue later processing. The
modified function is shown below.
Page 100
BS
LA
Note the following:
● Inner PL/SQL blocks are like a general block that can have EXCEPTION section as
well if required.
ML
● In the modified function, exception handling is not required. Because this time number of
employees is first checked before retrieving employee’s hiring date. If no such data is found,
then the first SELECT COUNT(*) INTO ECOUNT query retrieves 0 into ECOUNT variable.
So, no exception occurs and therefore exception handling is also not required.
Practice
Page 101
an input VARCHAR2 value and checks whether the input can be converted to a valid
number. If the input can be converted to a valid number than ISNUMBER should return
‘YES’, otherwise ISNUMBER should return ‘NO’.
6. Pl/SQL Triggers
A trigger is a PL/SQL stored block. It is like a function or a procedure. However, it is different than
a function or a procedure. To run a function or a procedure, it is explicitly called from a code.
However, a trigger is automatically run by the Oracle. It is not called from any code directly.
Trigger is very useful when certain tasks are needed to be done after or before a DML operation.
For example, suppose we need to ensure that after every deletion of an employee records from the
EMPLOYEES table, the records of the deleted employee should go to a backup table. In such
cases, a trigger can be written which will perform the required task easily. Since, trigger will be
LA
automatically called after the deletion operation; we need not to manually handle the writing
backup records.
The general syntax of a trigger is like a procedure or a function except the header line.
ML
Page 102
Let’s first create the following table STUDENTS.
Let’s understand the trigger by writing our first trigger HELLO_WORLD trigger. This trigger will
print “Hello World” whenever an insertion statement is run on the table STUDENTS.
BS
LA
Now, insert some rows (as shown below) and see what output comes!
ML
The trigger will run twice for the two insert statements and it will ouput “Hello World”.
Although, HELLO_WORLD trigger does not show the actual power of triggers, it demonstrates at
least the basic properties of a trigger which are following:
● HELLO_WORLD trigger will run automatically by Oracle when an insert statement is run on
the table STUDENTS.
Page 103
Let’s try several modification of the above trigger so that it runs in various settings. The following
codes show five variations of the HELLO_WORLD trigger.
--This trigger will run after an insert or a delete statement on STUDENTS table
ON
BS
CREATE OR REPLACE TRIGGER
HELLO_WORLD3 AFTER INSERT OR DELETE
STUDENTS
DECLARE
LA
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World3');
END ;
/
--The following trigger will run after an update statement on STUDENTS table.
--Added with that, this trigger will only run when update is performed on the
--CGPA column.
ML
--The following trigger will run after an update operation on the STUDENTS table.
--Added with that, the trigger will run once for each row. The previous rows will
Page 104
Read the above five trigger codes and understand them. After you properly understand all five
triggers, let’s now determine which trigger will be called by Oracle for the following five SQL
BS
LA
ML
statements.
Page 105
After analyzing the above five triggers, you should now understand the following:
● The DML operation can be insert, update, delete or a combination of the three.
● The trigger can be created such that it is run only once after an SQL statement or it is run
once per row affected by an SQL statement.
Classification of triggers
● BEFORE trigger vs. AFTER trigger – A BEFORE trigger is executed before a statement
and an AFTER trigger is executed after the statement.
BS ROW LEVEL trigger vs. STATEMENT LEVEL trigger – A ROW LEVEL trigger is created
when FOR EACH ROW clause is specified in the trigger definition. In this case, the trigger
will be called after or before each row that is affected by the operation. A STATEMENT
LEVEL trigger is executed only once for each statement. So, if you issue a DML statement
that affect N rows, then a STATEMENT LEVEL trigger will be executed once while a ROW
LA
LEVEL trigger will be executed N times. A STATEMENT LEVEL trigger must get executed
once while a ROW LEVEL trigger may not get executed at all if the DML operation does not
affect any row!!!
Practice
● Write a trigger HELLO_WORLD6 that will run after a deletion operation on the
ML
Problem Example 1
Write a PL/SQL trigger LOG_CGPA_UPDATE. This trigger will log all updates done on the CGPA
column of STUDENTS table. The trigger will save current user’s name, current system date and time
in a log table named LOG_TABLE_CGPA_UPDATE.
Solution
The trigger required will be a STATEMENT LEVEL trigger. Because, it is required to run only per
SQL statement which will serve our purpose.
Page 106
Let’s first create the LOG_TABLE_CGPA_UPDATE table as follows.
BS
LA
After the trigger is created, issue the following update commands and then finally view the rows
inserted into LOG_TABLE_CGPA_UPDATE table.
ML
Page 107
Problem Example 2
Write a PL/SQL trigger BACKUP_DELETED_STUDENTS. This trigger will save all records that
are deleted from the STUDENTS table into a backup table named STUDENTS_DELETED. The
trigger will save student’s record along with current user’s name and current system date and time.
Solution
The trigger required will be a ROW LEVEL trigger. Because, it is required to run per row affected.
Each row that will be deleted will need to be saved in the backup table.
BS
The following code shows the trigger definition required to perform the specified task.
LA
ML
Page 108
Note the use of :OLD special reference. This reference is used to access the column values of
currently affected row by the DELETE operation. Like the :OLD reference, there is a :NEW
reference that can be used to retrieve the column values of the new row that will result after
completion of the operation.
After the trigger is compiled and stored successfully, issue the following command and view the
rows inserted by the trigger.
●
BS
Note the following regarding :OLD and :NEW references-
● They are valid only for ROW LEVEL triggers! You are not allowed to use these
in a STATEMET LEVEL trigger.
For an update statement, :OLD is used to retrieve old values of columns while :NEW is
LA
used to retrieve new values of columns.
● For an insert statement, :OLD retrieves NULL values for all columns while :NEW can be
used to retrieve column values of the row
● For a delete statement :NEW retrieves NULL values while :OLD can be used to retrieve
column values of the row
ML
● :NEW reference can be used to change column values of a row before it is going to be
inserted in the table. This will require a BEFORE trigger.
To understand the :OLD and :NEW reference more deeply, write the following trigger and issue the
SQL commands listed after the trigger.
Page 109
Practice
● Write a trigger that will save a student records in a table named LOW_CGPA_STUDENTS
BS which contain only one column to store student’s names. The trigger will work before an
update operation or an insert operation. Whenever the update operation results in a CGPA
value less than 2.0, the trigger will be fired and the trigger will save the students name in the
LOW_CGPA_STUDENTS table. Similarly, when an insert operation inserts a new row with
CGPA less than 2.0, the corresponding row must be saved in the LOW_CGPA_STUDENTS
LA
table.
Problem Example 3
Write a PL/SQL trigger CORRECT_STUDENT_NAME. This trigger will be used to correct the text
case of the student names when it is going to be inserted. So, this will be a BEFORE INSERT trigger.
The trigger will change the case of the student’s name to INITCAP format if it was not given by the
ML
user in the INSERT statement. The trigger will thus ensure that all names stored in the STUDENTS
table will be in a consistent format.
Page 110
Note that the above trigger must be a BEFORE INSERT trigger. If you write an AFTER INSERT
trigger, then it will not work. Because in an AFTER INSERT trigger, you are not allowed to change
values of the
:NEW row.
Practice
● Write down a PL/SQL trigger on STUDENTS table. The trigger will ensure that whenever a
BS new row is inserted in the STUDENTS table, the name of the student contains only
alphabetic characters. Name your trigger INVALID_NAME. If the name is valid, then
insertion should be allowed. However, if the name is invalid, then insertion should be denied.
To deny insertion, you can throw an exception from the trigger that would halt the insertion
operation.
LA
Drop a trigger from database
So, to drop the trigger OLD_NEW_TEST from the database, issue the following command.
ML
In class.
Page 111
ML
LA
BS