Você está na página 1de 127

INTRODUCTION TO SQL FUNDAMENTALS I & II

Author:
Saad Ahmed Pasha
Doc Version:
V1.0
Date:
24-June-2011

Chapter # 1: Retrieving Data Using the SQL SELECT


Statement
Topics:
1.1: Select Statements
Sql> SELECT department_id, location_id FROM departments;
Output:
DEPARTMENT_ID
------------------------10
20
30
40

LOCATION_ID
-------------------1700
1800
1700
2400

1.2: Arithmetic expressions and NULL values in the SELECT statement


Sql> SELECT last_name, salary, 12*(salary+100) FROM employees;
Output:
LAST_NAME
------------------------Mavris
Baer
Higgins
Gietz
King
Kochhar

SALARY
-----------6500
10000
12008
8300
24000
17000

12*(SALARY+100)
---------------------------------79200
121200
145296
100800
289200
205200

Sql> SELECT last_name, salary, 12*salary+100 FROM employees;

1 | Page

Output:
LAST_NAME
------------------------OConnell
Grant
Whalen

SALARY
---------2600
2600
4400

12*SALARY+100
------------31300
31300
52900

Sql> SELECT last_name, salary, salary + 300 FROM employees;


Output:
LAST_NAME
------------------------OConnell
Grant
Whalen
Hartstein
Fay

SALARY
-----------2600
2600
4400
13000
6000

SALARY+300
-----------------2900
2900
4700
13300
6300

Sql> SELECT last_name, job_id, salary, commission_pct FROM employees; (NULL VALUES)
Output:
LAST_NAME
------------------------OConnell
Grant
Whalen
Hartstein
Fay

JOB_ID
---------SH_CLERK
SH_CLERK
AD_ASST
MK_MAN
MK_REP

SALARY
---------2600
2600
4400
13000
6000

COMMISSION_PCT
----------------------------(null)
(null)
(null)
(null)
(null)

Sql> SELECT last_name, 12*salary*commission_pct FROM employees;


(NULL VALUES IN ARTHIMATIC EXPRESSIONS)
Output:
LAST_NAME
-------------------------

12*SALARY*COMMISSION_PCT
--------------------------------------------

OConnell
Grant
Whalen
Hartstein
Fay
Sql> SELECT last_name AS name, commission_pct comm. FROM employees;
(COLUMN ALIASES)

2 | Page

Output:
NAME
------------------------OConnell
Grant
Whalen
Hartstein
Fay

COMM
----------

Sql> SELECT last_name "Name" , salary*12 "Annual Salary" FROM employees;


(apni marzi k alias k liye inverted comas use karte hain)
Output:
Name
------------------------OConnell
Grant
Whalen
Hartstein
Fay

Annual Salary
-------------------31200
31200
52800
156000
72000

1.3: Use of concatenation operator (||), literal character strings,


alternative quote operator, and the DISTINCT keyword
Sql> SELECT last_name || job_id AS "Employees" FROM employees;
Output:
Employees
---------------AbelSA_REP
AndeSA_REP
AtkinsonST_CLERK
AustinIT_PROG
BaerPR_REP
BaidaPU_CLERK
Sql> SELECT last_name ||' is a '||job_id AS "Employee Details" FROM employees;
(Literal Character String)
Output:
Employee Details
-----------------------Abel is a SA_REP
Ande is a SA_REP
Atkinson is a ST_CLERK
3 | Page

Austin is a IT_PROG
Baer is a PR_REP
Sql> SELECT department_name || q'[ Department's Manager Id: ]' || manager_id
AS "Department and Manager" FROM departments; (Alternative Quote q Operator)
Output:
Department and Manager
--------------------------------------------Administration Department's Manager Id: 200
Marketing Department's Manager Id: 201
Purchasing Department's Manager Id: 11
Sql> SELECT DISTINCT department_id FROM employees;
(DISTINCT Keyword Show NULL Values)
Output:
DEPARTMENT_ID
------------100
30
(null)
20
70
90
Sql> DESCRIBE employees
Output:
Name
----------------------------------------EMPLOYEE_ID
FIRST_NAME
LAST_NAME
EMAIL
PHONE_NUMBER
HIRE_DATE
JOB_ID
SALARY
COMMISSION_PCT
MANAGER_ID
DEPARTMENT_ID

Null?
-------NOT NULL
NOT NULL
NOT NULL
NOT NULL
NOT NULL

Type
-----------NUMBER(6)
VARCHAR2(20)
VARCHAR2(25)
VARCHAR2(25)
VARCHAR2(20)
DATE
VARCHAR2(10)
NUMBER(8,2)
NUMBER(2,2)
NUMBER(6)
NUMBER(4)

4 | Page

Summary:
1. Sql> SELECT department_id, location_id FROM departments;
2. Sql> SELECT last_name, salary, 12*(salary+100) FROM employees;
3. Sql> SELECT last_name, salary, 12*salary+100 FROM employees;
4. Sql> SELECT last_name, salary, salary + 300 FROM employees;
5. Sql> SELECT last_name, job_id, salary, commission_pct FROM employees;
6. Sql> SELECT last_name, 12*salary*commission_pct FROM employees;
7. Sql> SELECT last_name AS name, commission_pct comm FROM employees;
8. Sql> SELECT last_name "Name", salary*12 "Annual Salary" FROM employees;
9. Sql> SELECT last_name || job_id AS "Employees" FROM employees;
10. Sql> SELECT last_name ||' is a '||job_id AS "Employee Details" FROM employees;
11. Sql> SELECT department_name || q'[ Department's Manager Id: ]' || manager_id AS
"Department and Manager" FROM departments;
12. Sql> SELECT DISTINCT department_id FROM employees;
13. Sql> DESCRIBE employees

5 | Page

Chapter # 2: Restricting and Sorting Data


Topics:
2.1: Limiting rows with:
The WHERE clause
The comparison conditions using =, <=, BETWEEN, IN, LIKE,
and NULL conditions
Logical conditions using AND, OR, and NOT operators
Sql> SELECT employee_id, last_name, job_id, department_id FROM employees
WHERE department_id = 90;
Output:
EMPLOYEE_ID
--------------------100
101
102

LAST_NAME
-----------------King
Kochhar
De Haan

JOB_ID
----------AD_PRES
AD_VP
AD_VP

DEPARTMENT_ID
-------------------------90
90
90

Sql> SELECT last_name, job_id, department_id FROM employees


WHERE last_name = 'Whalen' ; (Character String (case sensitive))
Output:
LAST_NAME
-----------------Whalen

JOB_ID
-----------AD_ASST

DEPARTMENT_ID
-------------------------10

Sql> SELECT last_name FROM employees


WHERE hire_date = '23-MAY-06'; (Date String (Format Sensitive DD-MON-RR))
Output:
LAST_NAME
-----------------Feeney

6 | Page

Comparison Operators Table:


Operator

Meaning

=
>
>=
<
<=
<>
BETWEEN ...AND...
IN(set)
LIKE
IS NULL

Equal to
Greater than
Greater than or equal to
Less than
Less than or equal to
Not equal to
Between two values (inclusive)
Match any of a list of values
Match a character pattern
Is a null value

Sql> SELECT last_name, salary FROM employees WHERE salary <= 3000;
Output:
LAST_NAME
------------------------OConnell
Grant
Baida
Tobias

SALARY
------------2600
2600
2900
2800

Sql> SELECT last_name, salary FROM employees


WHERE salary BETWEEN 2500 AND 3500;
LOWER LIMIT

UPPER

Output:
LAST_NAME
------------------------OConnell
Grant
Khoo
Baida

SALARY
-----------2600
2600
3100
2900

Sql> SELECT employee_id, last_name, salary, manager_id FROM employees


WHERE manager_id IN (100, 101, 201);
Output:
EMPLOYEE_ID
--------------------201
101

LAST_NAME
-----------------Hartstein
Kochhar

SALARY
------------13000
17000

MANAGER_ID
-------------------100
100
7 | Page

200
Whalen
4400
101
Sql> SELECT last_name FROM employees WHERE last_name LIKE '_o%';
Output:
LAST_NAME
--------------Colmenares
Doran
Fox
Johnson
Jones
Sql> SELECT last_name, manager_id FROM employees WHERE manager_id IS NULL;
Output:
LAST_NAME
------------------------King

MANAGER_ID
--------------------(null)

Logical Operators Table:


Operator

Meaning

AND
OR
NOT

Returns TRUE if both component conditions are true


Returns TRUE if either component condition is true
Returns TRUE if the condition is false

Sql> SELECT employee_id, last_name, job_id, salary FROM employees


WHERE salary >= 10000 AND job_id LIKE '%MAN%';
Output:
EMPLOYEE_ID
--------------------201
114
145
146
147
148
149

LAST_NAME
------------------------Hartstein
Raphaely
Russell
Partners
Errazuriz
Cambrault
Zlotkey

JOB_ID
-----------MK_MAN
PU_MAN
SA_MAN
SA_MAN
SA_MAN
SA_MAN
SA_MAN

SALARY
-----------13000
11000
14000
13500
12000
11000
10500

Sql> SELECT employee_id, last_name, job_id, salary FROM employees


WHERE salary >= 10000 OR job_id LIKE '%MAN%';

8 | Page

Output:
EMPLOYEE_ID
--------------------201
204
205
100
101

LAST_NAME
-----------------Hartstein
Baer
Higgins
King
Kochhar

JOB_ID
-----------MK_MAN
PR_REP
AC_MGR
AD_PRES
AD_VP

SALARY
-----------13000
10000
12008
24000
17000

Sql> SELECT last_name, job_id FROM employees WHERE job_id


NOT IN ('IT_PROG', 'ST_CLERK', 'SA_REP');
Output:
LAST_NAME
----------------Baer
Baida
Bell
Bull
Cabrio
Cambrault

JOB_ID
-----------PR_REP
PU_CLERK
SH_CLERK
SH_CLERK
SH_CLERK
SA_MAN

2.2: Rules of precedence for operators in an expression


Rule of Precedence Table:
Operator
1
2
3
4
5
6
7
8
9

Meaning
Arithmetic operators
Concatenation operator
Comparison conditions
IS [NOT] NULL, LIKE, [NOT] IN
[NOT] BETWEEN
Not equal to
NOT logical condition
AND logical condition
OR logical condition

You can use parentheses to override rules of precedence.


Sql> SELECT last_name, job_id, salary FROM employees WHERE job_id = 'SA_REP'
OR job_id = 'AD_PRES' AND salary > 15000;

Output:
9 | Page

LAST_NAME
------------------------King
Tucker
Bernstein
Hall

JOB_ID
---------AD_PRES
SA_REP
SA_REP
SA_REP

SALARY
-----------24000
10000
9500
9000

Sql> SELECT last_name, job_id, salary FROM employees


WHERE ( job_id = 'SA_REP' OR job_id = 'AD_PRES' ) AND salary > 15000;
Output:
LAST_NAME
------------------------King

JOB_ID
----------AD_PRES

SALARY
------------24000

2.3: Sorting rows using the ORDER BY clause (BY DEFAULT ASCENDING ORDER)
Sql> SELECT last_name, job_id, department_id, hire_date FROM employees
ORDER BY hire_date;
Output:
LAST_NAME
------------------------De Haan
Mavris
Baer
Higgins
Gietz

JOB_ID DEPARTMENT_ID
---------------------AD_VP
90
HR_REP
40
PR_REP
70
AC_MGR
110
AC_ACCOUNT
110

HIRE_DATE
--------13-JAN-01
07-JUN-02
07-JUN-02
07-JUN-02
07-JUN-02

Sql> SELECT last_name, job_id, department_id, hire_date FROM employees


ORDER BY hire_date DESC;
Output:
LAST_NAME
------------------------Banda
Kumar
Ande
Markle

JOB_ID DEPARTMENT_ID
---------------------SA_REP
80
SA_REP
80
SA_REP
80
ST_CLERK
50

HIRE_DATE
--------21-APR-08
21-APR-08
24-MAR-08
08-MAR-08

Sql> SELECT employee_id, last_name, salary*12 annsal FROM employees ORDER BY


Annsal;

Output:
10 | P a g e

EMPLOYEE_ID
----------132
136
128
127

LAST_NAME
------------------Olson
Philtanker
Markle
Landry

ANNSAL
------------25200
26400
26400
28800

Sql> SELECT last_name, job_id, department_id, hire_date FROM employees ORDER BY 3;


Output:
LAST_NAME
------------------------Whalen
Hartstein
Fay
Raphaely
Colmenares
Khoo

JOB_ID DEPARTMENT_ID
---------------------AD_ASST
10
MK_MAN
20
MK_REP
20
PU_MAN
30
PU_CLERK
30
PU_CLERK
30

HIRE_DATE
--------17-SEP-03
17-FEB-04
17-AUG-05
07-DEC-02
10-AUG-07
18-MAY-03

Sql> SELECT last_name, department_id, salary FROM employees


ORDER BY department_id, salary DESC;
Output:
LAST_NAME
------------------------Whalen
Hartstein
Fay
Raphaely

DEPARTMENT_ID
------------10
20
20
30

SALARY
-----------4400
13000
6000
11000

2.4: Substitution variables (Single Ampersand (&) n Double Ampersand(&&))


Use a variable prefixed with an ampersand (&) to prompt the user for a value
Sql> SELECT employee_id, last_name, salary, department_id FROM employees
WHERE employee_id = &employee_num;
Output:
Enter value for employee_num: 100
old 3: WHERE employee_id = &employee_num
new 3: WHERE employee_id = 100
EMPLOYEE_ID
LAST_NAME
SALARY
DEPARTMENT_ID
------------------------------------------------------------------------100
King
24000
90
Sql> SELECT last_name, department_id, salary*12 FROM employees
WHERE job_id = '&job_title';
11 | P a g e

Output:
Enter value for job_title: IT_PROG
old 3: WHERE job_id = '&job_title'
new 3: WHERE job_id = 'IT_PROG'
LAST_NAME
------------------------Hunold
Ernst
Austin
Pataballa
Lorentz

DEPARTMENT_ID
----------------------60
60
60
60
60

SALARY*12
---------------108000
72000
57600
57600
50400

Sql> SELECT employee_id, last_name, job_id, &&column_name FROM employees


ORDER BY &column_name;
Output:
Enter value for column_name: first_name
old 1: SELECT employee_id, last_name, job_id, &&column_name
new 1: SELECT employee_id, last_name, job_id, first_name
old 3: ORDER BY &column_name
new 3: ORDER BY first_name
EMPLOYEE_ID
--------------------121
196
147
103

LAST_NAME
-----------------Fripp
Walsh
Errazuriz
Hunold

JOB_ID
---------ST_MAN
SH_CLERK
SA_MAN
IT_PROG

FIRST_NAME
------------------Adam
Alana
Alberto
Alexander

2.5: DEFINE and VERIFY commands


Sql> DEFINE employee_num = 200
SELECT employee_id, last_name, salary, department_id
FROM employees
WHERE employee_id = &employee_num ;
UNDEFINE employee_num
Output:
old 3: WHERE employee_id = &employee_num
new 3: WHERE employee_id = 200
EMPLOYEE_ID
LAST_NAME
SALARY
------------------------------------------------200
Whalen
4400
Sql> SET VERIFY ON
SELECT employee_id, last_name, salary FROM employees

DEPARTMENT_ID
------------------------10

12 | P a g e

WHERE employee_id = &employee_num;


Output:
Enter value for employee_num: 200
old 3: WHERE employee_id = &employee_num
new 3: WHERE employee_id = 200
EMPLOYEE_ID
--------------------200

LAST_NAME
-----------------Whalen

SALARY
-----------4400

Summary:
13 | P a g e

Sql> SELECT employee_id, last_name, job_id, department_id FROM employees


WHERE department_id = 90;
Sql> SELECT last_name, job_id, department_id FROM employees
WHERE last_name = 'Whalen' ;
Sql> SELECT last_name FROM employees WHERE hire_date = '23-MAY-06';
Sql> SELECT last_name, salary FROM employees WHERE salary <= 3000;
Sql> SELECT last_name, salary FROM employees
WHERE salary BETWEEN 2500 AND 3500;
Sql> SELECT employee_id, last_name, salary, manager_id FROM employees
WHERE manager_id IN (100, 101, 201);
Sql> SELECT last_name FROM employees WHERE last_name LIKE '_o%';
Sql> SELECT last_name, manager_id FROM employees WHERE manager_id IS NULL;
Sql> SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary >= 10000 AND job_id LIKE '%MAN%';
Sql> SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary >= 10000 OR job_id LIKE '%MAN%';
Sql> SELECT last_name, job_id FROM employees WHERE job_id
NOT IN ('IT_PROG', 'ST_CLERK', 'SA_REP');
Sql> SELECT last_name, job_id, salary FROM employees WHERE job_id = 'SA_REP'
OR job_id = 'AD_PRES' AND salary > 15000;
Sql> SELECT last_name, job_id, salary FROM employees
WHERE ( job_id = 'SA_REP' OR job_id = 'AD_PRES' ) AND salary > 15000;
Sql> SELECT last_name, job_id, department_id, hire_date FROM employees
ORDER BY hire_date;
Sql> SELECT last_name, job_id, department_id, hire_date FROM employees
ORDER BY hire_date DESC;
Sql> SELECT employee_id, last_name, salary*12 annsal FROM employees ORDER BY
annsal;
Sql> SELECT last_name, job_id,department_id,hire_date FROM employees ORDER BY 3;
Sql> SELECT last_name, department_id, salary FROM employees
ORDER BY department_id, salary DESC;
Sql> SELECT employee_id, last_name, salary, department_id FROM employees
WHERE employee_id = &employee_num;
Sql> SELECT last_name, department_id, salary*12 FROM employees
WHERE job_id = '&job_title';
Sql> SELECT employee_id, last_name, job_id, &&column_name FROM employees
ORDER BY &column_name;
Sql> DEFINE employee_num = 200
SELECT employee_id, last_name, salary, department_id FROM employees
WHERE employee_id = &employee_num ;
UNDEFINE employee_num
Sql> SET VERIFY ON
SELECT employee_id, last_name, salary FROM employees

WHERE employee_id = &employee_num;

14 | P a g e

Chapter # 3: Using Single-Row Functions to Customize


Output
Topics:
3.1: Single-row SQL functions (Return One Result per Row)
Single-row functions:
Manipulate data items
Accept arguments and return one value
Act on each row that is returned
Return one result per row
May modify the data type
Can be nested
Accept arguments that can be a column or an expression

Character

General

Single
Row

Conversion

Number

Date

15 | P a g e

3.2: Character functions

Character
Functions

Function

Result

LOWER('SQL Course')
UPPER('SQL Course')
CaseINITCAP('SQL Course')

sql course
SQL COURSE
Sql Course

Conversion
Functions
LOWER
UPPER
INITCAP

Character
Manipulation
Functions
CONCAT
SUBSTR
LENGTH
INSTR
LPAD | RPAD
TRIM
REPLACE

3.2.1 Case-Conversion Functions:

Sql> SELECT employee_id, last_name, department_id FROM employees


WHERE LOWER(last_name) = 'higgins';
Output:
EMPLOYEE_ID
---------------------

LAST_NAME
------------------

DEPARTMENT_ID
-------------------------16 | P a g e

205

Higgins

110

3.2.2: Character-Manipulation Functions


Function

Result

CONCAT('Hello', 'World')
SUBSTR('HelloWorld',1,5)
LENGTH('HelloWorld')
INSTR('HelloWorld', 'W')
LPAD(salary,10,'*')
RPAD(salary, 10, '*')
REPLACE ('JACK and JUE','J','BL')
TRIM('H' FROM
'HelloWorld')

HelloWorld
Hello
10
6
*****24000
24000*****
BLACK and BLUE
elloWorld

Sql> SELECT employee_id, CONCAT(first_name, last_name) NAME,


job_id, LENGTH (last_name), INSTR(last_name, 'a') "Contains 'a'?" FROM employees
WHERE SUBSTR(job_id, 4) = 'REP';
Output:
EMPLOYEE_ID
--------------------202
203
204

NAME
LENGTH (LAST_NAME)
----------------------------------------PatFay
3
SusanMavris
6
HermannBaer
4

Contains 'a'?
----------------2
2
2

JOB_ID
----------MK_REP
HR_REP
PR_REP

3.3: Number functions

ROUND: Rounds value to a specified decimal


TRUNC: Truncates value to a specified decimal
MOD: Returns remainder of division

Function

Result

ROUND(45.926, 2)
TRUNC(45.926, 2)
MOD(1600, 300)

45.93
45.92
100

Sql> SELECT ROUND(45.923,2), ROUND(45.923,0), ROUND(45.923,-1)


FROM DUAL; (DUAL is a Dummy Table)

17 | P a g e

Output:
ROUND(45.923,2)
-----------------------45.92

ROUND(45.923,0)
-----------------------46

ROUND(45.923,-1)
------------------------50

Sql> SELECT TRUNC(45.923,2), TRUNC(45.923),


TRUNC(45.923,-1) FROM DUAL;
Output:
TRUNC(45.923,2)
-----------------------45.92

TRUNC(45.923)
---------------------45

TRUNC(45.923,-1)
------------------------40

Sql> SELECT last_name, salary, MOD(salary, 5000) FROM employees


WHERE job_id = 'SA_REP';
Output:
LAST_NAME
-----------------Tucker
Bernstein
Hall
Olsen

SALARY
-----------10000
9500
9000
8000

MOD(SALARY,5000)
----------------------------0
4500
4000
3000

3.4: Working with dates


The default date display format is DD-MON-RR.
--Enables you to store 21st-century dates in the 20th century by specifying only the last two
digits of the year.
--Enables you to store 20th-century dates in the 21st century in the same way.
Sql> SELECT last_name, hire_date FROM employees
WHERE hire_date < '23-May-06 ';
Output:
LAST_NAME
-----------------Whalen
Hartstein
Fay

HIRE_DATE
----------------17-SEP-03
17-FEB-04
17-AUG-05

18 | P a g e

Current Year

Specified Date

