SQL and SQL Plus Basics
SQL and SQL Plus Basics
Introduction to
SQL for Oracle
NORTHERN ARIZONA UNIVERSITY
INTRODUCTION
MODULE 1 MODUL E 5
Operators 11
Comparison Operators 11
Creating Triggers 45
SQLPlus Worksheet 52
MODULE 4
GROUP BY Clause 25
ORDER BY Clause 28
HAVING Clause 30
Joining Tables 31
S O L U T I O N S T O E X E R C I S E S A R E I N T H E A P P E N D I X
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Introduction
Introduction
T
his course is designed to help you quickly learn the basics of SQL and
SQL*PLUS queries. We will start from the beginning, assuming that you have
no experience with SQL and take you through the steps. By the end of this
course, you should be able to perform simple operations using SQL. This
course has no prerequisites and you will soon discover that basic SQL is easy to learn
and use.
About the Solution Center and the Software, Web Applications, & Training Teams
I T S S O L U T I O N
This manual was created for you by the ITS Software, Web Applications, & Training
C E N T E R team. The Software, Web Applications, & Training (SWAT) team works with the
Phone: (520) 523-1511 Solution Center to provide our customers the best service possible. The mission of the
Fax: (520) 523-9259
Solution Center and the SWAT team is to maintain or increase the productivity of
NAU staff and faculty by providing professional development and computing
http://www.nau.edu/its
solutions from a central point of contact, and acting as an advocate for our customers
in obtaining NAU computing support services. One of the goals of the SWAT team is
to provide you with the training and training materials you need to improve your
computing skills. Please feel free to contact us anytime with your computing or
computer training questions.
II
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
ü
Course Objectives
At the end of the course, students will be able to:
1
2. Explain basic SQL/SQL*PLUS terms and concepts.
S
QL is an acronym for “Structured Query Language”. SQL can be pronounced
as “ess-cue-ell”, but many people refer to it as “sequel”. The paper, "A
Relational Model of Data for Large Shared Data Banks," by Dr. E. F. Codd, was
published in June 1970. Codd's model is now accepted as the definitive model
for relational database management systems (RDBMS).
SQL was developed by IBM to use Codd's model. In 1979, Relational Software, Inc.
(now Oracle Corporation) introduced the first commercially available implementation
of SQL. Today, SQL is accepted as the standard RDBMS language. By the late 1980’s
there were over seventy-five SQL or SQL-like database management systems.
The latest SQL standard is often called SQL92 (and sometimes SQL2).
SQL92 defines four levels of compliance: Entry, Transitional, Intermediate, and Full. A
conforming SQL implementation must support at least Entry SQL.
Oracle8, Release 8.0, fully supports Entry SQL and has many features that conform to
Transitional, Intermediate, or Full SQL.
1
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
• querying data
• inserting, updating, and deleting rows in a table
• creating, replacing, altering, and dropping objects
• controlling access to the database and its objects
• guaranteeing database consistency and integrity
All major relational database management systems support SQL, so you can transfer all
skills you have gained with SQL from one database to another. In addition, all
programs written in SQL are portable: they can often be moved from one database to
another with very little modification.
DML allows you to manipulate the contents of a database. You use DML to capture,
insert, and delete data. Examples of DML commands include:
SQL*PLUS
What is the difference between SQL and SQL*Plus? SQL is the standard database
query language that all relational databases use to manipulate data. SQL*Plus is a
programming environment where you can use SQL.
2
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
SQL*Plus is usually thought of as a kind of interactive query tool and report writer. It
uses SQL to get information from the Oracle data structure, and lets you create
polished, well-formatted reports by giving you easy control over titles, column heading,
subtotals and totals, formatting of numbers, dates, and text, and much more.
At the log on prompt, type scott for username and tiger for the password. Leave the
host string blank.
3
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Username: your_userid
Password: your_userid
Host: NAUDEV
You should change your password once you have logged in to something more secure.
Use the following SQL statement to change your password:
SQL> alter user your_userid identified by new_password;
You should get a “user altered” message. The next time you log in, you will have to
enter the new password.
4
2
Module
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
O
racle SQL*Plus comes with a demo database that contains several tables.
Some of these tables already include data. We will use these tables for our
exercises.
To see which tables are available, type in the following at the SQL prompt: and hit
“enter”.
SQL> select table_name from all_tables;
TABLE_NAME
------------------------------
DUAL
SYSTEM_PRIVILEGE_MAP
TABLE_PRIVILEGE_MAP
STMT_AUDIT_OPTION_MAP
AUDIT_ACTIONS
PSTUBTBL
DEPT
EMP
BONUS
SALGRADE
USER_PROFILE
LOCATION
DEPARTMENT
JOB
EMPLOYEE
SALARY_GRADE
PRODUCT
PRICE
CUSTOMER
SALES_ORDER
ITEM
21 rows selected.
5
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
An alternative SQL statement that displays all available tables as the previous example
did is:
SQL> select * from tab;
Below is a list of all the tables that are available in the demo database. For this course,
however, we will only use three: dept, emp, and salgrade.
EMP Table
DEPT Table
SALGRADE Table
6
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
RAW(n) n=1 to 255 Raw binary data of variable length. For files
Like MS Word documents.
LONGRAW none Raw binary data of variable length.
For graphics.
CHAR(n) n=1 to 255 Text string with fixed length. For short
Codes, like state abbreviations.
Metadata
Metadata is the To view the metadata of a table, use the DESCRIBE command. This will let you know
data about the exactly what the names of your columns are, as well as what types (datatypes) of
data. It let’s us information they contain. Let’s look at the metadata for the emp table.
know how a table
is structured. It is SQL> describe emp
also referred to as Name Null? Type
------------------------------- -------- ----
the data EMPNO NOT NULL NUMBER(4)
dictionary. ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
This information tells us that we have eight columns in the emp table called EMPNO,
ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO. Of these columns,
only one, EMPNO, must have something entered into it. We know this because of the
NOT NULL listed next to it. We can also see what type of information must be
entered into each column.
For example, EMPNO must be a number not to exceed four digits. ENAME can be a
maximum of ten letters, numbers, or symbols in any combination.
SAL must be a number, not to exceed seven digits. Of those seven digits, two must be
behind a decimal point. Therefore, you could not enter a number above 99,999.99. If
you enter more than two decimal places, SQL will round up or down.
7
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Structuring Queries
Although SQL queries can become complicated, the basic structure is always the same.
A SQL query has five main parts (clauses):
SELECT
FROM
WHERE (optional)
GROUP BY (optional)
ORDER BY (optional)
• SELECT: Put the list of columns you want to see here. List all the columns, even if
they are from several tables. Separate them with commas.
• FROM: Put the table name here. If you have more than one table, list them all
here, separated with commas.
• WHERE (optional): Where some condition is true. Put comparisons, limits, and
connections between tables here. List them with either AND or OR between each
set. When left out, all rows are chosen.
• GROUP BY (optional): Tells how you want data grouped or summarized. This is
only needed for a query that summarizes data.
8
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
• ORDER BY (optional): List columns to use for sort order here. When left out,
rows are returned in the order in which they are found in the table.
Basic Query • HAVING (optional): Similar to WHERE, but with some important distinctions
that we’ll look at later.
select column , column
from table SELECT specifies which column(s) in a table you want to see.
where clause
group by clause FROM specifies the names of the table or tables in which the columns listed in the
order by clause SELECT clause are located. If more than one table is listed, they should be separated
having clause by a comma.
If you want to see all the columns, enter an asterisk. The following example shows
how we would obtain all the information from the department table.
If we wanted to know just the department number and the location, we would have to
select the specific columns.
SQL> select deptno, loc
2 from dept;
DEPTNO LOC
--------- -------------
10 NEW YORK
20 DALLAS
30 CHICAGO
40 BOSTON
9
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
3
Exercise 2.1
1. Using SQL, display all the columns from the employee (emp) table.
2. Now display just the name (ename), position (job), and hire date (hiredate) of the
employees.
5. Create a query to display unique (distinct ) jobs from the EMP table.
SQL>
In Personal Oracle 8, the file is saved to the oracle8/BIN directory. Most likely, you
will find it at C:/oracle8/BIN.
or
10
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
SQL> @example
Either start or @ will run the saved query. You can also edit the saved query by
entering edit followed by the filename:
SQL> edit example
Once the file has been saved, you can later append more information to it by using
the following command:
SQL> save example append
Finally, you can replace the saved file by using the replace command with save:
SQL> save example replace
Operators
The WHERE Clause
The WHERE clause is the part of the SELECT clause that specifies the search
conditions. These conditions determine which rows are retrieved.
To set up these search conditions, we use operators. The system will search for rows of
data that meet the conditions (qualifications) you specified by the operators.
Remember that operator parameters are case sensitive. “Manager” is not the same as
“manager”.
Comparison Operators
SQL provides a variety of operators and keywords for expressing search conditions.
• Comparison operators
= equal to
> greater than
< less than
>= greater than or equal to
<= less than or equal to
!= not equal to
<> not equal to
SELECT EMP_ID SELECT EMP_ID
FROM EMPLOYEES FROM EMPLOYEES
WHERE SALARY >= 50000; WHERE POSITION = 'Manager';
11
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Notice that “Manager” is placed in single quotes in the where clause, while “50000”
was not. Any character string, including dates, must be set off by single quotes,
while numbers do not require this.
SELECT EMP_ID
FROM EMPLOYEES
WHERE POSITION = 'Manager'
AND (SALARY > 50000 OR BENEFIT > 10000);
Let’s say you wanted to see all people whose last names started with "L" in the
EMPLOYEES table:
SELECT EMPLOYEEIDNO
FROM EMPLOYEESTATISTICSTABLE
WHERE LASTNAME LIKE 'L%';
12
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
The percent sign (%) is used to represent any possible character (number, letter, or
punctuation) or set of characters that might appear after the "L". To find those people
with LastName's ending in "L", use '%L', or if you wanted the "L" in the middle of the
word, try '%L%'. The “%” is a wildcard that can represent any number of characters.
ename like ‘SMITH_’ would return SMITHE, SMITHY, and SMITHS, but not SMITHEY.
Arithmetic Operators
Arithmetic operators allow you to modify the way data is displayed, perform
calculations, or look at what-if scenarios. Arithmetic operators can be used in any
clause of a SQL statement except the FROM clause.
Operator Description
+ Add
- Subtract
* Multiply
/ Divide
14 rows selected.
13
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
14 rows selected.
In the first example we multiplied the monthly salary by twelve and then added a one-
time bonus of $200. In the following example, parentheses are used to raise the salary
$100 per month and then multiply by twelve.
Null Values
If a row lacks the data value for a particular column, that value is said to be null, or to
contain null. A null value is not the same as zero or a space. Zero is a number, and a
space is a character. NULL is absolutely nothing at all, but NULL can be used as a
qualifier.
SQL> select mgr as manager, sal, comm SQL> select mgr, sal, comm"Commission"
2 from emp; 2 from emp;
3
Exercise 2.2
1. Create a query to display the name and salary of employees earning more than
$2850. Save your SQL to statement to a file named q1.sql. Run your query.
2. Create a query to display the employee name and department number for
employee number 7566.
14
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
3. Modify q1.sql to display the name and salary for all employees whose salary is not
in the range of $1500 and $2850. Resave the SQL statement as q2.sql and run it.
5. Find out how much Turner will make annually if we give her a $75 dollar a month
raise.
6. Select all columns from the employee table, but cause the heading “ename” to be
displayed as “Last Name”.
Aggregates are functions you can use to get summary values. You apply aggregates to
sets of rows: to all the rows in a table, to just those rows specified by a WHERE clause,
or to groups of rows set up in the GROUP BY clause, (discussed in the next module).
No matter how you structure the sets, you get a single value for each set of rows.
SUM
This query provides the total amount of commissions:
15
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
SUM(COMM)
---------
2200
AVG
Here we have the average of commissions paid, with a different heading:
SQL> select avg(comm) "Average Commission"
2 from emp;
Average Commission
------------------
550
Let’s say that the commissions paid this month were indicative of commissions paid
each month and we wanted to know what the average yearly commission might be:
SQL> select avg(comm)*12
2 from emp;
AVG(COMM)*12
------------
6600
COUNT
What if we wanted to know how many employees worked in the accounting
department (dept. number 10):
SQL> select count(deptno) SQL> select count(deptno) "Accounting
2 from emp 2 Employees"
3 where deptno=10; 3 from emp
4 where deptno=10;
COUNT(DEPTNO)
------------- Accounting Employees
3 --------------------
3
COUNT(*)
The apparent similarity of COUNT and COUNT(*) can lead to confusion. However,
the two are really not the same. COUNT takes an argument (a column or expression)
and discovers all not-null occurrences of that argument, while COUNT(*) counts all
rows, whether or not any particular column contains a null value. Let’s look at how
each behaves in the following examples:
SQL> select count(comm), count(*)
2 from emp;
COUNT(COMM) COUNT(*)
----------- ---------
4 14
16
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
The results produced by the two functions are different because ten rows in the
COMM column have null values. Note that the commission listed as “0” was counted
by COUNT, because “0” is a value, and therefore is not null.
MIN
MIN provides the lowest value in an expression. MAX and MIN can be used for
things other than the lowest or highest amount. For example we can use the following
query to find out which employee has worked in the company the longest:
SQL> select min(hiredate)
2 from emp;
MIN(HIRED
---------
17-DEC-80
ENAME HIREDATE
---------- ---------
SMITH 17-DEC-80
While subqueries are beyond the scope of this course, I’ll point out that they exist and
that one could have been used to obtain the same information in a single query using
the following format:
SQL> select ename, hiredate
2 from emp
3 where hiredate=(select min(hiredate) from emp);
ENAME HIREDATE
---------- ---------
SMITH 17-DEC-80
Essentially, a subquery is nothing more than a query within a query
17
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
SUM(DISTINCTSAL)
----------------
24775
The difference in the two results comes from the fact that there are duplicate values of
1250 and 3000 in the SAL column.
DISTINCT This option causes a group function to consider only distinct values
the argument expression.
ALL This option causes a group function to consider all values, including
all duplicates.
For example, the DISTINCT average of 1, 1, 1, and 3 is 2; the ALL average is 1.5. If
neither option is specified, the default is ALL.
3
Exercise 2.3
1. Display the highest, lowest, sum, and average salary of all employees. Label the
columns Maximum, Minimum, Sum, and Average.
3. Determine the number of clerks without listing them. Include the heading
“Number of Clerks”.
18
3
Module
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
The default display and input format for any date is DD-MON-YY. Valid Oracle dates
are between January 1, 4712 BC and December 31, 9999 AD.
SYSDATE
SYSDATE uses the computer’s operating system for the current date and time.
SYSDATE can be thought of as a function whose result is always the current date and
time. It can be regarded as a hidden column that is in every table. It is used in
calculations that need to compare past or future dates/times with the current date or
time. You can list the SYSDATE by itself by using the DUAL table, which is a small
but useful Oracle table created for testing functions or doing quick calculations. Try it.
SQL> select sysdate from dual;
19
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
ENAME YEARS
---------- ---------
CLARK 17.561648
KING 17.120854
MILLER 16.937418
The preceding example displays the number of years that each employee in department
10 has worked. It subtracts the current date (SYSDATE) from the date on which the
employee was hired and divides the result by 365.25 to calculate the number of years
that a worker has been employed.
Date Functions
Here is a list of a few date functions. We will not deal with them in this course, but I
wanted to at least make you aware of them.
Function Description
months_between (date1, date2)
months_between (‘01-sep-95’,’11-jan-94’)
Number of months between two dates
add_months (date, n)
add_months (‘11-jan-94’,6)
Add calendar months to date
next_day (date, ‘char’)
next_day (‘01-sep-95’,’Friday’)
Next date of the day specified
last_day (date)
last_day (‘01-sep-95’)
Last day of the month
round (date [, ‘fmt’])
round (‘25-jul-95’,’month’)
Round date
round (‘25-jul-95’,’year’)
trunc (date [ , ‘fmt’])
trunc (‘25-jul-95’,’month’)
Truncate date
trunc(‘25-jul-95’,’year’)
TO_CHAR
to_char (date, ‘fmt’)
Up to now, all date values were displayed in the DD-MON-YY format. The to_char
function allows you to convert a date from this default format to one specified by you.
20
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
EMPNO MONTH
--------- -----
7839 11/81
Element Description
BC or AD BC/AD indicator
Q Quarter of year
21
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Element Description
AM or PM Meridian indicator
MI Minute (0-59)
SS Second (0-59)
Element De
SQL> select ename, to_char (hiredate, 'Ddspth "of" Month YYYY HH:MI:SSAM')
2 Hiredate
3 from emp;
ENAME HIREDATE
---------- -------------------------------------------
SMITH Seventeenth of December 1980 12:00:00AM
ALLEN Twentieth of February 1981 12:00:00AM
WARD Twenty-Second of February 1981 12:00:00AM
JONES Second of April 1981 12:00:00AM
MARTIN Twenty-Eighth of September 1981 12:00:00AM
BLAKE First of May 1981 12:00:00AM
CLARK Ninth of June 1981 12:00:00AM
SCOTT Nineteenth of April 1987 12:00:00AM
KING Seventeenth of November 1981 12:00:00AM
TURNER Eighth of September 1981 12:00:00AM
ADAMS Twenty-Third of May 1987 12:00:00AM
JAMES Third of December 1981 12:00:00AM
22
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
14 rows selected.
To_char can be used with numbers in the same way. It converts a number to a
character datatype.
SALARY
--------
$1,500
23
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
to_number (char)
Example: Display the names and hire dates of all the employees who joined on
February 22, 1981.
SQL> select ename, hiredate
2 from emp
3 where hiredate = to_date ('February 22, 1981', 'Month dd, YYYY');
ENAME HIREDATE
---------- ---------
WARD 22-FEB-81
Birthday Trick
Use the following query to see what day you were born on. Substitute the date with
your own birth date. Be careful to type everything exactly.
SQL> select to_char(to_date('23-sep-63'), 'Day') "Born on" from dual;
Born on
---------
Monday
3
Exercise 3.1
1. Write a query to display the current date.
2. Now write a query to display the current date in a different format, such as the
“4th of July”. Display it first as a numeral and then run a second query that spells it
out. Label the heading “Today’s Date”.
24
4
Module
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
T
he GROUP BY and ORDER BY clauses can be used to organize your query
results, so that they display the data in a more meaningful way. The HAVING
clause works in a manner similar to the WHERE clause, but with some
important differences.
GROUP BY
The GROUP BY clause is usually used with an aggregate function such as SUM or
AVG. GROUP BY doesn’t really have much use without aggregate functions.
GROUP BY divides a table into sets, while aggregate functions produce summary
values for each set. Until now, all aggregate functions have treated the table as one large
group of information. At times, you need to divide the table of information into
smaller groups. This can be done by using the GROUP BY clause.
You can use the GROUP BY clause to divide the rows in a table into groups. You can
then use the group functions to return summary information for each group.
Guidelines:
• If you include a group function in a SELECT clause, you cannot select individual
results as well unless the individual column appears in the GROUP BY clause. You
will receive an error message if you fail to include the column list.
• Using a WHERE clause, you can exclude rows before dividing them into groups.
• You must include the columns in the GROUP BY clause.
• You cannot use a column alias in the GROUP BY clause.
• By default, rows are sorted by ascending order of the columns included in the
GROUP BY list. You can override this by using the ORDER BY clause
25
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
DEPTNO AVG(SAL)
--------- ---------
10 2916.6667
20 2175
30 1566.6667
When using the GROUP BY clause, make sure that all columns in the SELECT list
that are not in the group functions are included in the GROUP BY clause. The above
example displays the department number and the average salary for each department.
Here is how the SELECT statement above, containing a GROUP BY clause is
evaluated.
AVG(SAL)
---------
2916.6667
2175
1566.6667
You can also use the ORDER BY clause to rearrange the query results.
SQL> select deptno, avg(sal) SQL> select deptno, avg(sal)
2 from emp 2 from emp
3 group by deptno; 3 group by deptno
4 order by avg(sal);
DEPTNO AVG(SAL)
--------- --------- DEPTNO AVG(SAL)
10 2916.6667 --------- ---------
20 2175 30 1566.6667
30 1566.6667 20 2175
10 2916.6667
26
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
The EMP table is grouped first by department number and then within that grouping
it is grouped by job title. For example, the two clerks in department 20 are grouped
together and a single result (total salary) is produced for all salesmen within the group.
SQL> select deptno, job, sum(sal)
2 from emp
3 group by deptno, job;
9 rows selected.
You can return summary results for groups and subgroups by listing more than one
GROUP BY column. You can determine the default sort order of the results by the
order of the columns in the GROUP BY clause. Here is how the SELECT statement
above, containing a GROUP BY clause, is evaluated:
So the SUM function is being applied to the salary column for all job titles within each
department number group.
27
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
DEPTNO COUNT(ENAME)
--------- ------------
10 3
20 5
30 6
You cannot use the WHERE clause to restrict groups. Note the following error which
results from a misuse of the WHERE clause
SQL> select deptno, avg(sal)
2 from emp
3 where avg(sal) > 2000
4 group by deptno;
where avg(sal) > 2000
*
ERROR at line 3:
ORA-00934: group function is not allowed here
You can correct the above error by using the HAVING clause to restrict groups.
SQL> select deptno, avg(sal)
2 from emp
3 group by deptno
4 having avg(sal) > 2000;
DEPTNO AVG(SAL)
--------- ---------
10 2916.6667
20 2175
Exercise 4.1
1. Display the minimum, maximum, sum, and average salary for each job type
(analyst, clerk, manager, president, salesman).
2. Write a query to display the number of people with the same job.
ORDER BY
The ORDER BY clause arranges your query results by one or more columns. The
default order is ascending. If you want the list to be sorted in descending order, you
have to use DESC in the ORDER BY clause.
28
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
You can also sort by more than one column. When you use more than one column in
the ORDER BY clause, sorts are nested ( that is, ordered by job first and then by
ename within each job category. You can have as many levels of sorts as you like. The
following example sorts the query result first by job title and then by last name.
14 rows selected.
You could also add DESC to one or both of the columns in the ORDER BY clause to
reverse sort the query result.
Exercise 4.2
1. Display the employee name, job and start date of employees hired between
February 20, 1981, and May 1, 1981. Order the query in ascending order of start
date.
29
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
3. Display the name, salary, and commission for all employees who earn
commissions. Sort data in descending order of salary and commissions.
When there are aggregates in the select list of a query, WHERE clause conditions apply
to the aggregates, while HAVING conditions apply to the query as a whole, after
you’ve calculated the aggregates and set up the groups.
SQL> select deptno
2 from emp
3 group by deptno
4 having max(sal) > 2900;
DEPTNO
---------
10
20
The following example displays the job title and total monthly salary for each job title
with a total payroll exceeding $5000. The example excludes salesmen and sorts the list
by the total monthly salary.
JOB PAYROLL
--------- ---------
ANALYST 6000
MANAGER 8275
Exercise 4.3
1. Display the manager number and the salary of the lowest paid employee for that
manager. Exclude anyone where the manager id is not known. Exclude any groups
where the minimum salary is less than $1000. Sort the output in descending order
of salary.
30
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Joining Tables
In a database that has been designed properly, one table may not give you all the
information that you need. When this happens, you may need to query more than one
table at the same time using a join operation. The join operation lets you retrieve and
manipulate data from more than one table in a single SELECT statement. In most
cases, you specify joins in the WHERE clause of a SELECT statement.
To perform a simple or inner join, you need to join the two tables together by using a
column that is found in both tables, usually as a primary key in one table and a foreign
key in the other. Let’s look at a join involving the EMP and DEPT tables.
SQL> select emp.empno, emp.ename, emp.deptno, dept.deptno, dept.loc
2 from emp, dept
3 where emp.deptno=dept.deptno;
14 rows selected.
31
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
You can cut down on the typing by using table aliases in the SELECT statement. A
table alias is defined in the FROM clause after the actual table name.
14 rows selected.
Sometimes you may need to join more than one table. This is done in the following
manner
(This table is an example only. It will not work with your practice tables)
SQL> select e.name, e.emp_id, d.deptno, d.manager, p.project_id
2 from employee e, department d, projects p
3 where e.deptno=d.deptno
4 and d.manager=p.manager;
Exercise 4.4
1. Write a query to display the employee name, department number, and department
name for all employees. List the results alphabetically by name.
2. Write a query to display the employee name, department name, commission, and
location of all employees who earn a commission.
3. Write a query to display the name, job, department number, and department name
for all employees who work in Dallas.
32
5
Module
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
N
ow that you know how to pull data out of tables that were created for you,
you probably want to know how to create your own tables, drop (delete)
them, and alter them as necessary. This module will give you the knowledge
to create your own tables and fields and then alter or modify them after you
have created them.
Naming Conventions
There are certain restrictions on names you give to tables and columns. Table and
column names:
To create a table, you need to specify the name of the table and then specify its fields
and the datatypes of those fields. Here is an example:
SQL> create table table_name (
2 id number(4),
3 name varchar2(20),
4 city varchar2(20));
This will create a table called “table_name” with three fields: an ID field which can take
up to four numbers and a name and a city field which can each hold up to twenty
alphanumeric characters.
33
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
A not null constraint has now been placed on the “name” field. This means that a
record cannot be inserted without a value being placed in this field. The following
constraints are available in Oracle:
1. Not Null –specifies that a column may not contain a null value
2. Unique – Specifies a column whose values must be unique for all rows
3. Primary Key – Uniquely identifies each row of the table
4. Foreign Key – Establishes and enforces a foreign key relationship between the
column and a column of the referenced table
5. Check – Specifies a condition that must be true
The unique constraint will allow more than one null value, but it would prevent you
from entering John Smith twice. It would not prevent you from entering John Smith
and JOHN SMITH, however, because Oracle is case sensitive.
FOREIGN KEY is used to define the column in the child table at the table constraint level.
REFERENCES identifies the table and column in the parent table.
ON DELETE CASCADE indicates that when a row in the parent table is deleted, the dependent rows
in any child tables will also be deleted. Without the ON DELETE CASCADE option, the row in the
parent table cannot be deleted if it is referenced in the child table.
34
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Now let’s create the child table and create a foreign key to reference the “id” column in
the parent table.
SQL> create table child_table (
2 child_id number(2) primary key,
3 name varchar2(20),
4 id number(2) not null,
5 constraint childtable_id_fk FOREIGN KEY (id)
6 REFERENCES parent_table (id));
This enters data into your tables and relates the John Smith record to Flagstaff by
virtue of the foreign key. Now try to delete the Flagstaff record from the parent table:
SQL> delete from parent_table where id=01;
What happened?
Let’s do an alter table command to add “ON DELETE CASCADE” to the foreign
key constraint. First drop (delete) the old constraint.
SQL> alter table child_table
2 drop constraint CHILDTABLE_ID_FK;
Now add a new constraint that contains the “ON DELETE CASCADE” clause to
the child table:
SQL> alter table child_table
2 add constraint childtable_id_fk
3 Foreign key(id) references parent_table(id)
4 ON DELETE CASCADE;
Try to drop the Flagstaff record now and see what happens now that we’ve added the
ON DELETE CASCADE clause.
SQL> delete from parent_table where id=01;
Check the child table and note that the dependent record has also been deleted.
SQL> select * from child_table
35
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Check Constraint
Check constraints define a condition that each row must satisfy. A check constraint
that makes sure that the id column does not contain four-digit numbers below 1000 or
above 5000 can be created with the following statement:
SQL> create table table_name (
2 id number(4)
3 constraint tablename_id_ck check (id between 999 and 5001),
4 name varchar2(20) not null,
5 city varchar2(20));
Note that you are actually creating a constraint with its own name, “tablename_id_ck”.
You can check for all uppercase letters in the name column by using this constraint:
SQL> create table table_name (
2 id number(4),
3 name varchar2(20) not null
4 constraint tablename_name_ck check (name=upper(name)),
5 city varchar2(20));
The previous statement will not allow nulls or lower case letters to be entered into the
name column, but it will allow numbers and certain symbols. Of course another way to
ensure that you only get capital letters would be to convert lowercase letters
automatically when they are inserted, which we will cover in the next module.
Constraints can also be used on dates, including sysdate, and can be used in simple
logic statements.
check (start_date < sysdate and (end_date > sysdate or end_date is null)));
36
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Now try inserting data in the first two columns only and then select it:
SQL> insert into clients (id,name) values (10, 'JOHN SMITH');
SQL> select * from clients;
You should see that Flagstaff has automatically been entered in the city column. You
should be able to do the same thing with dates, including the sysdate function.
SQL> create table employees (
2 id number(2),
3 name varchar2(20),
4 hiredate date default sysdate);
In other cases, you may simply want to modify the structure of a table. This can be
done with the Alter Table statement. The alter table statement is used to add, modify
or delete columns, add or remove constraints as we saw above, define a default value
on a new column, and even to rename a table.
To demonstrate how to add a column, let’s first create the new table:
SQL> create table clients (
2 id number(2),
3 name varchar2(20);
Now let’s add the city column using the alter table statement:
SQL> alter table clients
2 ADD (city varchar2(20));
37
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
You can also use alter table to modify columns. You can change a column’s datatype,
size, default value, and NOT NULL column constraint. Let’s modify the name column
to be thirty spaces instead of twenty.
SQL> alter table clients
2 MODIFY (name varchar2(30));
A feature that first showed up with Oracle8 is the ability to drop a column as well. The
statement to do this is:
SQL> alter table clients
2 drop (name);
This is a handy feature. You can create tables from very sophisticated queries and joins
that provide only the data you need. You can also do this with views, which we will
look at in module seven.
38
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Creating Views
You may create tables that contain data that you don’t want to be made available to
certain people or groups. Rather than create new tables with redundant data, you can
create a “view” of the table which only presents the data fields that you want to make
available. A view is set up with certain privileges for users. A view can also be
configured to control how data is manipulated in the table. For example, you may want
to set it up so that users can only see the data and not be allowed to update it.
To create the view, you specify the name and then use a select statement:
SQL> create view employeeVU
2 as select empno, ename, job
3 from employees
4 where deptno=20;
View created.
To drop a view:
SQL> drop view employeeVU;
View dropped.
You can rename the column names when you create your view in the following
manner:
SQL> create view employeeVU
2 as select empno ID,
3 ename NAME, job TITLE
4 from employees
5 where deptno=20;
View created.
39
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
View created.
This is just a superficial overview of views. There are many rules and commands that
you need to be aware of before using a view in a production environment. For more
information consult the comprehensive Oracle complete reference guide or an online
resource such as http://www.oracle.com or http://otn.oracle.com.
40
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Inserting Records
Now that you know how to create and manage tables and views, let’s look at how to
insert data into your tables and manage it once it’s there. It’s actually a pretty simple
and straight-forward process.
Remember that varchar2 and date datatypes need to be enclosed in quotes, while
number datatypes do not.
If you only want to insert data in certain fields, then you must identify the fields by
name.
SQL> insert into employees (empno,ename)
2 values (8888,’SUTHERLAND’);
Updating Records
To update a record, use the following statement::
SQL> update employees
2 set job=’ACTOR’,mgr=7839,hiredate=’01-FEB-02’,sal=10000,deptno=50
3 where ename=’SUTHERLAND’;
Deleting Records
To delete a record, use the following statement:
SQL> delete from employees
3 where ename=’SUTHERLAND’;
41
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Make sure that you use a where clause with the delete statement, or you may
delete the entire contents of the table! If you do this by accident, you can use the
rollback function to correct it, but you must do it before you commit. We will look at
the commit function in the following section.
SQL> delete from employees;
17 rows deleted.
SQL> rollback;
Rollback complete.
Committing Changes
After making changes to records, you need to issue a “commit” command to make the
changes permanent. Oracle will make them permanent if you exit from the SQL*Plus
tool, but it is a good idea to get in the habit of committing after important changes.
This becomes very important if you are designing dynamic web pages that present data
from your Oracle tables. The changes appear to have been made in SQL*Plus, but they
will not show up in your web pages until you have issued a commit command.
Remember this and save yourself potentially hours of frustration if you present data on
the web.
SQL> commit;
Commit complete.
As we saw in the last section, you can also issue a rollback command and undo all of
the changes up to the point where you last issued a commit command.
SQL> rollback;
Rollback complete.
Creating an Index
If you have a large table in which only a small percentage of records are expected to be
returned at any one time, then you will probably want to create an index to speed query
searches. An index is an independent object, separate from the table it indexes. It
speeds up the retrieval of data by using a pointer and can reduce disk input/output by
using a rapid path access method. Since indexes are independent of the tables, they can
be dropped at any time without affecting the data in the tables or the tables themselves.
You probably do not want to use indexes on a table that is updated frequently as it may
slow down inserts or updates.
There are two types of indexes. An implicit index is created automatically when you
define a primary key or unique constraint on a table. An explicit constraint is created when
you manually execute a create index statement as shown below.
42
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
To create an index:
SQL> create index employees_empno_idx
2 on employees(empno);
Index created.
You can view the indexes you created by using the following:
SQL> select ic.index_name, ic.column_name,
2 ic.column_position col_pos, ix.uniqueness
3 from user_indexes ix, user_ind_columns ic
4 where ic.index_name = ix.index_name
5 and ic.table_name = 'employees';
43
6
Module
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Other Tips
T
he next step is to learn how to use sequences and triggers to allow for
automatic numbering and to cause things to happen when an event occurs.
We’ll also look at how to schedule jobs to make things happen to your data
and tables at pre -determined times.
Sequences
Many tables need unique numbers to serve as primary key values. A sequence
generator can be used to automatically assign unique numbers to a row. When
combined with a trigger, a sequence can create the equivalent of an Access database
autonumber, which automatically creates a new number each time a record is inserted
into a table. Sequences are typically used to generate primary numbers. Sequence
numbers are independent of tables, so one sequence can be used on multiple tables.
The “increment by” clause can be left out if you want it to increase by one number at a
time, which is the default. The “start with” clause can also be left out if you want the
sequence number to begin at one, but it can be useful in a case where you need the
sequence number to start at a value like 1000.
“No cache” is important if you are using the sequence to create sequential numbers
and it’s important that you don’t have any missing values. Oracle tends to pre -allocate
20 values per day. If your table only inserts three records the first day, it will assign the
numbers 1, 2, and 3. If you didn’t specify “no cache” when you created the sequence,
your sequence value will start at 21 the following day.
We are going to create a sequence to generate an autonumber. The sequence will also
need a trigger, which we will create in the next section. To generate the sequence type:
44
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
You should get a “Sequence created” message if it was successful. To drop the
sequence, use “drop sequence sequence_name”
If you are embedding an SQL insert statement in something like Active Server Pages,
you can create an autonumber that will be initiated by the code itself, rather than an
event trigger in the table. You can do it this way:
“Autonumber” is the name of the sequence and “nextval” tells the sequence to give
you the next value available. “SMITH” is just data in the second column.
As mentioned, this works fine if you can count on a dynamic page or other code to
trigger the sequence event. In other cases where a front end such as Microsoft Access
is being used to insert data, a sequence combined with a trigger is probably the best
situation. The trigger allows the sequence to fire internally when a record is inserted,
without relying on external code, such as Visual Basic in an Active Server Page.
Triggers
Here’s how the trigger is created. Give it the name of the owner, in this case employee
is the tablename. ID is the name of the field where the autoincrement will be.
“number(5)” specifies the datatype and number of digits.
Trigger created.
This creates a trigger that will automatically place a sequential number in whichever
column specified. This works like an autonumber in Access and allow access to be
used as a front end to Oracle in situations where a primary key are similar automatically
generated unique value is necessary.
45
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
To set up Access as a front end, first create your tables in Oracle using SQL*Plus and
then follow these steps.
Now go to the File menu and select Get External Data > Link Tables. In the “Link”
dialog box that pops up, find “Files of Type: Microsoft Access” and scroll to the
bottom to change “Microsoft Access” to “ODBC Databases”. Click OK.
46
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Select the “Machine Data Source” tab and click on the “New” button.
47
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Click on the “Microsoft ODBC for Oracle” driver and click the next button. Note that
this is different from the “Oracle ODBC Driver” which may also be listed in your
choices. The Oracle ODBC Driver is not recommended because of some anomalies
that have been noticed in the NAU env ironment. Click on the Next button and then
click “Finish”. Now fill in the box that should pop up.
“Naudev_tables” can be any name you want to give your ODBC connection. A
description can also be entered if useful. Put your Oracle username in and then most
likely NAUDEV or ITSDEV for the Server name, depending on where your tables are
located. Click OK.
The new ODBC name should now be highlighted. Simply click OK and then enter the
Oracle password that the DBA’s assigned to you. (Don’t forget to change this
password shortly after they assign it.) See page ??? if you forgot how to do this.
Find your username and the tables that are located in your space. Choose one or more
tables and click OK.
If you can’t find any tables above a certain letter, it means that you probably used the
“Oracle ODBC Driver” instead of the “Microsoft ODBC for Oracle” drive. If so, go
back, delete the ODBC connection and re -create it using Microsoft ODBC for Oracle.
48
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Access will probably prompt you for a Unique Record Identifier. This is only
important for Access and does not change anything on the Oracle side. You should
choose something however or you probably will not be able to enter any data through
Access, only view it. Click the OK button.
Your link to the Oracle table is now complete. You will notice that the table icon is
different than what is usually seen in Access. (It is a globe with an arrow.) This
represents a linked table. The good news is that once you have this link, it can be
treated as any other table in Access. Queries, forms, and modules can be written in
Access that actually run against the Oracle tables. As mentioned above, this can be a
very powerful tool, especially when non-technical personnel are expected to manage
the data. Plus it gives you the security of having your data stored and backed up on ITS
professionally-managed databases.
49
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
1. Create a new table called lab_one and add several columns, including one called
unique_id and make it a primary key with an identifiable name.
2. Using an SQL insert statement, enter one or two records into the new table.
3. Now create a sequence, named something like “autonumber”, which will be used
to create an autonumber in the unique_id field.
4. Since we will use Access as a front end, you will also want to create a trigger to
cause the sequence to insert a value when a new record is inserted.
5. Now create an Access front end to your new table. Once it is set up, try to insert a
couple of records through the GUI interface. Which tool do you prefer, SQL*Plus
or Access?
SQL Loader
So how do you get large numbers of records into your tables without having to enter
each record by hand? There is a tool called SQL Loader that will let you enter data
from a delimited text file. The hard part is setting up the control file, but once you have
done this, the records can be loaded in a few seconds to a few minutes depending on
the quantity of data.
Whole books have been written on SQL Loader, most notably one by O’Reilly, which
is devoted entirely to the intricacies of this command line tool. First of all, you need to
do a search for the tool to make sure you have it. Look for “sqlldr.exe”. It should be in
a path like c:\ORACLE\ora81\bin.
SQL*Loader reads files and places the data from those files in an Oracle database
based on the instructions it receives from a control file. The control file describes the
data being loaded and tells Oracle where to place it. The SQL loader tool isn’t included
in the NAU download install, so you need to get it form a complete install from the
CD or ask your friendly neighborhood SWAT team member for it.
50
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
The last few lines dealing with “storage” are sometimes needed to avoid a “max
extents” error that occurs sometimes depending on the amount of data you are trying
to load.
If you get a max extents error, you need to add this storage clause when creating the
table. The DBA’s at NAU have se the default max extents to ten and the clause
changes that to allow for loading of large amounts of data.
2. Now create the control file and store it as “class_info.ctl”. (Note the “replace” in
the second line. This option wipes out existing data. Use “append” if you want
to add to existing data.):
load data
infile class_info.txt replace
into table class_info
fields terminated by ‘,’ optionally enclosed by ‘”’ trailing nullcolls
(idno, course_no, day_of_class, building, seats_remaining, instructor)
Chyfo at http://www.ispirer.com is a nice little tool which will creat all of the necessary
files and scripts for you when migrating data from various database to Oracle. It is a
command line tool and you still have to have a pretty good understanding of how
things work to use it effectively, however. Don’t forget about the O’Reilly book, which
is a great resource if you want to get serious about using SQL loader and tools like
Chyfo.
Your instructor will tell you where to get the data file, called “class_info.txt”. Place it in
the same directory as the control file. I usually create a directory at the root,
“C:\loaddata”, for example, to keep the path short and simple.
51
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
SQL Loader creates a log that explains how data was loaded and whether anything
went wrong. It is usually dumped in c:\documents and settings/yourusername.
SQL*Plus Worksheet
Another tool that you can install from the ITS dba website is the SQL*Plus
Worksheet. The worksheet works pretty much the same way as the SQL*Plus tool, but
it provides a slightly more intuitive graphical interface for running queries and has two
panes: one for the SQL queries and other commands and a second for the output. It’s
worth taking a look at. You will probably find it by going to the Start menu and going
to Oracle > Database Administration > SQLPlus Worksheet
52
I N T R O D U C T I O N T O S Q L A N D S Q L * P L U S
Solutions
Solutions to Exercises
Exercise 2.1
1.
SQL> select *
2 from emp;
14 rows selected.
2.
SQL> select ename, job, hiredate
2 from emp;
14 rows selected.
i
3.
SQL> describe dept
Name Null? Type
------------------------------- -------- ----
DEPTNO NOT NULL NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
4.
SQL> select *
2 from dept;
5.
SQL> select distinct job
2 from emp;
JOB
---------
ANALYST
CLERK
MANAGER
PRESIDENT
SALESMAN
Exercise 2.2
1.
SQL> select ename, sal
2 from emp
3 where sal > 2850;
ENAME SAL
---------- ---------
JONES 2975
SCOTT 3000
KING 5000
FORD 3000
2.
SQL> select ename, deptno
2 from emp
3 where empno=7566;
ENAME DEPTNO
---------- ---------
JONES 20
3.
ii
SQL> select ename, sal
2 from emp
3 where sal not between 1500 and 2850;
ENAME SAL
---------- ---------
SMITH 800
WARD 1250
JONES 2975
MARTIN 1250
SCOTT 3000
KING 5000
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300
10 rows selected.
4.
SQL> select ename
2 from emp
3 where ename like 'S%';
ENAME
----------
SMITH
SCOTT
5.
SQL> select ename, 12*sal "Old Salary", 12*(sal+75)"New Salary"
2 from emp
3 where ename='TURNER';
6. (Do this query first to find out what columns are in the table)
iii
SQL> select empno, ename as "Last Name", job, mgr, hiredate,
2 sal, comm, deptno
3 from emp;
14 rows selected.
Exercise 2.3
1.
SQL> select max(sal) "Maximum", min(sal) "Minimum",
2 sum(sal) "Sum", avg(sal) "Average"
3 from emp;
2.
SQL> select count(empno)
2 from emp;
COUNT(EMPNO)
------------
14
3.
SQL> select count(job) "Number of Clerks"
2 from emp
3 where job='CLERK';
Number of Clerks
----------------
4
iv
Exercise 3.1
1.
SQL> select sysdate
2 from dual;
SYSDATE
---------
25-JAN-99
2.
SQL> select to_char (sysdate, 'ddth "of" Month') "Today's Date"
2 from dual;
Today's Date
-----------------
25th of January
Today's Date
---------------------------
twenty-fifth of January
3.
ENAME MONTHS_BETWEEN(SYSDATE,HIREDATE)
---------- --------------------------------
TURNER 208.56175
4.
SQL> select ename, hiredate
2 from emp
3 where hiredate between '01-JAN-82' and '31-DEC-82';
ENAME HIREDATE
---------- ---------
MILLER 23-JAN-82
or
v
SQL> select ename, hiredate
2 from emp
3 where hiredate like '%-%-82';
ENAME HIREDATE
---------- ---------
MILLER 23-JAN-82
Exercise 4.1
1.
SQL> select job, min(sal), max(sal), sum(sal), avg(sal)
2 from emp
3 group by job;
2.
SQL> select job, count(job)
2 from emp
3 group by job;
JOB COUNT(JOB)
--------- ----------
ANALYST 2
CLERK 4
MANAGER 3
PRESIDENT 1
SALESMAN 4
Exercise 4.2
1.
SQL> select ename, job, hiredate
2 from emp
3 where hiredate between '20-FEB-81' and '01-MAY-81'
4 order by hiredate;
vi
2.
SQL> select ename, deptno
2 from emp
3 where deptno=10 or deptno=30
4 order by deptno, ename;
ENAME DEPTNO
---------- ---------
CLARK 10
KING 10
MILLER 10
ALLEN 30
BLAKE 30
JAMES 30
MARTIN 30
TURNER 30
WARD 30
3.
SQL> select ename, sal, comm
2 from emp
3 where comm is not null
4 order by sal desc, comm desc;
Exercise 4.3
1.
SQL> select mgr, min(sal)
2 from emp
3 group by mgr
4 having mgr is not null
5 and min(sal) > 1000
6 order by min(sal) desc;
MGR MIN(SAL)
--------- ---------
7566 3000
7839 2450
7782 1300
7788 1100
Exercise 4.4
1.
SQL> select emp.ename, emp.deptno, dept.dname
2 from emp, dept
3 where emp.deptno=dept.deptno
4 order by ename;
or
SQL> select e.ename, e.deptno, d.dname
2 from emp e, dept d
3 where e.deptno=d.deptno
vii
4 order by ename;
3.
SQL> select e.ename, e.job, e.deptno, d.dname
2 from emp e, dept d
3 where e.deptno=d.deptno
4 and loc='DALLAS';
viii