RR Format

YY Format

1995
1995
2001
2001

27-OCT-95
27-OCT-17
27-OCT-17
27-OCT-95

1995
2017
2017
1995

1995
1917
2017
2095

If the specified two-digit year is:


5099

0-49

The return date is


If two
The return dateinis in
digits5099
of
the century before
the current century
the
the current one
current
year are: The return date is
The return
0-49
date is in
in
the
current
century
the century before
the current one
Sql> SELECT sysdate FROM dual;
Output:
SYSDATE
-------------27-JUN-11
3.4.1: Arithmetic with Dates

Add or subtract a number to or from a date for a resultant date value.


Subtract two dates to find the number of days between those dates.
Add hours to a date by dividing the number of hours by 24.

Sql> SELECT last_name, (SYSDATE-hire_date)/7 AS WEEKS FROM employees


WHERE department_id = 90;
Output:
LAST_NAME
-----------------King
Kochhar
De Haan

WEEKS
----------418.943904
300.801047
545.372475

19 | P a g e

3.5: Date functions

Function

Result

MONTHS_BETWEEN('01-SEP-95','11-JAN-94')
ADD_MONTHS (31-JAN-96',1)
NEXT_DAY
('01-SEP-95','FRIDAY')

19.6774194
29-FEB-96'
'08-SEP-95'

LAST_DAY

'28-FEB-95'

('01-FEB-95')

Assume SYSDATE = '25-JUL-03':


Function

Result

ROUND(SYSDATE,'MONTH')
ROUND(SYSDATE ,'YEAR')
TRUNC(SYSDATE ,'MONTH')
TRUNC(SYSDATE ,'YEAR')

01-AUG-03
01-JAN-04
01-JUL-03
01-JAN-03

Summary:
Sql> SELECT employee_id, last_name, department_id FROM employees
WHERE LOWER(last_name) = 'higgins';
Sql> SELECT employee_id, CONCAT(first_name, last_name) NAME,
job_id, LENGTH (last_name), INSTR(last_name, 'a') "Contains 'a'?" FROM employees
WHERE SUBSTR(job_id, 4) = 'REP';
Sql> SELECT ROUND(45.923,2), ROUND(45.923,0), ROUND(45.923,-1)
FROM DUAL;
Sql> SELECT TRUNC(45.923,2), TRUNC(45.923),
TRUNC(45.923,-1) FROM DUAL;
Sql> SELECT last_name, salary, MOD(salary, 5000) FROM employees
WHERE job_id = 'SA_REP';
Sql> SELECT last_name, hire_date FROM employees
WHERE hire_date < '23-May-06 ';
Sql> SELECT sysdate FROM dual;
Sql> SELECT last_name, (SYSDATE-hire_date)/7 AS WEEKS FROM employees
WHERE department_id = 90;

20 | P a g e

Chapter # 4: Using Conversion Functions and Conditional


Expressions
Topics:
4.1: Implicit and explicit data type conversion

In expressions, the Oracle server can automatically convert the


following: (Implicit Data Type Conversion)

From

To

VARCHAR2 or CHAR
VARCHAR2 or CHAR

NUMBER
DATE

From

To

NUMBER VARCHAR2 or CHAR


DATE
VARCHAR2 or CHAR
Explicit Data Type Conversion
TO_NUMBER

NUMBER

TO_DATE

CHARACTER

DATE

21 | P a g e

TO_CHAR

TO_CHAR

4.2: TO_CHAR, TO_DATE, TO_NUMBER functions

(TO_CHAR Function With Dates)


Elemen
t

Result

YYYY
YEAR
MM
MONTH
MON
DY
DAY
DD

Full year in numbers


Year spelled out (in English)
Two-digit value for the month
Full name of the month
Three-letter abbreviation of the month
Three-letter abbreviation of the day of the week
Full name of the day of the week
Numeric day of the month

Time elements format the time portion of the date:


HH24:MI:SS AM
15:45:32 PM
Add character strings by enclosing them with double quotation marks:
DD "of" MONTH
12 of OCTOBER
Number suffixes spell out numbers:
ddspth

fourteenth

Sql> SELECT last_name, TO_CHAR(hire_date, 'fmDD Month YYYY')


AS HIREDATE FROM employees;
Output:
LAST_NAME
-----------------OConnell
Grant
Whalen
Hartstein

HIREDATE
----------------21 June 2007
13 January 2008
17 September 2003
17 February 2004

These are some of the format elements that you can use with the TO_CHAR function to display
a number value as a character
Elemen
t

Result

9
0
$

Represents a number
Forces a zero to be displayed
Places a floating dollar sign
22 | P a g e

L
.
,

Uses the floating local currency symbol


Prints a decimal point
Prints a comma as a thousand indicator

Sql> SELECT TO_CHAR(salary, '$99,999.00') SALARY FROM employees


WHERE last_name = 'Ernst';
Output:
SALARY
-----------$6,000.00
Using the TO_NUMBER and TO_DATE Functions
(Convert a character string to a number format using the
TO_NUMBER function)
TO_NUMBER(char[
,

'format_model'])

(Convert a character string to a date format using the


TO_DATE function)
TO_DATE(char[, 'format_model'])

These functions have an fx modifier. This modifier specifies the exact match for the character
argument and date format model of a TO_DATE function.
--Using the TO_CHAR and TO_DATE Function
with RR Date Format
Sql> SELECT last_name, TO_CHAR(hire_date, 'DD-Mon-YYYY') FROM employees
WHERE hire_date < TO_DATE('01-Jan-90','DD-Mon-RR');
Output:
LAST_NAME
-----------------Whalen
Hartstein
Fay
Mavris

TO_CHAR(HIR
--------------------17-Sep-2003
17-Feb-2004
17-Aug-2005
07-Jun-2002

4.3: Nesting functions

Single-row functions can be nested to any level.


23 | P a g e

Nested functions are evaluated from the deepest level to the least deep level.

Sql> SELECT last_name, UPPER (CONCAT (SUBSTR (LAST_NAME, 1, 8), '_US'))


FROM employees WHERE department_id = 60;
Output:
LAST_NAME
----------------Hunold
Ernst
Austin
Pataballa
Lorentz

UPPER(CONCA
----------------------HUNOLD_US
ERNST_US
AUSTIN_US
PATABALL_US
LORENTZ_US

4.4: General functions:


NVL
NVL2
NULLIF
COALESCE
NVL Function:
Converts a null value to an actual value:
Data types that can be used are date, character, and number.
Data types must match:
NVL (commission_pct,0)
NVL (hire_date,'01-JAN-97')
NVL (job_id,'No Job Yet')
Sql> SELECT last_name, salary, NVL (commission_pct, 0),
(salary*12) + (salary*12*NVL (commission_pct, 0)) AN_SAL FROM employees;
Output:
LAST_NAME
-----------------OConnell
Grant
Whalen
Hartstein

SALARY
----------2600
2600
4400
13000

NVL(COMMISSION_PCT,0)
-------------------------------------0
0
0
0

AN_SAL
-----------31200
31200
52800
156000

Using the NVL2 Function:


Sql> SELECT last_name, salary, commission_pct,
NVL2 (commission_pct, 'SAL+COMM', 'SAL') income
FROM employees WHERE department_id IN (50, 80);
24 | P a g e

Output:
LAST_NAME
-----------------OConnell
Grant
Russell
Partners
Errazuriz

SALARY
-----------2600
2600
14000
13500
12000

COMMISSION_PCT
--------------------------(null)
(null)
-4
-3
-3

INCOME
------------SAL
SAL
SAL+COMM
SAL+COMM
SAL+COMM

Using the NULLIF Function:


Sql> SELECT first_name, LENGTH(first_name) "expr1",
last_name, LENGTH(last_name) "expr2",
NULLIF(LENGTH(first_name), LENGTH(last_name)) result FROM employees;
Output:
FIRST_NAME
-------------------Jennifer
Louise
Bruce
Alberto
Britney

expr1
-------8
6
5
7
7

LAST_NAME
-----------------Dilly
Doran
Ernst
Errazuriz
Everett

expr2 RESULT
---------- -----------5
8
5
6
5
(null)
9
7
7
(null)

Using the COALESCE Function:

The advantage of the COALESCE function over the NVL function is that the COALESCE
function can take multiple alternate values.
If the first expression is not null, the COALESCE function returns that expression;
otherwise, it does a COALESCE of the remaining expressions.

Sql> SELECT last_name, employee_id, COALESCE (TO_CHAR (commission_pct),


TO_CHAR (manager_id), 'No commission and no manager') FROM employees;
Output:
LAST_NAME
-----------------OConnell
Grant
Whalen

EMPLOYEE_ID
--------------------198
199
200

COALESCE (TO_CHAR(COMMISSION_PCT),TO_CHAR
----------------------------------------------------------------------------124
124
101
25 | P a g e

Hartstein
Gietz
King

201
206
100

100
205
No commission and no manager

4.5: Conditional expressions:


CASE
DECODE
Provide the use of the IF-THEN-ELSE logic within a SQL statement.
Use two methods:
--CASE expression
--DECODE function
CASE expression:
Sql> SELECT last_name, job_id, salary,
CASE job_id WHEN 'IT_PROG' THEN 1.10*salary
WHEN 'ST_CLERK' THEN 1.15*salary
WHEN 'SA_REP' THEN 1.20*salary
ELSE salary END "REVISED_SALARY" FROM employees;
Output:
LAST_NAME
-----------------De Haan
Hunold
Tucker
Bernstein
Philtanker

JOB_ID
----------AD_VP
IT_PROG
SA_REP
SA_REP
ST_CLERK

SALARY
----------17000
9000
10000
9500
2200

REVISED_SALARY
-------------------------17000
9900
12000
11400
2530

DECODE Function:
Sql> SELECT last_name, job_id, salary,
DECODE(job_id, 'IT_PROG', 1.10*salary, 'ST_CLERK', 1.15*salary,
'SA_REP', 1.20*salary, salary) REVISED_SALARY FROM employees;
Output:
LAST_NAME
-----------------De Haan
Hunold
Markle
Hall

JOB_ID
----------AD_VP
IT_PROG
ST_CLERK
SA_REP

SALARY
-----------17000
9000
2200
9000

REVISED_SALARY
-------------------------17000
9900
2530
10800

Sql> SELECT last_name, salary, DECODE (TRUNC(salary/2000, 0),


0, 0.00,
26 | P a g e

1, 0.09,
2, 0.20,
3, 0.30,
4, 0.40,
5, 0.42,
6, 0.44, 0.45) TAX_RATE FROM employees WHERE department_id = 80;
Output:
LAST_NAME
-----------------Russell
Partners
Errazuriz
Cambrault

SALARY
-----------14000
13500
12000
11000

TAX_RATE
---------------45
-44
-44
-42

Summary:
Sql> SELECT last_name, TO_CHAR(hire_date, 'fmDD Month YYYY')
AS HIREDATE FROM employees;
Sql> SELECT TO_CHAR(salary, '$99,999.00') SALARY FROM employees
WHERE last_name = 'Ernst';
Sql> SELECT last_name, TO_CHAR(hire_date, 'DD-Mon-YYYY') FROM employees
WHERE hire_date < TO_DATE('01-Jan-90','DD-Mon-RR');
Sql> SELECT last_name, UPPER (CONCAT (SUBSTR (LAST_NAME, 1, 8), '_US'))
FROM employees WHERE department_id = 60;
Sql> SELECT last_name, salary, NVL (commission_pct, 0),
(salary*12) + (salary*12*NVL (commission_pct, 0)) AN_SAL FROM employees;
Sql> SELECT last_name, salary, commission_pct,
NVL2 (commission_pct, 'SAL+COMM', 'SAL') income
FROM employees WHERE department_id IN (50, 80);
Sql> SELECT first_name, LENGTH(first_name) "expr1",
last_name, LENGTH(last_name) "expr2",
NULLIF(LENGTH(first_name), LENGTH(last_name)) result FROM employees;
Sql> SELECT last_name, employee_id, COALESCE (TO_CHAR (commission_pct),
TO_CHAR (manager_id), 'No commission and no manager') FROM employees;
Sql> SELECT last_name, job_id, salary, CASE job_id WHEN 'IT_PROG' THEN 1.10*salary
WHEN 'ST_CLERK' THEN 1.15*salary WHEN 'SA_REP' THEN 1.20*salary
ELSE salary END "REVISED_SALARY" FROM employees;
Sql> SELECT last_name, job_id, salary,
DECODE(job_id, 'IT_PROG', 1.10*salary, 'ST_CLERK', 1.15*salary,
'SA_REP', 1.20*salary, salary) REVISED_SALARY FROM employees;
Sql> SELECT last_name, salary, DECODE (TRUNC(salary/2000, 0),
0, 0.00,
1, 0.09,
2, 0.20,
3, 0.30,
4, 0.40,
5, 0.42,
6, 0.44, 0.45) TAX_RATE FROM employees WHERE department_id = 80;
27 | P a g e

Chapter # 5: Reporting Aggregated Data Using the Group


Functions
Topics:
5.1: Group functions:
Types and syntax
Use AVG, SUM, MIN, MAX, COUNT
Use DISTINCT keyword within group functions
NULL values in a group function
Types of Group Functions
AVG
COUNT
MAX
MIN
STDDEV
SUM
VARIANCE
Using the AVG and SUM Functions
Sql> SELECT AVG(salary), MAX(salary),
MIN(salary), SUM(salary) FROM employees WHERE job_id LIKE '%REP%';
Output:
AVG (SALARY)
--------------------8272.72727

MAX (SALARY)
--------------------11500

MIN (SALARY)
-------------------6000

SUM (SALARY)
--------------------273000

Using the MIN and MAX Functions


Sql> SELECT MIN(hire_date), MAX(hire_date) FROM employees;
Output:
MIN (HIRE_ DATE)
-------------------------

MAX(HIRE_DATE)
-------------------------28 | P a g e

13-JAN-01

21-APR-08

Using the COUNT Function


Sql> SELECT COUNT(*) FROM employees WHERE department_id = 50;
Output:
COUNT (*)
-------------45
Sql> SELECT COUNT (commission_pct) FROM employees WHERE department_id = 80;
Output:
COUNT (COMMISSION_PCT)
----------------------------------------34
Using the DISTINCT Keyword
COUNT (DISTINCT expr) returns the number of distinct non-null values of expr.
To display the number of distinct department values in the EMPLOYEES table:
Sql> SELECT COUNT(DISTINCT department_id) FROM employees;
Output:
COUNT (DISTINCTDEPARTMENT_ID)
----------------------------------------------------11
Group Functions and Null Values
Group functions ignore null values in the column
Sql> SELECT AVG(commission_pct) FROM employees;
Output:
AVG (COMMISSION_PCT)
------------------------------------0.222857143
The NVL function forces group functions to include null values:
Sql> SELECT AVG(NVL(commission_pct, 0)) FROM employees;
Output:
AVG (NVL (COMMISSION_PCT, 0))
-----------------------------------------------29 | P a g e

0.072897196
5.2: Grouping rows:
GROUP BY clause
HAVING clause
Using the GROUP BY Clause
All columns in the SELECT list that are not in group functions must be in the GROUP BY clause.
You can divide rows in a table into smaller groups by using the GROUP BY clause.
Sql> SELECT department_id, AVG(salary) FROM employees
GROUP BY department_id;
Output:
DEPARTMENT_ID
------------------------100
30
(null)
20

AVG (SALARY)
---------------------8601.33333
4150
7000
9500

The GROUP BY column does not have to be in the SELECT list.


Sql> SELECT AVG(salary) FROM employees
GROUP BY department_id;
Output:
AVG (SALARY)
--------------------8601.33333
4150
7000
Using the GROUP BY Clause on Multiple Columns
Sql> SELECT department_id, job_id, SUM(salary) FROM employees
WHERE department_id > 40 GROUP BY department_id, job_id ORDER BY department_id;
Output:
DEPARTMENT_ID
------------------------50
50
50
60

JOB_ID
----------SH_CLERK
ST_CLERK
ST_MAN
IT_PROG

SUM (SALARY)
--------------------64300
55700
36400
28800
30 | P a g e

Illegal Queries Using Group Functions


Sql> SELECT department_id, COUNT(last_name) FROM employees;
Output:

A GROUP BY clause must be added to count the last


names for each department_id.
Sql> SELECT department_id, job_id, COUNT(last_name) FROM employees
GROUP BY department_id;
Output:

Either add job_id in the GROUP BY or remove the job_id


column from the SELECT list.

You cannot use the WHERE clause to restrict groups.


You use the HAVING clause to restrict groups.
You cannot use group functions in the WHERE clause.

Sql> SELECT department_id, AVG (salary) FROM employees


WHERE AVG (salary) > 8000 GROUP BY department_id;
Output:

Cannot use the WHERE clause to


restrict group.
Restricting Group Results with the HAVING Clause
When you use the HAVING clause, the Oracle server restricts groups as follows:
1. Rows are grouped.
2. The group function is applied.
3. Groups matching the HAVING clause are displayed.
31 | P a g e

Sql> SELECT department_id, MAX(salary) FROM employees


GROUP BY department_id HAVING MAX(salary)>10000 ;
Output:
DEPARTMENT_ID
MAX (SALARY)
--------------------------------------------100
12008
30
11000
20
13000
Sql> SELECT job_id, SUM(salary) PAYROLL FROM employees
WHERE job_id NOT LIKE '%REP%' GROUP BY job_id
HAVING SUM(salary) > 13000 ORDER BY SUM(salary);
Output:
JOB_ID
----------PU_CLERK
AD_PRES
IT_PROG
AD_VP

PAYROLL
-------------13900
24000
28800
34000

5.3: Nesting Group Functions


Sql> SELECT MAX(AVG(salary)) FROM employees
GROUP BY department_id;
Output:
MAX (AVG (SALARY))
-----------------------------19333.3333
Summary:
Sql> SELECT AVG(salary), MAX(salary), MIN(salary), SUM(salary) FROM employees
WHERE job_id LIKE '%REP%';
Sql> SELECT MIN(hire_date), MAX(hire_date) FROM employees;
Sql> SELECT COUNT(*) FROM employees WHERE department_id = 50;
Sql> SELECT COUNT (commission_pct) FROM employees WHERE department_id = 80;
Sql> SELECT COUNT(DISTINCT department_id) FROM employees;
Sql> SELECT AVG(commission_pct) FROM employees;
Sql> SELECT AVG(NVL(commission_pct, 0)) FROM employees;
Sql> SELECT department_id, AVG(salary) FROM employees GROUP BY department_id;
Sql> SELECT AVG(salary) FROM employees GROUP BY department_id;
Sql> SELECT department_id, job_id, SUM(salary) FROM employees
WHERE department_id > 40 GROUP BY department_id, job_id ORDER BY department_id;
Sql> SELECT department_id, COUNT(last_name) FROM employees; (ERROR)
Sql> SELECT department_id, job_id, COUNT(last_name) FROM employees
GROUP BY department_id; (ERROR)
32 | P a g e

Sql> SELECT department_id, AVG (salary) FROM employees WHERE AVG (salary) > 8000
GROUP BY department_id; (ERROR)
Sql> SELECT department_id, MAX(salary) FROM employees
GROUP BY department_id HAVING MAX(salary)>10000 ;
Sql> SELECT job_id, SUM(salary) PAYROLL FROM employees
WHERE job_id NOT LIKE '%REP%' GROUP BY job_id HAVING SUM(salary) > 13000
ORDER BY SUM(salary);
Sql> SELECT MAX(AVG(salary)) FROM employees
GROUP BY department_id;

Chapter # 6: Displaying Data from Multiple Tables


Topics:
6.1: Types of JOINS and its syntax:
Joins that are compliant with the SQL: 1999 standard include the following:
Natural joins:
--NATURAL JOIN clause
--USING clause
--ON clause
OUTER joins:
--LEFT OUTER JOIN
--RIGHT OUTER JOIN
--FULL OUTER JOIN
Cross joins
Qualifying Ambiguous Column Names:
Use table prefixes to qualify column names that are in multiple tables.
Use table prefixes to improve performance.
Instead of full table name prefixes, use table aliases.
Table alias gives a table a shorter name:
--Keeps SQL code smaller, uses less memory
Use column aliases to distinguish columns that have identical names, but reside in
different tables.
6.2: Natural join:
--USING clause
--ON clause
Creating Natural Joins:
The NATURAL JOIN clause is based on all columns in the two tables that have the same name.
It selects rows from the two tables that have equal values in all matched columns.
If the columns having the same names have different data types, an error is returned.

33 | P a g e

Sql> SELECT department_id, department_name, location_id, city


FROM departments NATURAL JOIN locations;
Output:
DEPARTMENT_ID
------------------------60
50
10

DEPARTMENT_NAME
------------------------------IT
Shipping
Administration

LOCATION_ID
-------------------1400
1500
1700

CITY
---------Southlake
South San Francisco
Seattle

Creating Joins with the USING Clause:

If several columns have the same names but the data types do not match, use the
USING clause to specify the columns for the equijoin.
Use the USING clause to match only one column when more than one column matches.
The NATURAL JOIN and USING clauses are mutually exclusive.

Sql> SELECT employee_id, last_name, location_id, department_id


FROM employees JOIN departments USING (department_id);
Output:
EMPLOYEE_ID
--------------------200
201
202
114

LAST_NAME
------------------Whalen
Hartstein
Fay
Raphaely

LOCATION_ID
-------------------1700
1800
1800
1700

DEPARTMENT_ID
------------------------10
20
20
30

Using Table Aliases with the USING Clause:


Do not qualify a column that is used in the USING clause.
If the same column is used elsewhere in the SQL statement, do not alias it.
Sql> SELECT l.city, d.department_name FROM locations l JOIN departments d
USING (location_id) WHERE d.location_id = 1400;
Output:

34 | P a g e

Creating Joins with the ON Clause:


The join condition for the natural join is basically an equijoin of all columns with the same
name.
Use the ON clause to specify arbitrary conditions or specify columns to join.
The join condition is separated from other search conditions.
The ON clause makes code easy to understand.

Sql> SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id


FROM employees e JOIN departments d ON (e.department_id = d.department_id);
Output:
EMPLOYEE_ID
--------------------200
201
202
114

LAST_NAME
-----------------Whalen
Hartstein
Fay
Raphaely

DEPARTMENT_ID DEPARTMENT_ID_1 LOCATION_ID


-------------------------- ----------------------------- -------------------10
10
1700
20
20
1800
20
20
1800
30
30
1700

Creating Three-Way Joins with the ON Clause:


Sql> SELECT employee_id, city, department_name FROM employees e JOIN departments d
ON d.department_id = e.department_id JOIN locations l ON d.location_id = l.location_id;
Output:
EMPLOYEE_ID
--------------------100
101
103
104

CITY
----------------Seattle
Seattle
Southlake
Southlake

DEPARTMENT_NAME
------------------------------Executive
Executive
IT
IT

Applying Additional Conditions to a Join:


Use the AND clause or the WHERE clause to apply additional conditions:
Sql> SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id
FROM employees e JOIN departments d ON (e.department_id = d.department_id)
AND e.manager_id = 149;
Output:
EMPLOYEE_ID
--------------------174

LAST_NAME
-----------------Abel

DEPARTMENT_ID
------------------------80

DEPARTMENT_ID
------------------------80

LOCATION_ID
-------------------2500
35 | P a g e

175
179
177
176

Hutton
Johnson
Livingston
Taylor

80
80
80
80

80
80
80
80

2500
2500
2500
2500

Sql> SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id


FROM employees e JOIN departments d ON (e.department_id = d.department_id)
WHERE e.manager_id = 149;

Output:
EMPLOYEE_ID
--------------------174
175
179
177
176

LAST_NAME
-----------------Abel
Hutton
Johnson
Livingston
Taylor

DEPARTMENT_ID
------------------------80
80
80
80
80

DEPARTMENT_ID
------------------------80
80
80
80
80

LOCATION_ID
-------------------2500
2500
2500
2500
2500

6.3: Self-join
Self-Joins Using the ON Clause:
Sql> SELECT worker.last_name emp, manager.last_name mgr FROM employees worker JOIN
employees manager ON (worker.manager_id = manager.employee_id);
Output:
EMP
--------------Banda
Ande
Sarchand
Olson

MGR
--------------Errazuriz
Errazuriz
Fripp
Fripp

6.4: Non-equijoins:
Sql> SELECT e.last_name, e.salary, j.grade_level FROM employees e JOIN job_grades j
ON e.salary BETWEEN j.lowest_sal AND j.highest_sal;
Output:
LAST_NAME
------------------Rogers
Feeney
Fay

SALARY
-----------2900
3000
6000

GRADE_LEVEL
---------------------A
B
C
36 | P a g e

6.5: OUTER join:


LEFT OUTER join
RIGHT OUTER join
FULL OUTER join
--INNER versus OUTER Joins:
In SQL:1999, the join of two tables returning only matched rows is called an INNER join.
A join between two tables that returns the results of the INNER join as well as the
unmatched rows from the left (or right) table is called a left (or right) OUTER join.
A join between two tables that returns the results of an INNER join as well as the results
of a left and right join is a full OUTER join.
LEFT OUTER JOIN:
Sql> SELECT e.last_name, e.department_id, d.department_name FROM employees e
LEFT OUTER JOIN departments d ON (e.department_id = d.department_id);
Output:
LAST_NAME
-----------------Urman
Sciarra
Higgins
Grant

DEPARTMENT_ID
-------------------------100
100
110

DEPARTMENT_NAME
------------------------------Finance
Finance
Accounting

RIGHT OUTER JOIN:


Sql> SELECT e.last_name, d.department_id, d.department_name FROM employees e
RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);
Output:
LAST_NAME
-----------------Gietz
Higgins

DEPARTMENT_ID
------------------------110
110
130
140

DEPARTMENT_NAME
------------------------------Accounting
Accounting
Corporate Tax
Control and Credit

FULL OUTER JOIN:


Sql> SELECT e.last_name, d.department_id, d.department_name FROM employees e
FULL OUTER JOIN departments d ON (e.department_id = d.department_id);
Output:
LAST_NAME
-----------------Ozer

DEPARTMENT_ID
------------------------80

DEPARTMENT_NAME
------------------------------Sales
37 | P a g e

Grant
Popp
Raphaely

(null)
100
30

(null)
Finance
Purchasing

6.6: Cartesian product:


Cross join
Cartesian Products:
A Cartesian product is formed when:
--A join condition is omitted
--A join condition is invalid
--All rows in the first table are joined to all rows in the second table
To avoid a Cartesian product, always include a valid join condition.
Creating Cross Join:
The CROSS JOIN clause produces the cross-product of two tables.
This is also called a Cartesian product between the two tables.
Sql> SELECT last_name, department_name FROM employees CROSS JOIN departments;
Output:
LAST_NAME
-----------------Vargas
Vishney
Sciarra
Seo
2889 rows selected.

DEPARTMENT_NAME
------------------------------Payroll
Payroll
Recruiting
Recruiting

Summary:
Sql> SELECT department_id, department_name, location_id, city
FROM departments NATURAL JOIN locations;
Sql> SELECT employee_id, last_name, location_id, department_id
FROM employees JOIN departments USING (department_id);
Sql> SELECT l.city, d.department_name FROM locations l JOIN departments d
USING (location_id) WHERE d.location_id = 1400; (ERROR)
Sql> SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id
FROM employees e JOIN departments d ON (e.department_id = d.department_id);
Sql> SELECT employee_id, city, department_name FROM employees e JOIN departments d
ON d.department_id = e.department_id JOIN locations l ON d.location_id = l.location_id;
Sql> SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id
FROM employees e JOIN departments d ON (e.department_id = d.department_id)
AND e.manager_id = 149;
Sql> SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id
FROM employees e JOIN departments d ON (e.department_id = d.department_id)
WHERE e.manager_id = 149;
Sql> SELECT worker.last_name emp, manager.last_name mgr FROM employees worker JOIN
employees manager ON (worker.manager_id = manager.employee_id);
Sql> SELECT e.last_name, e.salary, j.grade_level FROM employees e JOIN job_grades j
38 | P a g e

ON e.salary BETWEEN j.lowest_sal AND j.highest_sal;


Sql> SELECT e.last_name, e.department_id, d.department_name FROM employees e
LEFT OUTER JOIN departments d ON (e.department_id = d.department_id);
Sql> SELECT e.last_name, d.department_id, d.department_name FROM employees e
RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id);
Sql> SELECT e.last_name, d.department_id, d.department_name FROM employees e
FULL OUTER JOIN departments d ON (e.department_id = d.department_id);
Sql> SELECT last_name, department_name FROM employees CROSS JOIN departments;

Chapter # 7: Using Sub-queries to Solve Queries


Topics:
7.1: Sub-query: Types, syntax, and guidelines:
Syntax:
SELECT select_list FROM table
WHERE expr operator (SELECT select_list FROM table);

The sub-query (inner query) executes before the main query (outer query).
The result of the sub-query is used by the main query.

Sql> SELECT last_name, salary FROM employees


WHERE salary > (SELECT salary FROM employees WHERE last_name = 'Abel');
Output:
LAST_NAME
-----------------Hartstein
Higgins
King
Kochhar

SALARY
-----------13000
12008
24000
17000

Guidelines for Using Sub-queries:


Enclose sub-queries in parentheses.
Place sub-queries on the right side of the comparison condition for readability (However,
the sub-query can appear on either side of the comparison operator.).
Use single-row operators with single-row sub-queries and multiple-row operators with
multiple-row sub-queries.
Types of Sub-queries:
Single-row sub-query
39 | P a g e

Main Query

Returns

Sub-Query

ST_Clerk

Multiple-row sub-query

Main Query
Returns

ST_CLERK
SA_MAN

7.2: Single-row sub-queries:


Group functions in a sub-query
HAVING clause with sub-queries
Single-Row Sub-queries:
Return only one row
Use single-row comparison operators
Operator

Meaning

=
>

Equal to
Greater than
Greater than or equal to
Less than
Less than or equal to
Not equal to

>=
<
<=
<>

Sql> SELECT last_name, job_id, salary FROM employees


WHERE job_id = (SELECT job_id FROM employees WHERE last_name = Taylor)
AND salary > (SELECT salary FROM employees WHERE last_name = Taylor);
Output:

Using Group Functions in a Sub-query:


Sql> SELECT last_name, job_id, salary FROM employees
WHERE salary = (SELECT MIN(salary) FROM employees);
Output:
40 | P a g e

LAST_NAME
-----------------Olson

JOB_ID
----------ST_CLERK

SALARY
-----------2100

The HAVING Clause with Sub-queries:


The Oracle server executes the sub-queries first.
The Oracle server returns results into the HAVING clause of the main query.
Sql> SELECT department_id, MIN(salary) FROM employees GROUP BY department_id
HAVING MIN(salary) > (SELECT MIN(salary) FROM employees WHERE department_id = 50);

Output:
DEPARTMENT_ID
------------------------100
30
(null)

MIN (SALARY)
-------------------6900
2500
7000

Sql> SELECT employee_id, last_name FROM employees


WHERE salary = (SELECT MIN(salary) FROM employees GROUP BY department_id);
Output:

Single-row operator with


multiple-row sub-query.
Sql> SELECT last_name, job_id FROM employees
WHERE job_id = (SELECT job_id FROM employees WHERE last_name = 'Haas');
Output:
no rows selected (Subquery returns no rows because there is no
employee named Haas.)
41 | P a g e

7.3: Multiple-row sub-queries:


Use ALL or ANY operator
Multiple-Row Sub-queries:
Return more than one row
Use multiple-row comparison operators
Operato
r
IN
ANY
ALL

Meaning
Equal to any member in the list
Must be preceded by = , !=, >, <, <=, >=. Compares a value to each value in a list
or returned by a query. Evaluates to FALSE if the query returns no rows.
Must be preceded by = , !=, >, <, <=, >=. Compares a value to every value in a list
or returned by a query. Evaluates to TRUE if the query returns no rows.

Using the ANY Operator in Multiple-Row Sub-queries:


Sql> SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary < ANY (SELECT salary FROM employees
WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
Output:
EMPLOYEE_ID
--------------------184
200
124
202

LAST_NAME
-----------------Sarchand
Whalen
Mourgos
Fay

JOB_ID
----------SH_CLERK
AD_ASST
ST_MAN
MK_REP

SALARY
-----------4200
4400
5800
6000

Using the ALL Operator in Multiple-Row Sub-queries:


Sql> SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary < ALL (SELECT salary FROM employees
WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
Output:
EMPLOYEE_ID
--------------------185
192
193

LAST_NAME
-----------------Bull
Bell
Everett

JOB_ID
----------SH_CLERK
SH_CLERK
SH_CLERK

SALARY
----------4100
4000
3900

7.4: Null values in a sub-query:


Sql> SELECT emp.last_name FROM employees emp WHERE emp.employee_id NOT IN
42 | P a g e

(SELECT mgr.manager_id FROM employees mgr);


Output:
no rows selected

Summary:
Sql> SELECT last_name, salary FROM employees
WHERE salary > (SELECT salary FROM employees WHERE last_name = 'Abel');
Sql> SELECT last_name, job_id, salary FROM employees
WHERE job_id = (SELECT job_id FROM employees WHERE last_name = Taylor)
AND salary > (SELECT salary FROM employees WHERE last_name = Taylor);
Sql> SELECT last_name, job_id, salary FROM employees
WHERE salary = (SELECT MIN (salary) FROM employees);
Sql> SELECT department_id, MIN (salary) FROM employees GROUP BY department_id
HAVING MIN (salary) > (SELECT MIN (salary) FROM employees WHERE department_id = 50);
Sql> SELECT employee_id, last_name FROM employees WHERE salary =
(SELECT MIN(salary) FROM employees GROUP BY department_id); (ERROR)
Sql> SELECT last_name, job_id FROM employees
WHERE job_id = (SELECT job_id FROM employees WHERE last_name = 'Haas');
Sql> SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary < ANY (SELECT salary FROM employees
WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
Sql> SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary < ALL (SELECT salary FROM employees
WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG';
Sql> SELECT emp.last_name FROM employees emp WHERE emp.employee_id NOT IN
(SELECT mgr.manager_id FROM employees mgr);

43 | P a g e

Chapter # 8: Using the Set Operators


Topics:
8.1: Set Operators: Types and guidelines:
UNION/UNION ALL
INTERSECT
MINUS
Set Operator Guidelines:
The expressions in the SELECT lists must match in number.
The data type of each column in the second query must match the data type of its
corresponding column in the first query.
Parentheses can be used to alter the sequence of execution.
ORDER BY clause can appear only at the very end of the statement.
The Oracle Server and Set Operators:
Duplicate rows are automatically eliminated except in UNION ALL.
Column names from the first query appear in the result.
The output is sorted in ascending order by default except in UNION ALL.
8.2: Tables used in this lesson:
The tables used in this lesson are:
EMPLOYEES: Provides details regarding all current employees.
JOB_HISTORY: Records the details of the start date and end date of the former job, and
the job identification number and department when an employee switches jobs.
8.3: UNION and UNION ALL operator:
44 | P a g e

UNION Operator:
The UNION operator returns rows from both queries after eliminating duplications.

Display the current and previous job details of all employees.


Display each employee only once.

Sql> SELECT employee_id, job_id FROM employees


UNION SELECT employee_id, job_id FROM job_history;
Output:
EMPLOYEE_ID
--------------------100
101
101
101

JOB_ID
----------AD_PRES
AC_ACCOUNT
AC_MGR
AD_VP

UNION ALL Operators:


The UNION ALL operator returns rows from both queries, including all duplications.

Display the current and previous departments of all employees.

Sql> SELECT employee_id, job_id, department_id FROM employees UNION ALL


SELECT employee_id, job_id, department_id FROM job_history ORDER BY employee_id;
Output:
EMPLOYEE_ID
--------------------100
101
101
102

JOB_ID
----------AD_PRES
AD_VP
AC_ACCOUNT
IT_PROG

DEPARTMENT_ID
------------------------90
90
110
60

8.4: INTERSECT operator:


The INTERSECT operator returns rows that are common to both queries.

Display the employee IDs and job IDs of those employees who currently have a job title
that is the same as their previous one (that is,they changed jobs but have now gone
back to doing the same job they did previously).

Sql> SELECT employee_id, job_id FROM employees


INTERSECT SELECT employee_id, job_id FROM job_history;
Output:
EMPLOYEE_ID

JOB_ID
45 | P a g e

--------------------176
200

----------SA_REP
AD_ASST

8.5: MINUS operator:


The MINUS operator returns all the distinct rows selected by the first query, but not
present in the second query result set.

Display the employee IDs of those employees who have not changed their jobs even
once.

Sql> SELECT employee_id FROM employees MINUS SELECT employee_id FROM


job_history;
Output:
EMPLOYEE_ID
--------------------100
103
104
8.6: Matching the SELECT statements:
Using the UNION operator, display the location ID, department name, and the state
where it is located.
You must match the data type (using the TO_CHAR function or any other conversion
functions) when columns do not exist in one or the other table.
Sql> SELECT location_id, department_name "Department", TO_CHAR(NULL) "Warehouse
location" FROM departments
UNION SELECT location_id, TO_CHAR(NULL) "Department", state_province FROM locations;
Output:
LOCATION_ID
-------------------1000
1100
1200

Department
---------------

Warehouse location
-------------------------Tokyo Prefecture

Using the UNION operator, display the employee ID, job ID, and salary of all employees.

Sql> SELECT employee_id, job_id,salary FROM employees


UNION SELECT employee_id, job_id,0 FROM job_history;
Output:
EMPLOYEE_ID
--------------------100
101
101

JOB_ID
----------AD_PRES
AC_ACCOUNT
AC_MGR

SALARY
----------24000
0
0
46 | P a g e

101

AD_VP

17000

8.7: Using the ORDER BY clause in set operations:


The ORDER BY clause can appear only once at the end of the compound query.
Component queries cannot have individual ORDER BY clauses.
ORDER BY clause recognizes only the columns of the first SELECT query.
By default, the first column of the first SELECT query is used to sort the output in an
ascending order.

Summary:
Sql> SELECT employee_id, job_id FROM employees
UNION SELECT employee_id, job_id FROM job_history;
Sql> SELECT employee_id, job_id, department_id FROM employees UNION ALL
SELECT employee_id, job_id, department_id FROM job_history ORDER BY employee_id;
Sql> SELECT employee_id, job_id FROM employees
INTERSECT SELECT employee_id, job_id FROM job_history;
Sql> SELECT employee_id FROM employees MINUS SELECT employee_id FROM
job_history;
Sql> SELECT location_id, department_name "Department", TO_CHAR(NULL) "Warehouse
location" FROM departments
UNION SELECT location_id, TO_CHAR(NULL) "Department", state_province FROM locations;
Sql> SELECT employee_id, job_id,salary FROM employees
UNION SELECT employee_id, job_id,0 FROM job_history;

47 | P a g e

Chapter # 9: Manipulating Data


Topics:
9.1: Adding new rows in a table:
INSERT statement
Data Manipulation Language:
A DML statement is executed when you:
-- Add new rows to a table
-- Modify existing rows in a table
-- Remove existing rows from a table
A transaction consists of a collection of DML statements that form a logical unit of work.
Inserting New Rows:
Insert a new row containing values for each column.
List values in the default order of the columns in the table.
Optionally, list the columns in the INSERT clause.
Enclose character and date values within single quotation marks.
Sql> INSERT INTO departments (department_id, department_name, manager_id, location_id)
VALUES (280, 'Public Relations', 100, 1700);
Output:
1 row created.
DEPARTMENT_ID

DEPARTMENT_NAME

MANAGER_ID

LOCATION_ID
48 | P a g e

------------------------280

------------------------------Public Relations

-------------------100

------------------1700

Inserting Rows with Null Values:


Implicit method: Omit the column from the column list.
Sql> INSERT INTO departments (department_id, department_name)
VALUES (290, 'Purchasing');
Output:
1 row created.
DEPARTMENT_ID
------------------------290

DEPARTMENT_NAME
------------------------------Purchasing

MANAGER_ID
--------------------

LOCATION_ID
-------------------

Explicit method: Specify the NULL keyword in the VALUES clause.

Sql> INSERT INTO departments VALUES (300, 'Finance', NULL, NULL);

Output:
1 row created.
DEPARTMENT_ID
------------------------300

DEPARTMENT_NAME
------------------------------Finance

MANAGER_ID
-------------------(null)

LOCATION_ID
------------------(null)

Inserting Special Values:


Sql> INSERT INTO employees (employee_id, first_name, last_name, email, phone_number,
hire_date, job_id, salary, commission_pct, manager_id, department_id) VALUES (99,
'Louis', 'Popp', 'LPOPPP', '515.124.4567', SYSDATE, 'AC_ACCOUNT', 6900, NULL, 205, 110);
Output:
1 row created.
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
--------------------- ------------------- ----------------- --------- -------------------------- ----------------- ---------- ----------- --------------------------- -------------------------------------------99
Louis
Popp
LPOPPP 515.124.4567
01-JUL-11 AC_ACCOUNT 6900
(null)
205
110

Inserting Specific Date and Time Values:


Add a new employee.
Sql> INSERT INTO employees VALUES (98, 'Den', 'Raphealy', 'DRAPHEALL', '515.127.4561',
TO_DATE('FEB 3, 1999', 'MON DD, YYYY'), 'SA_REP', 11000, 0.2, 100, 60);
Verify your addition.
49 | P a g e

Output:
1 row created.

Creating a Script:
Use & substitution in a SQL statement to prompt for values.
& is a placeholder for the variable value.
Sql> INSERT INTO departments (department_id, department_name, location_id)
VALUES (&department_id, '&department_name',&location);
Output:
1 row created.
Enter value for department_id: 310
Enter value for department_name: Finance
Enter value for location: 2500
old 3: VALUES (&department_id, '&department_name',&location)
new 3: VALUES (310, 'Finance',2500)
DEPARTMENT_ID
DEPARTMENT_NAME
LOCATION_ID
-------------------------------------------------------------------------310
Finance
2500
Copying Rows from Another Table:
Write your INSERT statement with a subquery:
Do not use the VALUES clause.
Match the number of columns in the INSERT clause to those in the subquery.
Inserts all the rows returned by the subquery in the table, sales_reps.
Sql> INSERT INTO sales_reps(id, name, salary, commission_pct) SELECT employee_id,
last_name, salary, commission_pct FROM employees WHERE job_id LIKE '%REP%';
Output:
34 rows created.
ID
NAME
-----------------202
Fay
203
Mavris
204
Baer
98
Raphealy

SALARY
-----------6000
6500
10000
11000

COMMISSION_PCT
--------------------------(null)
(null)
(null)
0

9.2: Changing data in a table:


UPDATE statement

Modify existing values in a table with the UPDATE statement:


Update more than one row at a time (if required).

50 | P a g e

Updating Rows in a Table:

Values for a specific row or rows are modified if you specify the WHERE clause:

Sql> UPDATE employees SET department_id = 50 WHERE employee_id = 113;


Output:
1 row updated.
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
--------------------- ------------------- ----------------- --------- -------------------------- ----------------- ---------- ----------- --------------------------- ---------------------- -----------------------113
Luis
Popp
LPOPP 515.124.4567
07-DEC-07 FI_ACCOUNT 6900
(null)
108
50

Values for all the rows in the table are modified if you omit the WHERE clause:

Sql> UPDATE copy_emp SET department_id = 110;


Output:
109 rows updated.
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
--------------------- -------------------- ------------------ --------- -------------------------- ----------------- ----------- ------------ ---------------------------- -------------------- -----------------------196
Alana
Walsh
AWALSH 650.507.9811
24-APR-06 SH_CLERK 3100
124
110
197
Kevin
Feeney
KFEENEY 650.507.9822
23-MAY-06 SH_CLERK 3000
124
110

Specify SET column_name= NULL to update a column value to NULL.

Updating Two Columns with a Sub-query:


Update employee 113s job and salary to match those of employee 205.
Sql> UPDATE employees SET job_id = (SELECT job_id FROM employees
WHERE employee_id = 205),
salary = (SELECT salary FROM employees WHERE employee_id = 205)
WHERE employee_id = 113;
Output:
1 row updated.
Updating Rows Based on Another Table:
Use the sub-queries in the UPDATE statements to update row values in a table based
on values from another table.
Sql> UPDATE copy_emp SET department_id = (SELECT department_id FROM employees
WHERE employee_id = 100)
WHERE job_id = (SELECT job_id FROM employees WHERE employee_id = 200);
Output:
1 row updated.
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
-------------------- ------------------- ------------------ ---------- -------------------------- ----------------- ----------- ----------- ---------------------------- ---------------------------------------------

51 | P a g e

200

Jennifer

Whalen JWHALEN

515.123.4444

17-SEP-03 AD_ASST 4400

(null)

101

9.3: Removing rows from a table:


DELETE statement
TRUNCATE statement
--You can remove existing rows from a table by using the DELETE statement:
Deleting Rows from a Table:
Specific rows are deleted if you specify the WHERE clause:
Sql> DELETE FROM dept4 WHERE department_name = Finance';
Output:
3 rows deleted.

All rows in the table are deleted if you omit the WHERE clause:

Sql> DELETE FROM copy_emp;


Output:
109 rows deleted.
Deleting Rows Based on Another Table:
Use the sub-queries in the DELETE statements to remove rows from a table based on
values from another table.
Sql> DELETE FROM employees WHERE department_id = (SELECT department_id FROM
departments WHERE department_name LIKE '%Public%');
Output:
1 row deleted.
TRUNCATE Statement:
Removes all rows from a table, leaving the table empty and the table structure intact
Is a data definition language (DDL) statement rather than a DML statement; cannot
easily be undone.
Sql> TRUNCATE TABLE copy_emp;
Output:
Table truncated.
9.4: Database transactions control using COMMIT, ROLLBACK and SAVEPOINT:
A database transaction consists of one of the following:
52 | P a g e

90

DML statements that constitute one consistent change to the data.


One DDL statement.
One data control language (DCL) statement.

Database Transactions: Start and End:


Begin when the first DML SQL statement is executed.
End with one of the following events:
-- A COMMIT or ROLLBACK statement is issued.
-- A DDL or DCL statement executes (automatic commit).
-- The user exits SQL Developer or SQL*Plus.
-- The system crashes.
Advantages of COMMIT and ROLLBACK Statements:
With COMMIT and ROLLBACK statements, you can:
Ensure data consistency
Preview data changes before making changes permanent
Group logically-related operations

Explicit Transaction Control Statements:

Rolling Back Changes to a Marker:


Create a marker in the current transaction by using the SAVEPOINT statement.
Roll back to that marker by using the ROLLBACK TO SAVEPOINT statement.
Sql> UPDATE... SAVEPOINT update_done;
53 | P a g e

Sql> INSERT... ROLLBACK TO update_done;


Implicit Transaction Processing:
An automatic commit occurs in the following circumstances:
--A DDL statement is issued
--A DCL statement is issued
--Normal exit from SQL Developer or SQL*Plus, without explicitly issuing
COMMIT or ROLLBACK statements
An automatic rollback occurs when there is an abnormal termination of SQL Developer
or SQL*Plus or a system failure.
State of the Data Before COMMIT or ROLLBACK:
The previous state of the data can be recovered.
The current user can review the results of the DML operations by using the SELECT
statement.
Other users cannot view the results of the DML statements issued by the current user.
The affected rows are locked; other users cannot change the data in the affected rows.
State of the Data after COMMIT:
Data changes are saved in the database.
The previous state of the data is overwritten.
All users can view the results.
Locks on the affected rows are released; those rows are available for other users to
manipulate.
All savepoints are erased.
Committing Data:
Makes the changes:
Sql> DELETE FROM employees WHERE employee_id = 99999;
Output:
0 row deleted.
Sql> INSERT INTO departments VALUES (290, 'Corporate Tax', NULL, 1700);

Output:
1 row created.
DEPARTMENT_ID
------------------------3000

DEPARTMENT_NAME
------------------------------Corporate Tax

MANAGER_ID
-------------------(null)

LOCATION_ID
------------------1700

Commit the changes:

Sql> COMMIT;
Output:
54 | P a g e

Commit Complete.
State of the Data After ROLLBACK:
Discard all pending changes by using the ROLLBACK statement:
Data changes are undone.
Previous state of the data is restored.
Locks on the affected rows are released.
Sql> DELETE FROM copy_emp1;
Output:
109 rows deleted.
Sql> ROLLBACK;
Output:
Rollback Complete.
Statement-Level Rollback:
If a single DML statement fails during execution, only that statement is rolled back.
The Oracle server implements an implicit savepoint.
All other changes are retained.
The user should terminate transactions explicitly by executing a COMMIT or ROLLBACK
statement.
9.5: Read consistency:
Read consistency guarantees a consistent view of the data at all times.
Changes made by one user do not conflict with the changes made by another user.
Read consistency ensures that, on the same data:
--Readers do not wait for writers
--Writers do not wait for readers
--Writers wait for writers
9.6: FOR UPDATE clause in a SELECT statement:
Locks the rows in the EMPLOYEES table where job_id is SA_REP.
Lock is released only when you issue a ROLLBACK or a COMMIT.
If the SELECT statement attempts to lock a row that is locked by another user, then the
database waits until the row is available, and then returns the results of the SELECT
statement.
Sql> SELECT employee_id, salary, commission_pct, job_id FROM employees
WHERE job_id = 'SA_REP' FOR UPDATE ORDER BY employee_id;
Output:
EMPLOYEE_ID
---------------------

SALARY
------------

COMMISSION_PCT
----------------------------

JOB_ID
----------55 | P a g e

98
150
151

11000
10000
9500

.2
.3
.25

SA_REP
SA_REP
SA_REP

FOR UPDATE Clause: Examples


You can use the FOR UPDATE clause in a SELECT statement against multiple tables.
Rows from both the EMPLOYEES and DEPARTMENTS tables are locked.
Use FOR UPDATE OF column_name to qualify the column you intend to change, then
only the rows from that specific table are locked.
Sql> SELECT e.employee_id, e.salary, e.commission_pct FROM employees e JOIN
departments d USING (department_id) WHERE job_id = 'ST_CLERK AND location_id = 1500
FOR UPDATE ORDER BY e.employee_id;
Output:
EMPLOYEE_ID
--------------------125
126
127

SALARY
-----------3200
2700
2400

COMMISSION_PCT
--------------------------(null)
(null)
(null)

Summary:
Sql> INSERT INTO departments (department_id, department_name, manager_id, location_id)
VALUES (280, 'Public Relations', 100, 1700);
Sql> INSERT INTO departments (department_id, department_name)
VALUES (290, 'Purchasing');
Sql> INSERT INTO departments VALUES (300, 'Finance', NULL, NULL);
Sql> INSERT INTO employees (employee_id, first_name, last_name, email, phone_number,
hire_date, job_id, salary, commission_pct, manager_id, department_id) VALUES (99,
'Louis', 'Popp', 'LPOPPP', '515.124.4567', SYSDATE, 'AC_ACCOUNT', 6900, NULL, 205, 110);
Sql> INSERT INTO employees VALUES (98, 'Den', 'Raphealy', 'DRAPHEALL', '515.127.4561',
TO_DATE('FEB 3, 1999', 'MON DD, YYYY'), 'SA_REP', 11000, 0.2, 100, 60);
Sql> INSERT INTO departments (department_id, department_name, location_id)
VALUES (&department_id, '&department_name',&location);
Sql> INSERT INTO sales_reps(id, name, salary, commission_pct) SELECT employee_id,
last_name, salary, commission_pct FROM employees WHERE job_id LIKE '%REP%';
Sql> UPDATE employees SET department_id = 50 WHERE employee_id = 113;
Sql> UPDATE copy_emp SET department_id = 110;
Sql> UPDATE employees SET job_id = (SELECT job_id FROM employees
WHERE employee_id = 205),
salary = (SELECT salary FROM employees WHERE employee_id = 205)
WHERE employee_id = 113;
56 | P a g e

Sql> UPDATE copy_emp SET department_id = (SELECT department_id FROM employees


WHERE employee_id = 100)
WHERE job_id = (SELECT job_id FROM employees WHERE employee_id = 200);
Sql> DELETE FROM dept4 WHERE department_name = Finance';
Sql> DELETE FROM copy_emp;
Sql> DELETE FROM employees WHERE department_id = (SELECT department_id FROM
departments WHERE department_name LIKE '%Public%');
Sql> TRUNCATE TABLE copy_emp;
Sql> DELETE FROM employees WHERE employee_id = 99999;
Sql> INSERT INTO departments VALUES (290, 'Corporate Tax', NULL, 1700);
Sql> COMMIT;
Sql> DELETE FROM copy_emp1;
Sql> ROLLBACK;
Sql> SELECT employee_id, salary, commission_pct, job_id FROM employees
WHERE job_id = 'SA_REP' FOR UPDATE ORDER BY employee_id;
Sql> SELECT e.employee_id, e.salary, e.commission_pct FROM employees e JOIN
departments d USING (department_id) WHERE job_id = 'ST_CLERK AND location_id = 1500
FOR UPDATE ORDER BY e.employee_id;

Chapter # 10: Using DDL Statements to Create and


Manage Tables
Topics:
10.1: Database objects:
Naming rules
Database Objects:
Object

Description

Table
View
Sequence
Index
Synonym

Basic unit of storage; composed of rows


Logically represents subsets of data from one or more tables
Generates numeric values
Improves the performance of some queries
Gives alternative name to an object

57 | P a g e

Naming Rules:
Table names and column names:
Must begin with a letter
Must be 130 characters long
Must contain only AZ, az, 09, _, $, and #
Must not duplicate the name of another object owned by the same user
Must not be an Oracle serverreserved word
10.2: CREATE TABLE statement:
Access another users tables
DEFAULT option
CREATE TABLE Statement:
You must have:
--CREATE TABLE privilege
--A storage area
You specify:
--Table name
--Column name, column data type, and column size
Referencing another Users Tables:
Tables belonging to other users are not in the users schema.
You should use the owners name as a prefix to those tables.
DEFAULT Option:
Specify a default value for a column during an insert.
... hire_date DATE DEFAULT SYSDATE, ...
Literal values, expressions, or SQL functions are legal values.
Another columns name or a pseudocolumn are illegal values.
The default data type must match the column data type.
Sql> CREATE TABLE hire_dates (id NUMBER(8), hire_date DATE DEFAULT SYSDATE);
Output:
Table created.
Creating Tables:
Create the table:
Sql> CREATE TABLE dept (deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13),
create_date DATE DEFAULT SYSDATE);
Output:
Table created.

Confirm table creation:


58 | P a g e

Sql> DESCRIBE dept


Output:
Name
--------------------DEPTNO
DNAME
LOC
CREATE_DATE

Null?
-------

Type
-----------NUMBER(2)
VARCHAR2(14)
VARCHAR2(13)
DATE

10.3: Data types:


Data types:
Data Type

Description

VARCHAR2(size)
CHAR(size)
NUMBER(p,s)
DATE
LONG
CLOB
RAW and LONG RAW
BLOB
BFILE
ROWID

Variable-length character data


Fixed-length character data
Variable-length numeric data
Date and time values
Variable-length character data (up to 2 GB)
Character data (up to 4 GB)
Raw binary data
Binary data (up to 4 GB)
Binary data stored in an external file (up to 4 GB)
A base-64 number system representing the unique address of a row in its table

Date time Data Types:


You can use several date time data types:
Data Type

Description

TIMESTAMP
INTERVAL YEAR TO MONTH
INTERVAL DAY TO SECOND

Date with fractional seconds


Stored as an interval of years and months
Stored as an interval of days, hours, minutes, and seconds

10.4: Overview of constraints: NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY,
CHECK constraints:
Including Constraints:
Constraints enforce rules at the table level.
Constraints prevent the deletion of a table if there are dependencies.
59 | P a g e

The following constraint types are valid:


--NOT NULL
--UNIQUE
--PRIMARY KEY
--FOREIGN KEY
--CHECK

Constraint Guidelines:
You can name a constraint, or the Oracle server generates a name by using the
SYS_Cn format.
Create a constraint at either of the following times:
--At the same time as the creation of the table
--After the creation of the table
Define a constraint at the column or table level.
View a constraint in the data dictionary.
Defining Constraints:
Example of a column-level constraint:
Sql> CREATE TABLE employees(employee_id NUMBER(6)
CONSTRAINT emp_emp_id_pk PRIMARY KEY, first_name VARCHAR2(20), ...);

Example of a table-level constraint:

Sql> CREATE TABLE employees (employee_id NUMBER (6), first_name VARCHAR2 (20),
... job_id VARCHAR2 (10) NOT NULL, CONSTRAINT emp_emp_id_pk PRIMARY KEY
(EMPLOYEE_ID));
UNIQUE Constraint:
Sql> CREATE TABLE employees(employee_id NUMBER(6), last_name VARCHAR2(25) NOT
NULL, email VARCHAR2(25), salary NUMBER(8,2), commission_pct NUMBER(2,2), hire_date
DATE NOT NULL, ... CONSTRAINT emp_email_uk UNIQUE(email));
FOREIGN KEY Constraint:
Defined at either the table level or the column level:
Sql> CREATE TABLE employees (employee_id NUMBER(6), last_name VARCHAR2(25) NOT
NULL, email VARCHAR2(25), salary NUMBER(8,2), commission_pct NUMBER(2,2),
hire_date DATE NOT NULL, ... department_id NUMBER(4), CONSTRAINT emp_dept_fk
FOREIGN KEY (department_id) REFERENCES departments(department_id),
CONSTRAINT emp_email_uk UNIQUE(email));
FOREIGN KEY Constraint Keywords:
FOREIGN KEY: Defines the column in the child table at the table-constraint level
REFERENCES: Identifies the table and column in the parent table
ON DELETE CASCADE: Deletes the dependent rows in the child table when a row in
the parent table is deleted
ON DELETE SET NULL: Converts dependent foreign key values to null

60 | P a g e

CHECK Constraint:
Defines a condition that each row must satisfy
The following expressions are not allowed:
--References to CURRVAL, NEXTVAL, LEVEL, and ROWNUM pseudocolumns
--Calls to SYSDATE, UID, USER, and USERENV functions
--Queries that refer to other values in other rows
CREATE TABLE: Example
Sql> CREATE TABLE employees (employee_id NUMBER(6)
CONSTRAINT emp_employee_id PRIMARY KEY , first_name VARCHAR2(20)
, last_name VARCHAR2(25) CONSTRAINT emp_last_name_nn NOT NULL
, email VARCHAR2(25) CONSTRAINT emp_email_nn NOT NULL
CONSTRAINT emp_email_uk UNIQUE , phone_number VARCHAR2(20)
, hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL
, job_id VARCHAR2(10) CONSTRAINT emp_job_nn NOT NULL
, salary NUMBER(8,2) CONSTRAINT emp_salary_ck CHECK (salary>0)
, commission_pct NUMBER(2,2) , manager_id NUMBER(6)
CONSTRAINT emp_manager_fk REFERENCES employees (employee_id)
, department_id NUMBER(4) CONSTRAINT emp_dept_fk REFERENCES departments
(department_id));
Violating Constraints:
Sql> UPDATE employees SET department_id = 55 WHERE department_id = 110;
Output:
ERROR at line 1:
ORA-02291: integrity constraint (HR.EMP_DEPT_FK) violated - parent key not
Found
Department 55 does not exist.

You cannot delete a row that contains a primary key that is used as a foreign key in
another table.

Sql> DELETE FROM departments WHERE department_id = 60;


Output:
ERROR at line 1:
ORA-02292: integrity constraint (HR.EMP_DEPT_FK) violated - child record found.
10.5: Creating a table using a sub-query:

Create a table and insert rows by combining the CREATE TABLE statement and the AS
sub-query option.
Match the number of specified columns to the number of sub-query columns.
Define columns with column names and default values.
61 | P a g e

Sql> CREATE TABLE dept80 AS SELECT employee_id, last_name, salary*12 ANNSAL,


hire_date FROM employees WHERE department_id = 80;
Output:
Table created.
Sql> DESCRIBE dept80
Output:
Name
---------------------EMPLOYEE_ID
LAST_NAME
ANNSAL
HIRE_DATE

Null?
--------

Type
-----------NUMBER (6)
NOT NULL VARCHAR2 (25)
NUMBER
NOT NULL DATE

10.6: ALTER TABLE:


Read-only tables
ALTER TABLE Statement:
Use the ALTER TABLE statement to:
Add a new column
Modify an existing column definition
Define a default value for the new column
Drop a column
Rename a column
Change table to read-only status

Read-Only Tables:
You can use the ALTER TABLE syntax to:
Put a table into read-only mode, which prevents DDL or DML changes during table
maintenance.
Put the table back into read/write mode.
Sql> ALTER TABLE employees READ ONLY;
-- perform table maintenance and then
-- return table back to read/write mode
Sql> ALTER TABLE employees READ WRITE;
10.7: DROP TABLE statement:
Moves a table to the recycle bin
Removes the table and all its data entirely if the PURGE clause is specified.
Invalidates dependent objects and removes object privileges on the table.
62 | P a g e

Sql> DROP TABLE dept80;


Output:
Table dropped.

Summary:
Sql> CREATE TABLE hire_dates (id NUMBER(8), hire_date DATE DEFAULT SYSDATE);
Sql> CREATE TABLE dept (deptno NUMBER(2), dname VARCHAR2(14), loc VARCHAR2(13),
create_date DATE DEFAULT SYSDATE);
Sql> DESCRIBE dept
Sql> CREATE TABLE employees(employee_id NUMBER(6)
CONSTRAINT emp_emp_id_pk PRIMARY KEY, first_name VARCHAR2(20), ...);
Sql> CREATE TABLE employees (employee_id NUMBER(6), first_name VARCHAR2(20),
... job_id VARCHAR2(10) NOT NULL, CONSTRAINT emp_emp_id_pk PRIMARY KEY
(EMPLOYEE_ID));
Sql> CREATE TABLE employees(employee_id NUMBER(6), last_name VARCHAR2(25) NOT
NULL, email VARCHAR2(25), salary NUMBER(8,2), commission_pct NUMBER(2,2), hire_date
DATE NOT NULL, ... CONSTRAINT emp_email_uk UNIQUE(email));
Sql> CREATE TABLE employees (employee_id NUMBER(6), last_name VARCHAR2(25) NOT
NULL, email VARCHAR2(25), salary NUMBER(8,2), commission_pct NUMBER(2,2),
63 | P a g e

hire_date DATE NOT NULL, ... department_id NUMBER(4), CONSTRAINT emp_dept_fk


FOREIGN KEY (department_id) REFERENCES departments(department_id),
CONSTRAINT emp_email_uk UNIQUE(email));
Sql> CREATE TABLE employees (employee_id NUMBER(6)
CONSTRAINT emp_employee_id PRIMARY KEY , first_name VARCHAR2(20)
, last_name VARCHAR2(25) CONSTRAINT emp_last_name_nn NOT NULL
, email VARCHAR2 (25) CONSTRAINT emp_email_nn NOT NULL
CONSTRAINT emp_email_uk UNIQUE , phone_number VARCHAR2(20)
, hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL
, job_id VARCHAR2 (10) CONSTRAINT emp_job_nn NOT NULL
, salary NUMBER (8,2) CONSTRAINT emp_salary_ck CHECK (salary>0)
, commission_pct NUMBER (2,2) , manager_id NUMBER(6)
CONSTRAINT emp_manager_fk REFERENCES employees (employee_id)
, department_id NUMBER (4) CONSTRAINT emp_dept_fk REFERENCES departments
(department_id));
Sql> UPDATE employees SET department_id = 55 WHERE department_id = 110; (ERROR)
Sql> DELETE FROM departments WHERE department_id = 60; (ERROR)
Sql> CREATE TABLE dept80 AS SELECT employee_id, last_name, salary*12 ANNSAL,
hire_date FROM employees WHERE department_id = 80;
Sql> DESCRIBE dept80
Sql> DROP TABLE dept80;

Chapter # 11: Creating Other Schema Objects


Topics:
11.1: Overview of views:
Creating, modifying, and retrieving data from a view
Data manipulation language (DML) operations on a view
Dropping a view
Database Objects:
Object

Description

Table

Basic unit of storage; composed of rows


64 | P a g e

View
Sequenc
e
Index
Synonym

Logically represents subsets of data from one or more tables


Generates numeric values
Improves the performance of data retrieval queries
Gives alternative names to objects

Advantages of Views:

To
restrict

To make
Complex

To provide
data
independenc

T o present
different views of
the same data

Simple Views and Complex Views:


Feature

Simple Views

Complex Views

Number of tables
Contain functions
Contain groups of data
DML operations through a view

One
No
No
Yes

One or more
Yes
Yes
Not always

Creating a View:
You embed a sub-query in the CREATE VIEW statement:
The sub-query can contain complex SELECT syntax.
Create the EMPVU80 view, which contains details of the employees in department 80:
Sql> CREATE VIEW empvu80 AS SELECT employee_id, last_name, salary
FROM employees WHERE department_id = 80;
Output:
View created.

Describe the structure of the view by using the SQL*Plus DESCRIBE command:
65 | P a g e

Sql> DESCRIBE empvu80


Output:
Name
----------------------EMPLOYEE_ID
LAST_NAME
SALARY

Null?
--------

Type
-----------NOT NULL NUMBER (6)
NOT NULL VARCHAR2 (25)
NUMBER (8, 2)

Create a view by using column aliases in the sub-query:

Sql> CREATE VIEW salvu50 AS SELECT employee_id ID_NUMBER, last_name NAME,


salary*12 ANN_SALARY FROM employees WHERE department_id = 50;
Output:
View created.

Select the columns from this view by the given alias names.

Retrieving Data from a View:


Sql> SELECT * FROM salvu50;
Output:
ID_NUMBER
-----------------196
197

NAME
---------Walsh
Feeney

ANN_SALARY
-------------------37200
36000

Modifying a View:
Modify the EMPVU80 view by using a CREATE OR REPLACE VIEW clause. Add an
alias for each column name:
Sql> CREATE OR REPLACE VIEW empvu80 (id_number, name, sal, department_id)
AS SELECT employee_id, first_name || ' ' || last_name, salary, department_id
FROM employees WHERE department_id = 80;
Output:
View created.

Column aliases in the CREATE OR REPLACE VIEW clause are listed in the same order
as the columns in the sub-query.

Creating a Complex View:


Create a complex view that contains group functions to display values from two tables:
66 | P a g e

Sql> CREATE OR REPLACE VIEW dept_sum_vu (name, minsal, maxsal, avgsal)


AS SELECT d.department_name, MIN(e.salary), MAX(e.salary),AVG(e.salary)
FROM employees e JOIN departments d ON (e.department_id = d.department_id)
GROUP BY d.department_name;
Output:
View created.
Rules for Performing DML Operations on a View:
You can usually perform DML operations on simple views.
You cannot remove a row if the view contains the following:
--Group functions
--A GROUP BY clause
--The DISTINCT keyword
--The pseudocolumn ROWNUM keyword
You cannot modify data in a view if it contains:
Group functions
A GROUP BY clause
The DISTINCT keyword
The pseudocolumn ROWNUM keyword
Columns defined by expressions
You cannot add data through a view if the view includes:

Group functions
A GROUP BY clause
The DISTINCT keyword
The pseudocolumn ROWNUM keyword
Columns defined by expressions
NOT NULL columns in the base tables that are not selected by the view

Using the WITH CHECK OPTION Clause:


You can ensure that DML operations performed on the view stay in the domain of the
view by using the WITH CHECK OPTION clause:
Sql> CREATE OR REPLACE VIEW empvu20 AS SELECT * FROM employees
WHERE department_id = 20 WITH CHECK OPTION CONSTRAINT empvu20_ck;

Any attempt to INSERT a row with a department_id other than 20, or to UPDATE the
department number for any row in the view fails because it violates the WITH CHECK
OPTION constraint.

Denying DML Operations:


You can ensure that no DML operations occur by adding the WITH READ ONLY option
to your view definition.
Any attempt to perform a DML operation on any row in the view results in an Oracle
server error.
67 | P a g e

Sql> CREATE OR REPLACE VIEW empvu10 (employee_number, employee_name, job_title)


AS SELECT employee_id, last_name, job_id FROM employees WHERE department_id = 10
WITH READ ONLY;
Output:
View Created.
Removing a View:
You can remove a view without losing data because a view is based on underlying tables
in the database.
Sql> DROP VIEW empvu80;
Output:
View dropped.
11.2: Overview of sequences:
Creating, using, and modifying a sequence
Cache sequence values
NEXTVAL and CURRVAL pseudocolumns
Sequences:
Object

Description

Table
View
Sequenc
e
Index
Synonym

Basic unit of storage; composed of rows


Logically represents subsets of data from one or more tables
Generates numeric values
Improves the performance of some queries
Gives alternative names to objects

A sequence:
Can automatically generate unique numbers
Is a shareable object
Can be used to create a primary key value
Replaces application code
Speeds up the efficiency of accessing sequence values when cached in memory
Creating a Sequence:
Create a sequence named DEPT_DEPTID_SEQ to be used for the primary key of the
DEPARTMENTS table.
68 | P a g e

Do not use the CYCLE option.

Sql> CREATE SEQUENCE dept_deptid_seq1 INCREMENT BY 20 START WITH 320


MAXVALUE 9999 NOCACHE NOCYCLE;

Output:
Sequence created.
NEXTVAL and CURRVAL Pseudocolumns:
NEXTVAL returns the next available sequence value. It returns a unique value every
time it is referenced, even for different users.
CURRVAL obtains the current sequence value.
NEXTVAL must be issued for that sequence before CURRVAL contains a value.
Using a Sequence:
Insert a new department named Support in location ID 2500:
Sql> INSERT INTO departments(department_id, department_name, location_id) VALUES
(dept_deptid_seq1.NEXTVAL, 'Support', 2500);
Output:
1 row created.

View the current value for the DEPT_DEPTID_SEQ sequence:

Sql> SELECT dept_deptid_seq1.CURRVAL FROM dual;


Caching Sequence Values:
Caching sequence values in memory gives faster access to those values.
Gaps in sequence values can occur when:
--A rollback occurs
--The system crashes
--A sequence is used in another table
Modifying a Sequence:
Change the increment value, maximum value, minimum value, cycle option, or cache option:
Sql> ALTER SEQUENCE dept_deptid_seq1 INCREMENT BY 30 MAXVALUE 999999
NOCACHE NOCYCLE;
Output:
Sequence altered.
Guidelines for Modifying a Sequence:
You must be the owner or have the ALTER privilege for the sequence.
Only future sequence numbers are affected.
69 | P a g e

The sequence must be dropped and re-created to restart the sequence at a different
number.
Some validation is performed.
To remove a sequence, use the DROP statement:

Sql> DROP SEQUENCE dept_deptid_seq1;


Output:
Sequence dropped.
11.3: Overview of indexes:
Creating, dropping indexes
Indexes:
Object

Description

Table
View
Sequenc
e
Index
Synonym

Basic unit of storage; composed of rows


Logically represents subsets of data from one or more tables
Generates numeric values
Improves the performance of some queries
Gives alternative names to objects

An index:
Is a schema object
May be used by the Oracle server to speed up the retrieval of rows by using a pointer
Can reduce disk input/output (I/O) by using a rapid path access method to locate data
quickly
Is independent of the table that it indexes
Is used and maintained automatically by the Oracle server
How Are Indexes Created?
Automatically: A unique index is created automatically when you define a PRIMARY KEY
or UNIQUE constraint in a table definition.
Manually: Users can create nonunique indexes on columns to speed up access to the
rows.
Creating an Index:
Create an index on one or more columns:
Improve the speed of query access to the LAST_NAME column in the EMPLOYEES
table:
Sql> CREATE INDEX emp_last_name_idx ON employees(last_name);
Output:
70 | P a g e

Index created.
Index Creation Guidelines:
Create an index when:
A column contains a wide range of values
A column contains a large number of null values
One or more columns are frequently used together in a WHERE clause or a join condition

The table is large and most queries are expected to retrieve less than 2% to 4% of the rows in the table
Do not create an index when:
The columns are not often used as a condition in the query

The table is small or most queries are expected to retrieve more than 2% to 4% of the rows in the table
The table is updated frequently
The indexed columns are referenced as part of an expression

Removing an Index:
Remove an index from the data dictionary by using the DROP INDEX command:
Remove the emp_last_name_idx index from the data dictionary:
To drop an index, you must be the owner of the index or have the DROP ANY INDEX
privilege.
Sql> DROP INDEX emp_last_name_idx;
Output:
Index dropped.

11.4: Overview of synonyms:


Creating, dropping synonyms
71 | P a g e

Synonyms:
Object

Description

Table
View
Sequenc
e
Index
Synonym

Basic unit of storage; composed of rows


Logically represents subsets of data from one or more tables
Generates numeric values
Improves the performance of some queries
Gives alternative names to objects

Creating a Synonym for an Object:


Simplify access to objects by creating a synonym (another name for an object). With
synonyms, you can:
Create an easier reference to a table that is owned by another user.
Shorten lengthy object names.
Creating and Removing Synonyms:
Create a shortened name for the DEPT_SUM_VU view:
Sql> CREATE SYNONYM d_sum FOR dept_sum_vu;
Output:
Synonym created.

Drop a synonym:

Sql> DROP SYNONYM d_sum;


Output:
Synonym dropped.

72 | P a g e

Summary:
Sql> CREATE VIEW empvu80 AS SELECT employee_id, last_name, salary
FROM employees WHERE department_id = 80;
Sql> DESCRIBE empvu80
Sql> SELECT * FROM salvu50;
Sql> CREATE OR REPLACE VIEW empvu80 (id_number, name, sal, department_id)
AS SELECT employee_id, first_name || ' ' || last_name, salary, department_id
FROM employees WHERE department_id = 80;
Sql> CREATE OR REPLACE VIEW dept_sum_vu (name, minsal, maxsal, avgsal)
AS SELECT d.department_name, MIN(e.salary), MAX(e.salary),AVG(e.salary)
FROM employees e JOIN departments d ON (e.department_id = d.department_id)
GROUP BY d.department_name;
Sql> CREATE OR REPLACE VIEW empvu20 AS SELECT * FROM employees
WHERE department_id = 20 WITH CHECK OPTION CONSTRAINT empvu20_ck;
Sql> CREATE OR REPLACE VIEW empvu10 (employee_number, employee_name, job_title)
AS SELECT employee_id, last_name, job_id FROM employees WHERE department_id = 10
WITH READ ONLY;
Sql> DROP VIEW empvu80;
Sql> CREATE SEQUENCE dept_deptid_seq1 INCREMENT BY 20 START WITH 320
MAXVALUE 9999 NOCACHE NOCYCLE;
Sql> INSERT INTO departments(department_id, department_name, location_id) VALUES
(dept_deptid_seq1.NEXTVAL, 'Support', 2500);
Sql> ALTER SEQUENCE dept_deptid_seq1 INCREMENT BY 30 MAXVALUE 999999
NOCACHE NOCYCLE;
Sql> DROP SEQUENCE dept_deptid_seq1;
Sql> CREATE INDEX emp_last_name_idx ON employees(last_name);
Sql> DROP INDEX emp_last_name_idx;
Sql> CREATE SYNONYM d_sum FOR dept_sum_vu;
Sql> DROP SYNONYM d_sum;

73 | P a g e

Chapter # 12: Controlling User Access


Topics:
12.1: System privileges:
Privileges:
Database security:
--System security
--Data security
System privileges: Performing a particular action within the database.
Object privileges: Manipulating the content of the database objects.
Schemas: Collection of objects such as tables, views, and sequences.
System Privileges:
More than 100 privileges are available.
The database administrator has high-level system privileges for tasks such as:
--Creating new users
--Removing users
--Removing tables
--Backing up tables
Creating Users:
The database administrator (DBA) creates users with the CREATE USER statement.
Sql> CREATE USER demo IDENTIFIED BY demo;
Output:
User Created.
User System Privileges:
After a user is created, the DBA can grant specific system privileges to that user.
An application developer, for example, may have the following system privileges:
--CREATE SESSION
--CREATE TABLE
--CREATE SEQUENCE
--CREATE VIEW
--CREATE PROCEDURE
Granting System Privileges:
The DBA can grant specific system privileges to a user.
Sql> GRANT create session, create table, create sequence, create view TO demo;
Output:
Grant succeeded.

74 | P a g e

12.2: Creating a role:


What Is a Role?

Use
r

Allocating Privileges
Without a Role

Allocating
ManagerPrivileges
with a Role

Creating and Granting Privileges to a Role:


Privilege
Create a role:
s

Sql> CREATE ROLE manager;


Output:
Role created.

Grant privileges to a role:

Sql> GRANT create table, create view TO manager;


Output:
Grant succeeded.

Grant a role to users:

Sql> GRANT manager TO BELL, KOCHHAR;

Output:
Grant succeeded.
Changing Your Password:
The DBA creates your user account and initializes your password.
75 | P a g e

You can change your password by using the ALTER USER statement.

Sql> ALTER USER demo IDENTIFIED BY employ;


Output:
User altered.
12.3: Object privileges:
Object Privilege Table
ALTER
DELETE
INDEX
INSERT
REFERENCES
SELECT
UPDATE

View
Yes
Yes
Yes
Yes
Yes
Yes
Yes

Sequenc
e
Yes

Yes
Yes
Yes
Yes

Yes

Object privileges vary from object to object.


An owner has all the privileges on the object.
An owner can give specific privileges on that owners object.
Granting Object Privileges:
Grant query privileges on the EMPLOYEES table:
Sql> GRANT select ON employees TO demo;
Output:
Grant succeeded.

Grant privileges to update specific columns to users and roles:

Sql> GRANT update (department_name, location_id) ON departments TO demo, manager;


Output:
Grant succeeded.
Passing On Your Privileges:
Give a user authority to pass along privileges:
Sql> GRANT select, insert ON departments TO demo WITH GRANT OPTION;
Output:
Grant succeeded.

76 | P a g e

Allow all users on the system to query data from Alices DEPARTMENTS table:

Sql> GRANT select ON alice.departments TO PUBLIC;


Output:
Grant succeeded.
Confirming Granted Privileges:
Data Dictionary View
ROLE_SYS_PRIVS
ROLE_TAB_PRIVS
USER_ROLE_PRIVS
USER_SYS_PRIVS
USER_TAB_PRIVS_MADE
USER_TAB_PRIVS_RECD
USER_COL_PRIVS_MADE
USER_COL_PRIVS_RECD

Description
System privileges granted to roles
Table privileges granted to roles
Roles accessible by the user
System privileges granted to the user
Object privileges granted on the users objects
Object privileges granted to the user
Object privileges granted on the columns of the users objects
Object privileges granted to the user on specific columns

12.4: Revoking object privileges:


You use the REVOKE statement to revoke privileges granted to other users.
Privileges granted to others through the WITH GRANT OPTION clause are also
revoked.
Revoke the SELECT and INSERT privileges given to the demo user on the
DEPARTMENTS table.
Sql> REVOKE select, insert ON departments FROM demo;
Output:
Revoke succeeded.

Summary:
Sql> CREATE USER demo IDENTIFIED BY demo;
Sql> GRANT create session, create table, create sequence, create view TO demo;
77 | P a g e

Sql> CREATE ROLE manager;


Sql> GRANT create table, create view TO manager;
Sql> GRANT manager TO BELL, KOCHHAR;
Sql> ALTER USER demo IDENTIFIED BY employ;
Sql> GRANT select ON employees TO demo;
Sql> GRANT update (department_name, location_id) ON departments TO demo, manager;
Sql> GRANT select, insert ON departments TO demo WITH GRANT OPTION;
Sql> GRANT select ON alice.departments TO PUBLIC;
Sql> REVOKE select, insert ON departments FROM demo;

78 | P a g e

Chapter # 13: Managing Schema Objects


Topics:
13.1: Using the ALTER TABLE statement to add, modify, and drop a column:
ALTER TABLE Statement:
Use the ALTER TABLE statement to:
Add a new column
Modify an existing column
Define a default value for the new column
Drop a column
Use the ALTER TABLE statement to add, modify, or drop columns:
Adding a Column:
You use the ADD clause to add columns:
The new column becomes the last column:
Sql> ALTER TABLE dept80 ADD (job_id VARCHAR2(9));
Output:
Table altered.
Modifying a Column:
You can change a columns data type, size, and default value.
A change to the default value affects only subsequent insertions to the table.
Sql> ALTER TABLE dept80 MODIFY (last_name VARCHAR2(30));
Output:
Table altered.
Dropping a Column:
Use the DROP COLUMN clause to drop columns you no longer need from the table:
Sql> ALTER TABLE dept80 DROP COLUMN job_id;
Output:
Table altered.
SET UNUSED Option:
You use the SET UNUSED option to mark one or more columns as unused.
You use the DROP UNUSED COLUMNS option to remove the columns that are marked
as unused.

79 | P a g e

Syntax:
ALTER TABLE <table_name> SET UNUSED(<column_name>);
OR
ALTER TABLE <table_name> SET UNUSED COLUMN <column_name>;
ALTER TABLE <table_name> DROP UNUSED COLUMNS;
13.2: Managing constraints:
Adding and dropping a constraint
Deferring constraints
Enabling and disabling a constraint
Adding Constraint Syntax:
Use the ALTER TABLE statement to:
Add or drop a constraint, but not modify its structure
Enable or disable constraints
Add a NOT NULL constraint by using the MODIFY clause
Add a FOREIGN KEY constraint to the EMP2 table indicating that a manager must
already exist as a valid employee in the EMP2 table.
Sql> ALTER TABLE emp2 MODIFY employee_id Primary Key;
Output:
Table altered.
Sql> ALTER TABLE emp2 ADD CONSTRAINT emp_mgr_fk FOREIGN KEY(manager_id)
REFERENCES emp2(employee_id);
Output:
Table altered.
ON DELETE CASCADE:
Delete child rows when a parent key is deleted:
Sql> ALTER TABLE Emp2 ADD CONSTRAINT emp_dt_fk FOREIGN KEY (Department_id)
REFERENCES departments (department_id) ON DELETE CASCADE;
Output:
Table altered.
Deferring Constraints:
Constraints can have the following attributes:
DEFERRABLE or NOT DEFERRABLE
INITIALLY DEFERRED or INITIALLY IMMEDIATE

80 | P a g e

Sql> ALTER TABLE dept2 ADD CONSTRAINT dept2_id_pk PRIMARY KEY (department_id)
DEFERRABLE INITIALLY DEFERRED ;( Deferring constraint on creation).
Output:
Table altered.
Sql> SET CONSTRAINTS dept2_id_pk IMMEDIATE; (Changing a specific constraint
attribute).
Output:
Constraint set.
Sql> ALTER SESSION SET CONSTRAINTS= IMMEDIATE; (Changing all constraints for a
session).
Output:
Session altered.
Difference between INITIALLY DEFERRED and INITIALLY IMMEDIATE:
INITIALLY DEFERRED
INITIALLY IMMEDIATE

Waits to check the constraint until the transaction ends


Checks the constraint at the end of the statement execution

Sql> CREATE TABLE emp_new_sal (salary NUMBER CONSTRAINT sal_ck


CHECK (salary > 100) DEFERRABLE INITIALLY IMMEDIATE,
bonus NUMBER CONSTRAINT bonus_ck CHECK (bonus > 0 )
DEFERRABLE INITIALLY DEFERRED);
Output:
Table created.
Dropping a Constraint:
Remove the manager constraint from the EMP2 table:
Sql> ALTER TABLE emp2 DROP CONSTRAINT emp_mgr_fk;
Output:
Table altered.

Remove the PRIMARY KEY constraint on the DEPT2 table and drop the associated
FOREIGN KEY constraint on the EMP2.DEPARTMENT_ID column:

Sql> ALTER TABLE dept2 DROP PRIMARY KEY CASCADE;


81 | P a g e

Output:
Table altered.
Disabling Constraints:
Execute the DISABLE clause of the ALTER TABLE statement to deactivate an integrity
constraint.
Apply the CASCADE option to disable dependent integrity constraints.
Sql> ALTER TABLE emp2 DISABLE CONSTRAINT emp_dt_fk;
Output:
Table altered.
Enabling Constraints:
Activate an integrity constraint currently disabled in the table definition by using the
ENABLE clause.
A UNIQUE index is automatically created if you enable a UNIQUE key or a PRIMARY
KEY constraint.
Sql> ALTER TABLE emp2 ENABLE CONSTRAINT emp_dt_fk;
Output:
Table altered.
Cascading Constraints:
The CASCADE CONSTRAINTS clause is used along with the DROP COLUMN clause.
The CASCADE CONSTRAINTS clause drops all referential integrity constraints that
refer to the primary and unique keys defined on the dropped columns.
The CASCADE CONSTRAINTS clause also drops all multicolumn constraints defined
on the dropped columns.
Sql> ALTER TABLE emp2 DROP COLUMN employee_id CASCADE CONSTRAINTS;
Output:
Table altered.
Sql> ALTER TABLE test1 DROP (col1_pk, col2_fk, col1) CASCADE CONSTRAINTS;
Output:
Table altered.
Renaming Table Columns and Constraints:
Use the RENAME COLUMN clause of the ALTER TABLE statement to rename table
columns.
82 | P a g e

Sql> ALTER TABLE marketing RENAME COLUMN team_id TO id;


Output:
Table altered.

Use the RENAME CONSTRAINT clause of the ALTER TABLE statement to rename any
existing constraint for a table.

Sql> ALTER TABLE marketing RENAME CONSTRAINT mktg_pk TO new_mktg_pk;


Output:
Table altered.
13.3: Creating indexes:
Using the CREATE TABLE statement
Creating function-based indexes
Removing an index
Overview of Indexes:
Indexes are created:
Automatically
--PRIMARY KEY creation
--UNIQUE KEY creation
Manually
--The CREATE INDEX statement
--The CREATE TABLE statement
CREATE INDEX with the CREATE TABLE Statement:
Sql> CREATE TABLE NEW_EMP (employee_id NUMBER (6)
PRIMARY KEY USING INDEX (CREATE INDEX emp_id_idx ON
NEW_EMP (employee_id)), first_name VARCHAR2 (20), last_name VARCHAR2 (25));
Output:
Table created.
Sql> SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'NEW_EMP';
Output:
INDEX_NAME
-------------------EMP_ID_IDX

TABLE_NAME
------------------NEW_EMP

Function-Based Indexes:
A function-based index is based on expressions.
83 | P a g e

The index expression is built from table columns, constants, SQL functions, and userdefined functions.

Sql> CREATE INDEX upper_dept_name_idx ON dept2 (UPPER (department_name));


Output:
Index created.
Sql> SELECT * FROM dept2 WHERE UPPER (department_name) = 'SALES';
Output:
No row selected.
Removing an Index:
Remove an index from the data dictionary by using the DROP INDEX command:
DROP INDEX index;

Remove the UPPER_DEPT_NAME_IDX index from the data dictionary:

Sql> DROP INDEX upper_dept_name_idx;


Output:
Index dropped.

To drop an index, you must be the owner of the index or have the DROP ANY INDEX
privilege.

DROP TABLE PURGE:


Sql> DROP TABLE dept80 PURGE;
Output:
Table dropped.
13.4: Performing flashback operations:
FLASHBACK TABLE Statement:
Enables you to recover tables to a specified point in time with a single statement.
Restores table data along with associated indexes, and constraints.
Enables you to revert the table and its contents to a certain point in time or SCN.
Repair tool for accidental table modifications.
--Restores a table to an earlier point in time.
--Benefits: Ease of use, availability, and fast execution.
--Is performed in place.
84 | P a g e

Using the FLASHBACK TABLE Statement:


Sql> DROP TABLE emp2;

Output:
Table dropped.
Sql> SELECT original_name, operation, droptime FROM recyclebin;

Output:
ORIGINAL_NAME
------------------------EMP2

OPERATION
----------------DROP

DROPTIME
---------------2011-07-06:11:17:09

Sql> FLASHBACK TABLE emp2 TO BEFORE DROP;


Output:
Flashback complete.
13.5: Creating and using external tables:
Creating a Directory for the External Table:
Create a DIRECTORY object that corresponds to the directory on the file system where
the external data source resides.
Sql> CREATE OR REPLACE DIRECTORY emp_dir AS '//emp_dir';
Output:
Directory created.
Sql> GRANT READ ON DIRECTORY emp_dir TO hr;
Output:
Grant succeeded.
Creating an External Table by Using ORACLE_LOADER:
Sql> CREATE TABLE oldemp (fname char (25), lname CHAR (25)) ORGANIZATION
EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY emp_dir
ACCESS PARAMETERS (RECORDS DELIMITED BY NEWLINE
NOBADFILE NOLOGFILE FIELDS TERMINATED BY ',' (fname POSITION (1:20) CHAR, lname
POSITION (22:41) CHAR)) LOCATION ('emp.dat'))
PARALLEL 5 REJECT LIMIT 200;

85 | P a g e

Output:
Table created.
Sql> select * from oldemp;
Output:
FNAME
---------Saad
Ahmed
Pasha
Hassaan
waqar
Sherry

LNAME
----------Pasha
Pasha
Saad
Tahir
Abban
Shamsi

Creating an External Table by Using ORACLE_DATAPUMP: Example


Sql> CREATE TABLE emp_ext (employee_id, first_name, last_name)
ORGANIZATION EXTERNAL (TYPE ORACLE_DATAPUMP DEFAULT DIRECTORY emp_dir
LOCATION ('emp1.exp','emp2.exp') ) PARALLEL AS SELECT employee_id, first_name,
last_name FROM employees;
Summary:
Sql> ALTER TABLE dept80 ADD (job_id VARCHAR2(9));
Sql> ALTER TABLE dept80 MODIFY (last_name VARCHAR2(30));
Sql> ALTER TABLE dept80 DROP COLUMN job_id;
Sql> ALTER TABLE emp2 MODIFY employee_id Primary Key;
Sql> ALTER TABLE emp2 ADD CONSTRAINT emp_mgr_fk FOREIGN KEY(manager_id)
REFERENCES emp2(employee_id);
Sql> ALTER TABLE Emp2 ADD CONSTRAINT emp_dt_fk FOREIGN KEY (Department_id)
REFERENCES departments (department_id) ON DELETE CASCADE;
Sql> ALTER TABLE dept2 ADD CONSTRAINT dept2_id_pk PRIMARY KEY (department_id)
DEFERRABLE INITIALLY DEFERRED ;( Deferring constraint on creation)
Sql> SET CONSTRAINTS dept2_id_pk IMMEDIATE; (Changing a specific constraint
attribute)
Sql> ALTER SESSION SET CONSTRAINTS= IMMEDIATE; (Changing all constraints for a
session)
Sql> CREATE TABLE emp_new_sal (salary NUMBER CONSTRAINT sal_ck
CHECK (salary > 100) DEFERRABLE INITIALLY IMMEDIATE,
bonus NUMBER CONSTRAINT bonus_ck CHECK (bonus > 0 )
DEFERRABLE INITIALLY DEFERRED);
Sql> ALTER TABLE emp2 DROP CONSTRAINT emp_mgr_fk;
Sql> ALTER TABLE dept2 DROP PRIMARY KEY CASCADE;
Sql> ALTER TABLE emp2 DISABLE CONSTRAINT emp_dt_fk;
Sql> ALTER TABLE emp2 ENABLE CONSTRAINT emp_dt_fk;
Sql> ALTER TABLE emp2 DROP COLUMN employee_id CASCADE CONSTRAINTS;
Sql> ALTER TABLE test1 DROP (col1_pk, col2_fk, col1) CASCADE CONSTRAINTS;
Sql> ALTER TABLE marketing RENAME COLUMN team_id TO id;
86 | P a g e

Sql> ALTER TABLE marketing RENAME CONSTRAINT mktg_pk TO new_mktg_pk;


Sql> CREATE TABLE NEW_EMP (employee_id NUMBER (6)
PRIMARY KEY USING INDEX (CREATE INDEX emp_id_idx ON
NEW_EMP (employee_id)), first_name VARCHAR2 (20), last_name VARCHAR2 (25));
Sql> SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'NEW_EMP';
Sql> CREATE INDEX upper_dept_name_idx ON dept2 (UPPER (department_name));
Sql> SELECT * FROM dept2 WHERE UPPER (department_name) = 'SALES';
Sql> DROP INDEX upper_dept_name_idx;
Sql> DROP TABLE dept80 PURGE;
Sql> DROP TABLE emp2;
Sql> SELECT original_name, operation, droptime FROM recyclebin;
Sql> FLASHBACK TABLE emp2 TO BEFORE DROP;
Sql> CREATE OR REPLACE DIRECTORY emp_dir AS '//emp_dir';
Sql> GRANT READ ON DIRECTORY emp_dir TO hr;
Sql> CREATE TABLE oldemp (fname char (25), lname CHAR (25)) ORGANIZATION
EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY emp_dir
ACCESS PARAMETERS (RECORDS DELIMITED BY NEWLINE
NOBADFILE NOLOGFILE FIELDS TERMINATED BY ',' (fname POSITION (1:20) CHAR, lname
POSITION (22:41) CHAR)) LOCATION ('emp.dat'))
PARALLEL 5 REJECT LIMIT 200;
Sql> select * from oldemp;
Sql> CREATE TABLE emp_ext (employee_id, first_name, last_name)
ORGANIZATION EXTERNAL (TYPE ORACLE_DATAPUMP DEFAULT DIRECTORY emp_dir
LOCATION ('emp1.exp','emp2.exp') ) PARALLEL AS SELECT employee_id, first_name,
last_name FROM employees;

87 | P a g e

Chapter # 14: Managing Objects with Data Dictionary


Views
Topics:
14.1: Introduction to data dictionary:

Oracle server

Tables containing
Business data:
EMPLOYEES
DEPARTMENTS
LOCATIONS
JOB_HISTORY
.

Data dictionary
views:
DICTIONARY
USER_OBJECTS
USER_TABLES
USER_TAB_COLUMNS
..

Data Dictionary Structure:

88 | P a g e

Oracle server

Consists of:
Base tables
User-accessible
views

View naming convention:

View Prefix

Purpose

USER
ALL
DBA
V$

Users view (what is in your schema; what you own)


Expanded users view (what you can access)
Database administrators view (what is in everyones schemas)
Performance-related data

How to Use the Dictionary Views:


Start with DICTIONARY. It contains the names and descriptions of the dictionary tables
and views.
Sql> DESCRIBE DICTIONARY

Output:
Name
--------------------TABLE_NAME
COMMENTS

Null?
---------

Type
-------------VARCHAR2 (30)
VARCHAR2 (4000)

Sql> SELECT * FROM dictionary WHERE table_name = 'USER_OBJECTS';


Output:
TABLE_NAME
------------------------

COMMENTS
---------------------------------89 | P a g e

USER_OBJECTS

Objects owned by the user

USER_OBJECTS and ALL_OBJECTS Views:


USER_OBJECTS:
Query USER_OBJECTS to see all the objects that you own
Is a useful way to obtain a listing of all object names and types in your schema, plus the
following information:
--Date created
--Date of last modification
--Status (valid or invalid)
ALL_OBJECTS:
Query ALL_OBJECTS to see all objects to which you have access
USER_OBJECTS View:
Sql> SELECT object_name, object_type, created, status FROM user_objects
ORDER BY object_type;

Output:
OBJECT_NAME
---------------------EMP_ID_IDX
JHIST_JOB_IX
MKTG_PK

OBJECT_TYPE
--------------------INDEX
INDEX
INDEX

CREATED
-------------06-JUL-11
01-JUL-11
06-JUL-11

STATUS
-----------VALID
VALID
VALID

14.2: Querying the dictionary views for the following:


Table information
Column information
Constraint information
Table Information:
USER_TABLES:
Sql> DESCRIBE user_tables
Output:
Name
----------------------------TABLE_NAME
TABLESPACE_NAME
CLUSTER_NAME
IOT_NAME

Null?
-------------NOT NULL

Type
-----------------------VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (30)

Sql> SELECT table_name FROM user_tables;


90 | P a g e

Output:
TABLE_NAME
-------------------COUNTRIES
OLDEMP
NEW_EMP
MARKETING
TEST1
EMP_NEW_SAL
DEPT2
EMP2
DEPT
HIRE_DATES
COPY_EMP1

TABLE_NAME
---------------------DEPT4
SALES_REPS
JOB_HISTORY
EMPLOYEES
JOBS
DEPARTMENTS
LOCATIONS
REGIONS

Column Information:
USER_TAB_COLUMNS:
Sql> DESCRIBE user_tab_columns
Output:
Name
-----------------------TABLE_NAME
COLUMN_NAME
DATA_TYPE

Null?
-------------NOT NULL
NOT NULL

Type
-------------------VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (106)

Sql> SELECT column_name, data_type, data_length, data_precision, data_scale, nullable


FROM user_tab_columns WHERE table_name = 'EMPLOYEES';
Output:
COLUMN_NAME
-----------------------EMPLOYEE_ID
FIRST_NAME
LAST_NAME
EMAIL
PHONE_NUMBER
HIRE_DATE

DATA_TYPE
----------------NUMBER
VARCHAR2
VARCHAR2
VARCHAR2
VARCHAR2
DATE

DATA_LENGTH DATA_PRECISION DATA_SCALE


---------------------- -------------------------- ------------------22
6
0
20
25
25
20
7

NULLABLE
----------------N
Y
N
N
Y
N

Constraint Information:
USER_CONSTRAINTS describes the constraint definitions on your tables.
USER_CONS_COLUMNS describes columns that are owned by you and that are
specified in constraints.
Sql> DESCRIBE user_constraints
Output:
91 | P a g e

Name
-----------------------------OWNER
CONSTRAINT_NAME
CONSTRAINT_TYPE
TABLE_NAME

Null?
-------NOT NULL
NOT NULL

Type
-------------------VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (1)
VARCHAR2 (30)

Sql> SELECT constraint_name, constraint_type, search_condition, r_constraint_name,


delete_rule, status FROM user_constraints WHERE table_name = 'EMPLOYEES';
Output:

Querying USER_CONS_COLUMNS:
Sql> DESCRIBE user_cons_columns
Output:
Name
-----------------------------OWNER
CONSTRAINT_NAME
TABLE_NAME
COLUMN_NAME
POSITION

Null?
----------NOT NULL
NOT NULL
NOT NULL

Type
-------------VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (4000)
NUMBER

Sql> SELECT constraint_name, column_name FROM user_cons_columns


WHERE table_name = 'EMPLOYEES';
Output:
CONSTRAINT_NAME
-----------------------------EMP_EMP_ID_PK
EMP_EMAIL_UK
EMP_SALARY_MIN

COLUMN_NAME
------------------------EMPLOYEE_ID
EMAIL
SALARY
92 | P a g e

14.3: Querying the dictionary views for the following:


View information
Sequence information
Synonym information
Index information
View Information:
Sql> DESCRIBE user_views
Output:
Name
------------------------------VIEW_NAME
TEXT_LENGTH
TEXT
TYPE_TEXT_LENGTH
TYPE_TEXT
OID_TEXT_LENGTH
OID_TEXT
VIEW_TYPE_OWNER
VIEW_TYPE
SUPERVIEW_NAME
EDITIONING_VIEW
READ_ONLY

Null?
------------NOT NULL

Type
----------------VARCHAR2 (30)
NUMBER
LONG
NUMBER
VARCHAR2 (4000)
NUMBER
VARCHAR2 (4000)
VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (1)
VARCHAR2 (1)

Sql> SELECT view_name FROM user_views;


Output:
VIEW_NAME
------------------DEPT_SUM_VU
EMPVU10
EMP_DETAILS_VIEW
SALVU50
Sql> SELECT text FROM user_views WHERE view_name = 'EMP_DETAILS_VIEW';
Output:

93 | P a g e

TEXT
------------------SELECT
e.employee_id,
e.job_id,
e.manager_id,
e.department_id,
d.locat
Sequence Information:
Sql> DESCRIBE user_sequences
Output:
Name
---------------------------SEQUENCE_NAME
MIN_VALUE
MAX_VALUE
INCREMENT_BY
CYCLE_FLAG
ORDER_FLAG
CACHE_SIZE
LAST_NUMBER

Null?
------------NOT NULL
NOT NULL
NOT NULL
NOT NULL

Type
-----------------VARCHAR2 (30)
NUMBER
NUMBER
NUMBER
VARCHAR2 (1)
VARCHAR2 (1)
NUMBER
NUMBER

Confirming Sequences:
Verify your sequence values in the USER_SEQUENCES data dictionary table.
The LAST_NUMBER column displays the next available sequence number if NOCACHE
is specified.
Sql> SELECT sequence_name, min_value, max_value, increment_by, last_number
FROM user_sequences;
Output:
SEQUENCE_NAME
-----------------------------DEPARTMENTS_SEQ
DEPT_DEPTID_SEQ
EMPLOYEES_SEQ
LOCATIONS_SEQ

MIN_VALUE MAX_VALUE
----------------- -----------------1
9990
1
9999
1
1.0000E+28
1
9900

INCREMENT_BY LAST_NUMBER
----------------------- ---------------------10
280
10
130
1
207
100
3300

Index Information:
USER_INDEXES provides information about your indexes.
USER_IND_COLUMNS describes columns comprising your indexes and columns of
indexes on your tables.
Sql> DESCRIBE user_indexes
Output:
94 | P a g e

Name
-----------------------INDEX_NAME
INDEX_TYPE
TABLE_OWNER
TABLE_NAME

Null?
----------------NOT NULL
NOT NULL
NOT NULL

Type
-----------------VARCHAR2 (30)
VARCHAR2 (27)
VARCHAR2 (30)
VARCHAR2 (30)

USER_INDEXES: Examples
Sql> SELECT index_name, table_name,uniqueness FROM user_indexes
WHERE table_name = 'EMPLOYEES';
Output:
INDEX_NAME
---------------------------------EMP_NAME_IX
EMP_MANAGER_IX
EMP_JOB_IX
EMP_DEPARTMENT_IX
EMP_EMP_ID_PK
EMP_EMAIL_UK

TABLE_NAME
--------------------EMPLOYEES
EMPLOYEES
EMPLOYEES
EMPLOYEES
EMPLOYEES
EMPLOYEES

UNIQUENES
--------------------NONUNIQUE
NONUNIQUE
NONUNIQUE
NONUNIQUE
UNIQUE
UNIQUE

Sql> SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXES


WHERE TABLE_NAME = 'DEPARTMENTS';
Output:
INDEX_NAME
-----------------------------DEPT_LOCATION_IX
DEPT_ID_PK

TABLE_NAME
----------------DEPARTMENTS
DEPARTMENTS

Querying USER_IND_COLUMNS:
Sql> DESCRIBE user_ind_columns
Output:
Name
-----------------------------INDEX_NAME
TABLE_NAME
COLUMN_NAME
COLUMN_POSITION
COLUMN_LENGTH
CHAR_LENGTH
DESCEND

Null?
-----------------

Type
-----------------VARCHAR2(30)
VARCHAR2(30)
VARCHAR2(4000)
NUMBER
NUMBER
NUMBER
VARCHAR2(4)

Sql> SELECT INDEX_NAME, COLUMN_NAME,TABLE_NAME FROM user_ind_columns


95 | P a g e

WHERE INDEX_NAME = 'EMP_NAME_IX';


Output:
INDEX_NAME
EMP_NAME_IX
EMP_NAME_IX

COLUMN_NAME
LAST_NAME
FIRST_NAME

TABLE_NAME
EMPLOYEES
EMPLOYEES

Synonym Information:
Sql> DESCRIBE user_synonyms
Output:
Name
-------------------------SYNONYM_NAME
TABLE_OWNER
TABLE_NAME
DB_LINK

Null?
--------------NOT NULL
NOT NULL

Type
-------------------VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (30)
VARCHAR2 (128)

Sql> SELECT * FROM user_synonyms;


Output:
No row selected.
14.4: Adding a comment to a table and querying the dictionary views for comment
information:
Adding Comments to a Table:
You can add comments to a table or column by using the COMMENT statement:
Sql> COMMENT ON TABLE employees IS 'Employee Information';
Output:
Comment created.
Sql> COMMENT ON COLUMN employees.first_name IS 'First name of the employee';
Output:
Comment created.

Comments can be viewed through the data dictionary views:


--ALL_COL_COMMENTS
--USER_COL_COMMENTS
--ALL_TAB_COMMENTS
--USER_TAB_COMMENTS
96 | P a g e

Summary:
Sql> DESCRIBE DICTIONARY
Sql> SELECT * FROM dictionary WHERE table_name = 'USER_OBJECTS';
Sql> SELECT object_name, object_type, created, status FROM user_objects
ORDER BY object_type;
Sql> DESCRIBE user_tables
Sql> SELECT table_name FROM user_tables;
Sql> DESCRIBE user_tab_columns
Sql> SELECT column_name, data_type, data_length, data_precision, data_scale, nullable
FROM user_tab_columns WHERE table_name = 'EMPLOYEES';
Sql> DESCRIBE user_constraints
Sql> SELECT constraint_name, constraint_type, search_condition, r_constraint_name,
delete_rule, status FROM user_constraints WHERE table_name = 'EMPLOYEES';
Sql> DESCRIBE user_cons_columns
Sql> SELECT constraint_name, column_name FROM user_cons_columns
WHERE table_name = 'EMPLOYEES';
Sql> DESCRIBE user_views
Sql> SELECT view_name FROM user_views;
Sql> SELECT text FROM user_views WHERE view_name = 'EMP_DETAILS_VIEW';
Sql> DESCRIBE user_sequences
Sql> SELECT sequence_name, min_value, max_value, increment_by, last_number
FROM user_sequences;
Sql> DESCRIBE user_indexes
Sql> SELECT index_name, table_name,uniqueness FROM user_indexes
WHERE table_name = 'EMPLOYEES';
Sql> SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'DEPARTMENTS';
Sql> DESCRIBE user_ind_columns
Sql> SELECT INDEX_NAME, COLUMN_NAME,TABLE_NAME FROM user_ind_columns
WHERE INDEX_NAME = 'EMP_NAME_IX';
Sql> DESCRIBE user_synonyms
Sql> SELECT * FROM user_synonyms;
Sql> COMMENT ON TABLE employees IS 'Employee Information';
Sql> COMMENT ON COLUMN employees.first_name IS 'First name of the employee';

97 | P a g e

Chapter # 15: Manipulating Large Data Sets


Topics:
15.1: Manipulating data using sub-queries:
Using Sub-queries to Manipulate Data:
You can use sub-queries in data manipulation language (DML) statements to:
Retrieve data using an inline view.
Copy data from one table to another.
Update data in one table based on the values of another table.
Delete rows from one table based on rows in another table.
Retrieving Data Using a Sub-query as Source:
Sql> SELECT department_name, city FROM departments NATURAL JOIN (SELECT
l.location_id, l.city, l.country_id FROM locations l JOIN countries c ON(l.country_id =
c.country_id) JOIN regions USING(region_id) WHERE region_name = 'Europe');
Output:
DEPARTMENT_NAME
------------------------------Human Resources
Sales
Public Relations

CITY
-------------------London
Oxford
Munich

Inserting Using a Sub-query as a Target:


Sql> INSERT INTO (SELECT l.location_id, l.city, l.country_id FROM locations l
JOIN countries c ON(l.country_id = c.country_id) JOIN regions USING(region_id)
WHERE region_name = 'Europe') VALUES (3300, 'Cardiff', 'UK');
Output:
1 row created.
Sql> SELECT location_id, city, country_id FROM locations;
Output:
LOCATION_ID
-------------------3200
3300

CITY
---------------Mexico City
Cardiff

CO
----MX
UK

98 | P a g e

Using the WITH CHECK OPTION Keyword on DML Statements:


The WITH CHECK OPTION keyword prohibits you from changing rows that are not in the
sub-query.
Sql> INSERT INTO ( SELECT location_id, city, country_id FROM locations
WHERE country_id IN (SELECT country_id FROM countries NATURAL JOIN regions
WHERE region_name = 'Europe') WITH CHECK OPTION ) VALUES (3600, 'Washington', 'US');
Output:

15.2: Specifying explicit default values in the INSERT and UPDATE statements:
Overview of the Explicit Default Feature:
Use the DEFAULT keyword as a column value where the default column value is
desired.
This allows the user to control where and when the default value should be applied to
data.
Explicit defaults can be used in INSERT and UPDATE statements.
Using Explicit Default Values:
DEFAULT with INSERT:
Sql> INSERT INTO deptm3 (department_id, department_name, manager_id)
VALUES (300, 'Engineering', DEFAULT);
Output:
1 row created.

DEFAULT with UPDATE:

Sql> UPDATE deptm3 SET manager_id = DEFAULT WHERE department_id = 310;


Output:
1 row updated.
99 | P a g e

Copying Rows from Another Table:


Write your INSERT statement with a sub-query.
Sql> INSERT INTO sales_reps(id, name, salary, commission_pct) SELECT employee_id,
last_name, salary, commission_pct FROM employees WHERE job_id LIKE '%REP%';
Output:
33 rows created.

Do not use the VALUES clause.


Match the number of columns in the INSERT clause with that in the sub-query.

15.3: Using the following types of multitable INSERTs:


Unconditional INSERT
Pivoting INSERT
Conditional INSERT ALL
Conditional INSERT FIRST
Overview of Multitable INSERTS Statements:
Use the INSERTSELECT statement to insert rows into multiple tables as part of a
single DML statement.
Multitable INSERT statements are used in data warehousing systems to transfer data
from one or more operational sources to a set of target tables.
They provide significant performance improvement over:
--Single DML versus multiple INSERTSELECT statements
--Single DML versus a procedure to perform multiple inserts by using the
IF...THEN syntax
Types of Multitable INSERT Statements:
The different types of multitable INSERT statements are:
Unconditional INSERT
Conditional INSERT ALL
Pivoting INSERT
Conditional INSERT FIRST
Unconditional INSERT ALL:
Select the EMPLOYEE_ID, HIRE_DATE, SALARY, and MANAGER_ID values from the
EMPLOYEES table for those employees whose EMPLOYEE_ID is greater than 200.
Insert these values into the SAL_HISTORY and MGR_HISTORY tables by using a
multitable INSERT.
Sql> INSERT ALL INTO sal_history VALUES(EMPID,HIREDATE,SAL) INTO mgr_history
VALUES(EMPID,MGR,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL,
manager_id MGR FROM employees WHERE employee_id > 200;
100 | P a g e

Output:
12 rows created.
Conditional INSERT ALL:
Sql> INSERT ALL WHEN HIREDATE < '01-JAN-95' THEN INTO emp_history
VALUES(EMPID,HIREDATE,SAL) WHEN COMM IS NOT NULL THEN INTO emp_sales
VALUES(EMPID,COMM,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL,
commission_pct COMM FROM employees;
Output:
35 rows created.
Conditional INSERT FIRST:
Sql> INSERT FIRST WHEN salary < 5000 THEN INTO sal_low VALUES (employee_id,
last_name, salary) WHEN salary between 5000 and 10000 THEN INTO sal_mid VALUES
(employee_id, last_name, salary) ELSE INTO sal_high VALUES (employee_id, last_name,
salary) SELECT employee_id, last_name, salary FROM employees;
Output:
107 rows created.
Pivoting INSERT:
Convert the set of sales records from the non-relational database table to relational
format.
Sql> INSERT ALL INTO sales_info VALUES (employee_id,week_id,sales_MON)
INTO sales_info VALUES (employee_id,week_id,sales_TUE) INTO sales_info VALUES
(employee_id,week_id,sales_WED) INTO sales_info VALUES (employee_id, week_id,
sales_THUR) INTO sales_info VALUES (employee_id,week_id, sales_FRI) SELECT
EMPLOYEE_ID, week_id, sales_MON, sales_TUE, sales_WED, sales_THUR,sales_FRI FROM
sales_source_data;
Output:
5 rows created.
15.4: Merging rows in a table:
MERGE Statement:
Provides the ability to conditionally update, insert, or delete data into a database table
Performs an UPDATE if the row exists, and an INSERT if it is a new row:
--Avoids separate updates.
--Increases performance and ease of use.
--Is useful in data warehousing applications.
101 | P a g e

Merging Rows: Example


Insert or update rows in the COPY_EMP3 table to match the EMPLOYEES table.
Sql> MERGE INTO copy_emp3 c USING (SELECT * FROM EMPLOYEES) e
ON (c.employee_id = e.employee_id) WHEN MATCHED THEN UPDATE SET
c.first_name = e.first_name, c.last_name = e.last_name, ... DELETE WHERE
(E.COMMISSION_PCT IS NOT NULL) WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, e.last_name, e.email, e.phone_number,
e.hire_date, e.job_id, e.salary, e.commission_pct, e.manager_id, e.department_id);
Sql> TRUNCATE TABLE copy_emp3;
Output:
Table truncated.
Sql> SELECT * FROM copy_emp3;
Output:
0 row selected.
Sql> MERGE INTO copy_emp3 c USING (SELECT * FROM EMPLOYEES) e
ON (c.employee_id = e.employee_id) WHEN MATCHED THEN UPDATE SET c.first_name =
e.first_name, c.last_name = e.last_name, ... DELETE WHERE (E.COMMISSION_PCT IS NOT
NULL) WHEN NOT MATCHED THEN INSERT VALUES(e.employee_id, e.first_name, ...
Sql> SELECT * FROM copy_emp3;
Output:
20 rows selected.
15.5: Tracking the changes to data over a period of time:
Example of the Flashback Version Query:
Sql> SELECT salary FROM employees3 WHERE employee_id = 107;
Output:
SALARY
-----------4200
Sql> UPDATE employees3 SET salary = salary * 1.30 WHERE employee_id = 107;
Sql> COMMIT;
Output:
102 | P a g e

1 row updated.
Commit complete.

Sql> SELECT salary FROM employees3 VERSIONS BETWEEN SCN MINVALUE AND
MAXVALUE WHERE employee_id = 107;
Output:
SALARY
-----------5460
4200
VERSIONS BETWEEN Clauses:
Sql> SELECT versions_starttime "START_DATE", versions_endtime "END_DATE",
Salary FROM employees VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE last_name = 'Lorentz';
Output:
START_DATE
------------------(null)

END_DATE
---------------(null)

SALARY
-----------4200

Summary:
Sql> SELECT department_name, city FROM departments NATURAL JOIN (SELECT
l.location_id, l.city, l.country_id FROM locations l JOIN countries c ON(l.country_id =
c.country_id) JOIN regions USING(region_id) WHERE region_name = 'Europe');
Sql> INSERT INTO (SELECT l.location_id, l.city, l.country_id FROM locations l
JOIN countries c ON(l.country_id = c.country_id) JOIN regions USING(region_id)
WHERE region_name = 'Europe') VALUES (3300, 'Cardiff', 'UK');
Sql> SELECT location_id, city, country_id FROM locations;
Sql> INSERT INTO ( SELECT location_id, city, country_id FROM locations
WHERE country_id IN (SELECT country_id FROM countries NATURAL JOIN regions
WHERE region_name = 'Europe') WITH CHECK OPTION ) VALUES (3600, 'Washington', 'US');
Sql> INSERT INTO deptm3 (department_id, department_name, manager_id)
VALUES (300, 'Engineering', DEFAULT);
Sql> UPDATE deptm3 SET manager_id = DEFAULT WHERE department_id = 310;
Sql> INSERT INTO sales_reps(id, name, salary, commission_pct) SELECT employee_id,
last_name, salary, commission_pct FROM employees WHERE job_id LIKE '%REP%';
Sql> INSERT ALL INTO sal_history VALUES(EMPID,HIREDATE,SAL) INTO mgr_history
VALUES(EMPID,MGR,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL,
manager_id MGR FROM employees WHERE employee_id > 200;
Sql> INSERT ALL WHEN HIREDATE < '01-JAN-95' THEN INTO emp_history
VALUES(EMPID,HIREDATE,SAL) WHEN COMM IS NOT NULL THEN INTO emp_sales
VALUES(EMPID,COMM,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL,
commission_pct COMM FROM employees;
103 | P a g e

Sql> INSERT FIRST WHEN salary < 5000 THEN INTO sal_low VALUES (employee_id,
last_name, salary) WHEN salary between 5000 and 10000 THEN INTO sal_mid VALUES
(employee_id, last_name, salary) ELSE INTO sal_high VALUES (employee_id, last_name,
salary) SELECT employee_id, last_name, salary FROM employees;
Sql> INSERT ALL INTO sales_info VALUES (employee_id,week_id,sales_MON)
INTO sales_info VALUES (employee_id,week_id,sales_TUE) INTO sales_info VALUES
(employee_id,week_id,sales_WED) INTO sales_info VALUES (employee_id, week_id,
sales_THUR) INTO sales_info VALUES (employee_id,week_id, sales_FRI) SELECT
EMPLOYEE_ID, week_id, sales_MON, sales_TUE, sales_WED, sales_THUR,sales_FRI FROM
sales_source_data; (ERROR)
Sql> MERGE INTO copy_emp3 c USING (SELECT * FROM EMPLOYEES) e
ON (c.employee_id = e.employee_id) WHEN MATCHED THEN UPDATE SET
c.first_name = e.first_name, c.last_name = e.last_name, ... DELETE WHERE
(E.COMMISSION_PCT IS NOT NULL) WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, e.last_name, e.email, e.phone_number,
e.hire_date, e.job_id, e.salary, e.commission_pct, e.manager_id, e.department_id);
Sql> TRUNCATE TABLE copy_emp3;
Sql> SELECT * FROM copy_emp3;
Sql> MERGE INTO copy_emp3 c USING (SELECT * FROM EMPLOYEES) e
ON (c.employee_id = e.employee_id) WHEN MATCHED THEN UPDATE SET c.first_name =
e.first_name, c.last_name = e.last_name, ... DELETE WHERE (E.COMMISSION_PCT IS NOT
NULL) WHEN NOT MATCHED THEN INSERT VALUES(e.employee_id, e.first_name, ...
Sql> SELECT * FROM copy_emp3;
Sql> SELECT salary FROM employees3 WHERE employee_id = 107;
Sql> UPDATE employees3 SET salary = salary * 1.30 WHERE employee_id = 107;
Sql> COMMIT;
Sql> SELECT salary FROM employees3 VERSIONS BETWEEN SCN MINVALUE AND
MAXVALUE WHERE employee_id = 107;
Sql> SELECT versions_starttime "START_DATE", versions_endtime "END_DATE",
Salary FROM employees VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE last_name = 'Lorentz';

104 | P a g e

Chapter # 16: Managing Data in Different Time Zones


Topics:
Use data types similar to DATE that store fractional seconds and track time zones
Use data types that store the difference between two datetime values
Use the following datetime functions:
--CURRENT_DATE
--EXTRACT
--CURRENT_TIMESTAMP
--TZ_OFFSET
--LOCALTIMESTAMP
--TO_TIMESTAMP
--DBTIMEZONE
--TO_YMINTERVAL
--SESSIONTIMEZONE
--TO_DSINTERVAL
--FROM_TZ
16.1: CURRENT_DATE, CURRENT_TIMESTAMP, and LOCALTIMESTAMP:
TIME_ZONE Session Parameter:
TIME_ZONE may be set to:
An absolute offset
Database time zone
OS local time zone
A named region
Sql> ALTER SESSION SET TIME_ZONE = '-05:00';
Output:
Session altered.
Sql> ALTER SESSION SET TIME_ZONE = dbtimezone;
Output:
Session altered.
Sql> ALTER SESSION SET TIME_ZONE = local;
Output:
Session altered.
Sql> ALTER SESSION SET TIME_ZONE = 'America/New_York';

105 | P a g e

Output:
Session altered.
CURRENT_DATE, CURRENT_TIMESTAMP, and LOCALTIMESTAMP:
CURRENT_DATE:
--Returns the current date from the user session.
--Has a data type of DATE.
CURRENT_TIMESTAMP:
--Returns the current date and time from the user session.
--Has a data type of TIMESTAMP WITH TIME ZONE.
LOCALTIMESTAMP:
--Returns the current date and time from the user session.
--Has a data type of TIMESTAMP.
Comparing Date and Time in a Sessions Time Zone:
The TIME_ZONE parameter is set to 5:00 and then SELECT statements for each date
and time is executed to compare differences.
Sql> ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
Output:
Session altered.
Sql> ALTER SESSION SET TIME_ZONE = '-5:00';
Output:
Session altered.
Sql> SELECT SESSIONTIMEZONE, CURRENT_DATE FROM DUAL;
Output:
SESSIONTIMEZONE
-----------------------------05:00

CURRENT_DATE
-----------------------12-JUL-2011 06:55:59

Sql> SELECT SESSIONTIMEZONE, CURRENT_TIMESTAMP FROM DUAL;


Output:
SESSIONTIMEZONE
-----------------------------05:00

CURRENT_TIMESTAMP
-------------------------------------------------12-JUL-11 06.57.19.515000 AM -05:00

Sql> SELECT SESSIONTIMEZONE, LOCALTIMESTAMP FROM DUAL;


Output:
106 | P a g e

SESSIONTIMEZONE
-----------------------------05:00

LOCALTIMESTAMP
----------------------------------------12-JUL-11 06.59.02.375000 AM

DBTIMEZONE and SESSIONTIMEZONE:


Display the value of the database time zone:
Sql> SELECT DBTIMEZONE FROM DUAL;
Output:
DBTIMEZONE
-------------------+00:00

Display the value of the sessions time zone:

Sql> SELECT SESSIONTIMEZONE FROM DUAL;


Output:
SESSIONTIMEZONE
----------------------------+05:00
TIMESTAMP Data Types:
Data Type

Fields

TIMESTAMP
TIMESTAMP WITH
TIME ZONE
TIMESTAMP WITH
LOCAL TIME ZONE

Year, Month, Day, Hour, Minute, Second with fractional seconds


Same as the TIMESTAMP data type; also includes: TIMEZONE_HOUR,
and TIMEZONE_MINUTE or TIMEZONE_REGION
Same as the TIMESTAMP data type; also includes a time zone offset in
its value

TIMESTAMP Fields:
Datetime Field

Valid Values

YEAR
MONTH
DAY
HOUR
MINUTE
SECOND
TIMEZONE_HOUR
TIMEZONE_MINUTE

4712 to 9999 (excluding year 0)


01 to 12
01 to 31
00 to 23
00 to 59
00 to 59.9(N) where 9(N) is precision
12 to 14
00 to 59

107 | P a g e

Difference between DATE and TIMESTAMP:


when hire_date is of type DATE.
Sql> SELECT hire_date FROM employees;

Output:
HIRE_DATE
----------------21-JUN-07
13-JAN-08
17-SEP-03

when hire_date is of type TIMESTAMP.

Sql> ALTER TABLE employees MODIFY hire_date TIMESTAMP;


Output:
Table altered.
Sql> SELECT hire_date FROM employees;
Output:
HIRE_DATE
------------------------------------------21-JUN-07 12.00.00.000000 AM
13-JAN-08 12.00.00.000000 AM
17-SEP-03 12.00.00.000000 AM
Comparing TIMESTAMP Data Types:
Sql> CREATE TABLE web_orders (order_date TIMESTAMP WITH TIME ZONE, delivery_time
TIMESTAMP WITH LOCAL TIME ZONE);
Output:
Table created.
Sql> INSERT INTO web_orders values (current_date, current_timestamp + 2);
Output:
1 row created.
Sql> SELECT * FROM web_orders;
108 | P a g e

Output:
ORDER_DATE
---------------------------------------------------13-JUL-11 10.10.18.000000 AM +05:00

DELIVERY_TIME
-----------------------------------------15-JUL-11 10.10.18.000000 AM

16.2: INTERVAL data types:


INTERVAL Data Types:
INTERVAL data types are used to store the difference between two datetime values.
There are two classes of intervals:
--Year-month
--Day-time
The precision of the interval is:
--The actual subset of fields that constitutes an interval
--Specified in the interval qualifier
Data Type
INTERVAL YEAR TO MONTH
INTERVAL DAY TO SECOND

Fields
Year, Month
Days, Hour, Minute, Second with fractional seconds

INTERVAL Fields:
INTERVAL Field
YEAR
MONTH
DAY
HOUR
MINUTE
SECOND

Valid Values for Interval


Any positive or negative integer
00 to 11
Any positive or negative integer
00 to 23
00 to 59
00 to 59.9(N) where 9(N) is precision

INTERVAL YEAR TO MONTH: Example


Sql> CREATE TABLE warranty (prod_id number, warranty_time INTERVAL YEAR(3) TO
MONTH);
Output:
Table created.
Sql> INSERT INTO warranty VALUES (123, INTERVAL '8' MONTH);

Output:

109 | P a g e

1 row created.
Sql> INSERT INTO warranty VALUES (155, INTERVAL '200' YEAR (3));
Output:
1 row created.
Sql> INSERT INTO warranty VALUES (678, '200-11');
Output:
1 row created.
Sql> SELECT * FROM warranty;
Output:
PROD_ID
------------123
155
678

WARRANTY_TIME
-------------------------+000-08
+200-00
+200-11

INTERVAL DAY TO SECOND Data Type: Example


Sql> CREATE TABLE lab ( exp_id number, test_time INTERVAL DAY(2) TO SECOND);
Output:
Table created.
Sql> INSERT INTO lab VALUES (100012, '90 00:00:00');
Output:
1 row created.
Sql> INSERT INTO lab VALUES (56098, INTERVAL '6 03:30:16' DAY TO SECOND);
Output:
1 row created.
Sql> SELECT * FROM lab;
Output:
EXP_ID
---------100012
56098

TEST_TIME
--------------------------+90 00:00:00.000000
+06 03:30:16.000000
110 | P a g e

16.3: Using the following functions:


EXTRACT
TZ_OFFSET
FROM_TZ
TO_TIMESTAMP
TO_YMINTERVAL
TO_DSINTERVAL
EXTRACT:
Display the YEAR component from the SYSDATE.
Sql> SELECT EXTRACT (YEAR FROM SYSDATE) FROM DUAL;
Output:
EXTRACT (YEARFROMSYSDATE)
-----------------------------------------------2011

Display the MONTH component from the HIRE_DATE for those employees whose
MANAGER_ID is 100.

Sql> SELECT last_name, hire_date, EXTRACT (MONTH FROM HIRE_DATE) FROM


employees WHERE manager_id = 100;
Output:
LAST_NAME
----------------Hartstein

HIRE_DATE
-----------------------------------------17-FEB-04 12.00.00.000000 AM

EXTRACT (MONTHFROMHIRE_DATE)
----------------------------------------------------2

TZ_OFFSET:
Display the time zone offset for the 'US/Eastern', 'Canada/Yukon' and 'Europe/London'
time zones:
Sql> SELECT TZ_OFFSET ('US/Eastern'), TZ_OFFSET ('Canada/Yukon'),
TZ_OFFSET ('Europe/London') FROM DUAL;
Output:
TZ_OFFS
-------------04:00

TZ_OFFS
--------------07:00

TZ_OFFS
-------------+01:00

FROM_TZ:
Display the TIMESTAMP value '2000-03-28 08:00:00' as a TIMESTAMP WITH TIME
ZONE value for the 'Australia/North' time zone region.

111 | P a g e

Sql> SELECT FROM_TZ (TIMESTAMP '2000-07-12 08:00:00', 'Australia/North') FROM DUAL;


Output:
FROM_TZ (TIMESTAMP'2000-07-1208:00:00','AUSTRALIA/NORTH')
--------------------------------------------------------------------------------------------12-JUL-00 08.00.00.000000000 AM AUSTRALIA/NORTH
TO_TIMESTAMP:
Display the character string '2007-03-06 11:00:00' as a TIMESTAMP value:
Sql> SELECT TO_TIMESTAMP ('2007-03-06 11:00:00', 'YYYY-MM-DD HH: MI: SS) FROM
DUAL;
Output:
TO_TIMESTAMP ('2007-03-0611:00:00','YYYY-MM-DDHH: MI: SS)
------------------------------------------------------------------------------------------06-MAR-07 11.00.00.000000000 AM
TO_YMINTERVAL:
Display a date that is one year and two months after the hire date for the employees
working in the department with the DEPARTMENT_ID 20.
Sql> SELECT hire_date, hire_date + TO_YMINTERVAL ('01-02') AS
HIRE_DATE_YMININTERVAL FROM employees WHERE department_id = 20;
Output:
HIRE_DATE
-----------------------------------------17-FEB-04 12.00.00.000000 AM
17-AUG-05 12.00.00.000000 AM

HIRE_DATE_YMININTERVAL
----------------------------------------------17-APR-05 12.00.00.000000000 AM
17-OCT-06 12.00.00.000000000 AM

TO_DSINTERVAL:
Display a date that is 100 days and 10 hours after the hire date for all the employees.
Sql> SELECT last_name, TO_CHAR (hire_date, 'mm-dd-yy:hh:mi:ss') hire_date, TO_CHAR
(hire_date + TO_DSINTERVAL('100 10:00:00'), 'mm-dd-yy:hh:mi:ss') hiredate2 FROM
employees;
Output:
LAST_NAME
-----------------OConnell
Grant
Whalen

HIRE_DATE
----------------06-21-07:12:00:00
01-13-08:12:00:00
09-17-03:12:00:00

HIREDATE2
----------------09-29-07:10:00:00
04-22-08:10:00:00
12-26-03:10:00:00

112 | P a g e

Daylight Saving Time:


First Sunday in April
--Time jumps from 01:59:59 AM to 03:00:00 AM.
-- Values from 02:00:00 AM to 02:59:59 AM are not valid.
Last Sunday in October
--Time jumps from 02:00:00 AM to 01:00:01 AM.
--Values from 01:00:01 AM to 02:00:00 AM are ambiguous because they are
visited twice.
Summary:
Sql> ALTER SESSION SET TIME_ZONE = '-05:00';
Sql> ALTER SESSION SET TIME_ZONE = dbtimezone;
Sql> ALTER SESSION SET TIME_ZONE = local;
Sql> ALTER SESSION SET TIME_ZONE = 'America/New_York';
Sql> ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
Sql> ALTER SESSION SET TIME_ZONE = '-5:00';
Sql> SELECT SESSIONTIMEZONE, CURRENT_DATE FROM DUAL;
Sql> SELECT SESSIONTIMEZONE, CURRENT_TIMESTAMP FROM DUAL;
Sql> SELECT SESSIONTIMEZONE, LOCALTIMESTAMP FROM DUAL;
Sql> SELECT DBTIMEZONE FROM DUAL;
Sql> SELECT SESSIONTIMEZONE FROM DUAL;
Sql> SELECT hire_date FROM employees;
Sql> ALTER TABLE employees MODIFY hire_date TIMESTAMP;
Sql> SELECT hire_date FROM employees;
Sql> CREATE TABLE web_orders (order_date TIMESTAMP WITH TIME ZONE, delivery_time
TIMESTAMP WITH LOCAL TIME ZONE);
Sql> INSERT INTO web_orders values (current_date, current_timestamp + 2);
Sql> SELECT * FROM web_orders;
Sql> CREATE TABLE warranty (prod_id number, warranty_time INTERVAL YEAR(3) TO
MONTH);
Sql> INSERT INTO warranty VALUES (123, INTERVAL '8' MONTH);
Sql> INSERT INTO warranty VALUES (155, INTERVAL '200' YEAR (3));
Sql> INSERT INTO warranty VALUES (678, '200-11');
Sql> SELECT * FROM warranty;
Sql> CREATE TABLE lab ( exp_id number, test_time INTERVAL DAY(2) TO SECOND);
Sql> INSERT INTO lab VALUES (100012, '90 00:00:00');
Sql> INSERT INTO lab VALUES (56098, INTERVAL '6 03:30:16' DAY TO SECOND);
Sql> SELECT * FROM lab;
Sql> SELECT EXTRACT (YEAR FROM SYSDATE) FROM DUAL;
Sql> SELECT last_name, hire_date, EXTRACT (MONTH FROM HIRE_DATE) FROM
employees WHERE manager_id = 100;
Sql> SELECT TZ_OFFSET ('US/Eastern'), TZ_OFFSET ('Canada/Yukon'),
TZ_OFFSET ('Europe/London') FROM DUAL;
Sql> SELECT FROM_TZ (TIMESTAMP '2000-07-12 08:00:00', 'Australia/North') FROM DUAL;
Sql> SELECT TO_TIMESTAMP ('2007-03-06 11:00:00', 'YYYY-MM-DD HH: MI: SS) FROM
DUAL;
Sql> SELECT hire_date, hire_date + TO_YMINTERVAL ('01-02') AS
HIRE_DATE_YMININTERVAL FROM employees WHERE department_id = 20;

113 | P a g e

Sql> SELECT last_name, TO_CHAR (hire_date, 'mm-dd-yy:hh:mi:ss') hire_date, TO_CHAR


(hire_date + TO_DSINTERVAL('100 10:00:00'), 'mm-dd-yy:hh:mi:ss') hiredate2 FROM
employees;

Chapter # 17: Retrieving Data Using Sub-queries


Topics:
17.1: Writing a multiple-column sub-query:
Multiple-Column Sub-queries:
Each row of the main query is compared to values from a multiple-row and multiplecolumn sub-query.
Column Comparisons:
Multiple-column comparisons involving sub-queries can be:
Non-pairwise comparisons
Pairwise comparisons
Pairwise Comparison Sub-query:
Display the details of the employees who are managed by the same manager and work in the
same department as employees with the first name of John.
Sql> SELECT employee_id, manager_id, department_id FROM empl_demo
WHERE (manager_id, department_id) IN (SELECT manager_id, department_id FROM
empl_demo WHERE first_name = 'John') AND first_name <> 'John';
Output:
EMPLOYEE_ID
--------------------149
148
147

MANAGER_ID
-------------------100
100
100

DEPARTMENT_ID
------------------------80
80
80

Non-pairwise Comparison Sub-query:


Display the details of the employees who are managed by the same manager as the employees
with the first name of John and work in the same department as the employees with the first
name of John.

114 | P a g e

Sql> SELECT employee_id, manager_id, department_id FROM empl_demo WHERE


manager_id IN (SELECT manager_id FROM empl_demo WHERE first_name = 'John') AND
department_id IN (SELECT department_id FROM empl_demo WHERE first_name = 'John')
AND first_name <> 'John';
Output:
EMPLOYEE_ID
--------------------109
111
112

MANAGER_ID
-------------------108
108
108

DEPARTMENT_ID
------------------------100
100
100

17.2: Using scalar sub-queries in SQL:


Scalar Sub-query Expressions:
A scalar sub-query expression is a sub-query that returns exactly one column value from
one row.
Scalar sub-queries can be used in:
--The condition and expression part of DECODE and CASE.
--All clauses of SELECT except GROUP BY.
--The SET clause and WHERE clause of an UPDATE statement.
Scalar Sub-queries: Examples
Scalar sub-queries in CASE expressions:
Sql> SELECT employee_id, last_name, (CASE WHEN department_id = (SELECT
department_id FROM departments WHERE location_id = 1800) THEN 'Canada' ELSE 'USA'
END) location FROM employees;
Output:
EMPLOYEE_ID
--------------------198
199
201

LAST_NAME
------------------OConnell
Grant
Hartstein

LOCATION
--------------USA
USA
Canada

Scalar sub-queries in the ORDER BY clause:

Sql> SELECT employee_id, last_name FROM employees e ORDER BY (SELECT


department_name FROM departments d WHERE e.department_id = d.department_id);
Output:
EMPLOYEE_ID
--------------------191
192

LAST_NAME
-------------------Perkins
Bell
115 | P a g e

193

Everett

17.3: Solving problems with correlated sub-queries:


Correlated Sub-queries:
GET
Candidate row from outer query

EXECUTE
Inner query using candidate row value

USE
Values from inner query to qualify or
to disqualify candidate row
Correlated Sub-queries:
The sub-query references a column from a table in the parent query.
Using Correlated Sub-queries:
Find all employees who earn more than the average salary in their department.
Sql> SELECT last_name, salary, department_id FROM employees outer WHERE salary >
(SELECT AVG(salary) FROM employees WHERE department_id = outer.department_id);
Output:
LAST_NAME
SALARY
DEPARTMENT_ID
----------------------------------------------------Hartstein
13000
20
Higgins
12008
110
King
24000
90
Each time a row from the outer query is processed, the inner query is evaluated.
116 | P a g e

Using Correlated Sub-queries:


Display details of those employees who have changed jobs at least twice.
Sql> SELECT e.employee_id, last_name,e.job_id FROM employees e WHERE 2 <= (SELECT
COUNT(*) FROM job_history WHERE employee_id = e.employee_id);
Output:
EMPLOYEE_ID
LAST_NAME
JOB_ID
--------------------------------------------------200
Whalen
AD_ASST
101
Kochhar
AD_VP
176
Taylor
SA_REP
Correlated UPDATE:
Use a correlated sub-query to update rows in one table based on rows from another
table.
Denormalize the EMPL6 table by adding a column to store the department name.
Populate the table by using a correlated update.
Sql> ALTER TABLE empl6 ADD(department_name VARCHAR2(25));
Output:
Table altered.
Sql> UPDATE empl6 e SET department_name = (SELECT department_name FROM
departments d WHERE e.department_id = d.department_id);
Output:
107 rows updated.
Correlated DELETE:
Use a correlated sub-query to delete rows in one table based on rows from another
table.
Use a correlated sub-query to delete only those rows from the EMPL6 table that also
exist in the EMP_HISTORY table.
Sql> DELETE FROM empl6 E WHERE employee_id = (SELECT employee_id
FROM emp_history WHERE employee_id = E.employee_id);
Output:
0 row deleted.
17.4: Using the EXISTS and NOT EXISTS operators:
Using the EXISTS Operator:
The EXISTS operator tests for existence of rows in the results set of the sub-query.
117 | P a g e

If a sub-query row value is found:


--The search does not continue in the inner query
--The condition is flagged TRUE
If a sub-query row value is not found:
--The condition is flagged FALSE
--The search continues in the inner query

Find Employees Who Have at Least One Person Reporting to Them:


Sql> SELECT employee_id, last_name, job_id, department_id FROM employees outer
WHERE EXISTS (SELECT 'X' FROM employees WHERE manager_id = outer.employee_id);

Output:
EMPLOYEE_ID
--------------------201
205
100

LAST_NAME
-----------------Hartstein
Higgins
King

JOB_ID
--------------MK_MAN
AC_MGR
AD_PRES

DEPARTMENT_ID
------------------------20
110
90

Find All Departments That Do Not Have Any Employees:


Sql> SELECT department_id, department_name FROM departments d WHERE NOT EXISTS
(SELECT 'X' FROM employees WHERE department_id = d.department_id);
Output:
DEPARTMENT_ID
------------------------230
240
250

DEPARTMENT_NAME
-------------------------------IT Helpdesk
Government Sales
Retail Sales

17.5: Using the WITH clause:


WITH Clause:
Using the WITH clause, you can use the same query block in a SELECT statement
when it occurs more than once within a complex query.
The WITH clause retrieves the results of a query block and stores it in the users
temporary tablespace.
The WITH clause may improve performance.
WITH Clause: Example
Using the WITH clause, write a query to display the department name and total salaries for
those departments whose total salary is greater than the average salary across departments.
Sql> WITH dept_costs AS (SELECT d.department_name, SUM (e.salary) AS dept_total FROM
employees e JOIN departments d ON e.department_id = d.department_id GROUP BY
118 | P a g e

d.department_name), avg_cost AS (SELECT SUM (dept_total)/COUNT (*) AS dept_avg FROM


dept_costs) SELECT * FROM dept_costs WHERE dept_total > (SELECT dept_avg FROM
avg_cost) ORDER BY department_name;
Output:
DEPARTMENT_NAME
-----------------------------Sales
Shipping

DEPT_TOTAL
-------------------304500
156400

Summary:
Sql> SELECT employee_id, manager_id, department_id FROM empl_demo
WHERE (manager_id, department_id) IN (SELECT manager_id, department_id FROM
empl_demo WHERE first_name = 'John') AND first_name <> 'John';
Sql> SELECT employee_id, manager_id, department_id FROM empl_demo WHERE
manager_id IN (SELECT manager_id FROM empl_demo WHERE first_name = 'John') AND
department_id IN (SELECT department_id FROM empl_demo WHERE first_name = 'John')
AND first_name <> 'John';
Sql> SELECT employee_id, last_name, (CASE WHEN department_id = (SELECT
department_id FROM departments WHERE location_id = 1800) THEN 'Canada' ELSE 'USA'
END) location FROM employees;
Sql> SELECT employee_id, last_name FROM employees e ORDER BY (SELECT
department_name FROM departments d WHERE e.department_id = d.department_id);
Sql> SELECT last_name, salary, department_id FROM employees outer WHERE salary >
(SELECT AVG(salary) FROM employees WHERE department_id = outer.department_id);
Sql> SELECT e.employee_id, last_name,e.job_id FROM employees e WHERE 2 <= (SELECT
COUNT(*) FROM job_history WHERE employee_id = e.employee_id);
Sql> ALTER TABLE empl6 ADD(department_name VARCHAR2(25));
Sql> UPDATE empl6 e SET department_name = (SELECT department_name FROM
departments d WHERE e.department_id = d.department_id);
Sql> DELETE FROM empl6 E WHERE employee_id = (SELECT employee_id
FROM emp_history WHERE employee_id = E.employee_id);
Sql> SELECT employee_id, last_name, job_id, department_id FROM employees outer
WHERE EXISTS (SELECT 'X' FROM employees WHERE manager_id = outer.employee_id);
Sql> SELECT department_id, department_name FROM departments d WHERE NOT EXISTS
(SELECT 'X' FROM employees WHERE department_id = d.department_id);
Sql> WITH dept_costs AS (SELECT d.department_name, SUM (e.salary) AS dept_total FROM
employees e JOIN departments d ON e.department_id = d.department_id GROUP BY
d.department_name), avg_cost AS (SELECT SUM (dept_total)/COUNT (*) AS dept_avg FROM
dept_costs) SELECT * FROM dept_costs WHERE dept_total > (SELECT dept_avg FROM
avg_cost) ORDER BY department_name;

119 | P a g e

Chapter # 18: Regular Expression Support


Topics:
18.1: Introduction to regular expressions:
What Are Regular Expressions?
You use regular expressions to search for (and manipulate) simple and complex patterns
in string data by using standard syntax conventions.
You use a set of SQL functions and conditions to search for and manipulate strings in
SQL and PL/SQL.
You specify a regular expression by using:
--Metacharacters, which are operators that specify the search algorithms.
--Literals, which are the characters for which you are searching.
Benefits of Using Regular Expressions:
Regular expressions enable you to implement complex match logic in the database with the
following benefits:
By centralizing match logic in Oracle Database, you avoid intensive string processing of
SQL results sets by middletier applications.
Using server-side regular expressions to enforce constraints, you eliminate the need to
code data validation logic on the client.
The built-in SQL and PL/SQL regular expression functions and conditions make string
manipulations more powerful and easier than in previous releases of Oracle Database
10g.
Using the Regular Expressions Functions and Conditions in SQL and PL/SQL:

Function or
Condition Name

Description

120 | P a g e

REGEXP_LIKE

Is similar to the LIKE operator, but performs regular expression


matching instead of simple pattern matching (condition)
REGEXP_REPLACE Searches for a regular expression pattern and replaces it with a
replacement string
REGEXP_INSTR
Searches a string for a regular expression pattern and returns the
position where the match is found
REGEXP_SUBSTR
Searches for a regular expression pattern within a given string and
extracts the matched substring
REGEXP_COUNT
Returns the number of times a pattern match is found in an input
sting

18.2: Using meta-characters with regular expressions:


What Are Meta-characters?
Metacharacters are special characters that have a special meaning such as a wildcard,
a repeating character, a non-matching character, or a range of characters.
You can use several predefined meta-character symbols in the pattern matching.
For example, the ^ (f|ht)tps?:$ regular expression searches for the following from the
beginning of the string:
--The literals f or ht
--The t literal
--The p literal, optionally followed by the s literal
--The colon : literal at the end of the string
Using Meta-characters with Regular Expressions:
Syntax
.
+
?
*
{m}
{m, }
{m,n}
[]
|
( ... )

Description
Matches any character in the supported character set, except NULL
Matches one or more occurrences
Matches zero or one occurrence
Matches zero or more occurrences of the preceding subexpression
Matches exactly m occurrences of the preceding expression
Matches at least m occurrences of the preceding subexpression
Matches at least m, but not more than n, occurrences of the preceding
subexpression
Matches any single character in the list within the brackets
Matches one of the alternatives
Treats the enclosed expression within the parentheses as a unit. The
subexpression can be a string of literals or a complex expression
containingoperators.
121 | P a g e

Syntax
^
$
\
\n

\d
[:class:]
[^:class:]

Description
Matches the beginning of a string
Matches the end of a string
Treats the subsequent metacharacter in the expression as a literal
Matches the nth (19) preceding subexpression of whatever is grouped
within parentheses. The parentheses cause an expression to be
remembered; a backreference refers to it.
A digit character
Matches any character belonging to the specified POSIX character class
Matches any single character not in the list within the brackets

18.3: Using the regular expressions functions:


--REGEXP_LIKE
--REGEXP_REPLACE
--REGEXP_INSTR
--REGEXP_SUBSTR
Performing a Basic Search Using the REGEXP_LIKE Condition:
Sql> SELECT first_name, last_name FROM employees WHERE REGEXP_LIKE (first_name,
'^Ste(v|ph)en$');
Output:
FIRST_NAME
------------------Steven
Steven
Stephen

LAST_NAME
-----------------King
Markle
Stiles

Replacing Patterns Using the REGEXP_REPLACE Function:


Sql> SELECT REGEXP_REPLACE(phone_number, \.',-') AS phone FROM employees;
Output:
PHONE
-----------------650-507-9833
650-507-9844
515-123-4444
Finding Patterns Using the REGEXP_INSTR Function:
122 | P a g e

Sql> SELECT street_address, REGEXP_INSTR (street_address,'[[:alpha:]]') AS


First_Alpha_Position FROM locations;
Output:
STREET_ADDRESS
-------------------------------1297 Via Cola di Rie
93091 Calle della Testa
2017 Shinjuku-ku

FIRST_ALPHA_POSITION
-----------------------------------6
7
6

Extracting Substrings Using the REGEXP_SUBSTR Function:


Sql> SELECT REGEXP_SUBSTR (street_address , ' [^ ]+ ') AS Road FROM locations;

Output:
ROAD
--------Via
Calle
18.4: Accessing sub-expressions:
Using Sub-expressions with Regular Expression Support:
Sql> SELECT REGEXP_INSTR
('0123456789', -- source char or search value
'(123)(4(56)(78))', -- regular expression patterns
1, -- position to start searching
1, -- occurrence
0, -- return option
'i', -- match option (case insensitive)
1) -- sub-expression on which to search
"Position" FROM dual;
Output:
Position
----------2
Why Access the nth Sub-expression?
A more realistic use: DNA sequencing
You may need to find a specific subpattern that identifies a protein needed for immunity
in the mouse DNA.
123 | P a g e

Sql> SELECT REGEXP_INSTR ('ccacctttccctccactcctcacgttctcacctgtaaagcgtccctc


cctcatccccatgcccccttaccctgcagggtagagtaggctagaaaccagagagctccaagc
tccatctgtggagaggtgccatccttgggctgcagagagaggagaatttgccccaaagctgcc
tgcagagcttcaccacccttagtctcacaaagccttgagttcatagcatttcttgagttttca
ccctgcccagcaggacactgcagcacccaaagggcttcccaggagtagggttgccctcaagag
gctcttgggtctgatggccacatcctggaattgttttcaagttgatggtcacagccctgaggc
atgtaggggcgtggggatgcgctctgctctgctctcctctcctgaacccctgaaccctctggc
taccccagagcacttagagccag',
'(gtc(tcac)(aaag))',
1, 1, 0, 'i', 1) "Position" FROM dual;
Output:
Position
----------198

REGEXP_SUBSTR: Example
Sql> SELECT REGEXP_SUBSTR ('acgctgcactgca', -- source char or search value
'acg(.*)gca', -- regular expression pattern
1, -- position to start searching
1, -- occurrence
'i', -- match option (case insensitive)
1) -- sub-expression
"Value" FROM dual;
Output:
Value
--------ctgcact
18.5: Using the REGEXP_COUNT function:
Using the REGEXP_COUNT Function:
Sql> SELECT REGEXP_COUNT
( 'ccacctttccctccactcctcacgttctcacctgtaaagcgtccctccctcatccccatgcccccttaccctgcag
ggtagagtaggctagaaaccagagagctccaagctccatctgtggagaggtgccatccttgggctgcagagagaggag
aatttgccccaaagctgcctgcagagcttcaccacccttagtctcacaaagccttgagttcatagcatttcttgagtt
ttcaccctgcccagcaggacactgcagcacccaaagggcttcccaggagtagggttgccctcaagaggctcttgggtc
tgatggccacatcctggaattgttttcaagttgatggtcacagccctgaggcatgtaggggcgtggggatgcgctctg
ctctgctctcctctcctgaacccctgaaccctctggctaccccagagcacttagagccag,
gtc) AS Count FROM dual;
Output:
124 | P a g e

COUNT
----------4
Regular Expressions and Check Constraints: Examples
Sql> ALTER TABLE emp8 ADD CONSTRAINT email_addr CHECK (REGEXP_LIKE (email,'@'))
NOVALIDATE;
Output:
Table altered.

Sql> INSERT INTO emp8 VALUES (500,'Christian','Patel','ChrisP2creme.com', 1234567890,'12Jan-2004','HR_REP', 2000, null, 102, 40);
Output:

125 | P a g e

Summary:
Sql> SELECT first_name, last_name FROM employees WHERE REGEXP_LIKE (first_name,
'^Ste(v|ph)en$');
Sql> SELECT REGEXP_REPLACE(phone_number, \.',-') AS phone FROM employees;
Sql> SELECT street_address, REGEXP_INSTR (street_address,'[[:alpha:]]') AS
First_Alpha_Position FROM locations;
Sql> SELECT REGEXP_SUBSTR (street_address , ' [^ ]+ ') AS Road FROM locations;
Sql> SELECT REGEXP_INSTR
('0123456789', -- source char or search value
'(123)(4(56)(78))', -- regular expression patterns
1, -- position to start searching
1, -- occurrence
0, -- return option
'i', -- match option (case insensitive)
1) -- sub-expression on which to search
"Position" FROM dual;
Sql> SELECT REGEXP_INSTR ('ccacctttccctccactcctcacgttctcacctgtaaagcgtccctc
cctcatccccatgcccccttaccctgcagggtagagtaggctagaaaccagagagctccaagc
tccatctgtggagaggtgccatccttgggctgcagagagaggagaatttgccccaaagctgcc
tgcagagcttcaccacccttagtctcacaaagccttgagttcatagcatttcttgagttttca
ccctgcccagcaggacactgcagcacccaaagggcttcccaggagtagggttgccctcaagag
gctcttgggtctgatggccacatcctggaattgttttcaagttgatggtcacagccctgaggc
atgtaggggcgtggggatgcgctctgctctgctctcctctcctgaacccctgaaccctctggc
taccccagagcacttagagccag',
'(gtc(tcac)(aaag))',
1, 1, 0, 'i', 1) "Position" FROM dual;
Sql> SELECT REGEXP_SUBSTR ('acgctgcactgca', -- source char or search value
'acg(.*)gca', -- regular expression pattern
1, -- position to start searching
1, -- occurrence
'i', -- match option (case insensitive)
126 | P a g e

1) -- sub-expression
"Value" FROM dual;
Sql> SELECT REGEXP_COUNT
( 'ccacctttccctccactcctcacgttctcacctgtaaagcgtccctccctcatccccatgcccccttaccctgcag
ggtagagtaggctagaaaccagagagctccaagctccatctgtggagaggtgccatccttgggctgcagagagaggag
aatttgccccaaagctgcctgcagagcttcaccacccttagtctcacaaagccttgagttcatagcatttcttgagtt
ttcaccctgcccagcaggacactgcagcacccaaagggcttcccaggagtagggttgccctcaagaggctcttgggtc
tgatggccacatcctggaattgttttcaagttgatggtcacagccctgaggcatgtaggggcgtggggatgcgctctg
ctctgctctcctctcctgaacccctgaaccctctggctaccccagagcacttagagccag,
gtc) AS Count FROM dual;
Sql> ALTER TABLE emp8 ADD CONSTRAINT email_addr CHECK (REGEXP_LIKE (email,'@'))
NOVALIDATE;
Sql> INSERT INTO emp8 VALUES (500,'Christian','Patel','ChrisP2creme.com', 1234567890,'12Jan-2004','HR_REP', 2000, null, 102, 40); (ERROR)

127 | P a g e

Você também pode gostar