SQL-Create, Insert, Select

Kamis, 07 Oktober 2010

1 SQL – Structured Query Language
1.1 Tables
In relational database systems (DBS) data are represented using tables (relations). A query issued against the DBS also results in a table. A table has the following structure:

A table is uniquely identified by its name and consists of rows that contain the stored information, each row containing exactly one tuple (or record). A table can have one or more columns.

A column is made up of a column name and a data type, and it describes an attribute of the
tuples. The structure of a table, also called relation schema, thus is defined by its attributes.
The type of information to be stored in a table is defined by the data types of the attributes
at table creation time.

SQL uses the terms table, row, and column for relation, tuple, and attribute, respectively. In
this tutorial we will use the terms interchangeably.

A table can have up to 254 columns which may have different or same data types and sets of
values (domains), respectively. Possible domains are alphanumeric data (strings), numbers and date formats. Oracle offers the following basic data types:
char(n): Fixed-length character data (string), n characters long. The maximum size forn is 255 bytes (2000 in Oracle8). Note that a string of type char is always padded on right with blanks to full length of n. (+ can be memory consuming). Example: char(40)
varchar2(n): Variable-length character string. The maximum size for n is 2000 (4000 in Oracle8). Only the bytes used for a string require storage. Example: varchar2(80)
number(o, d): Numeric data type for integers and reals. o = overall number of digits, d = number of digits to the right of the decimal point. Maximum values: o =38, d= -84 to +127. Examples: number(8), number(5,2) Note that, e.g., number(5,2) cannot contain anything larger than 999.99 without resulting in an error. Data types derived from number are int[eger], dec[imal], smallint and real.
date: Date data type for storing date and time. The default format for a date is: DD-MMM-YY. Examples: ’13-OCT-94’, ’07-JAN-98’
long: Character data up to a length of 2GB. Only one long column is allowed per table.

Note: In Oracle-SQL there is no data type boolean. It can, however, be simulated by using either char(1) or number(1).

As long as no constraint restricts the possible values of an attribute, it may have the special value null (for unknown). This value is different from the number 0, and it is also different from the empty string ’’.

Further properties of tables are:
• the order in which tuples appear in a table is not relevant (unless a query requires an explicit sorting).
• a table has no duplicate tuples (depending on the query, however, duplicate tuples can appear in the query result).

A database schema is a set of relation schemas. The extension of a database schema at database run-time is called a database instance or database, for short.


1.1.1 Example Database
In the following discussions and examples we use an example database to manage information about employees, departments and salary scales. The corresponding tables can be created under the UNIX shell using the command demobld. The tables can be dropped by issuing the command demodrop under the UNIX shell.

The table EMP is used to store information about employees:


For the attributes, the following data types are defined:
EMPNO:number(4), ENAME:varchar2(30), JOB:char(10), MGR:number(4), HIREDATE:date, SAL:number(7,2), DEPTNO:number(2)

Each row (tuple) from the table is interpreted as follows: an employee has a number, a name, a job title and a salary. Furthermore, for each employee the number of his/her manager, the date he/she was hired, and the number of the department where he/she is working are stored.

The table DEPT stores information about departments (number, name, and location):



Finally, the table SALGRADE contains all information about the salary scales, more precisely, the maximum and minimum salary of each scale.


1.2 Queries (Part I)
In order to retrieve the information stored in the database, the SQL query language is used. In the following we restrict our attention to simple SQL queries and defer the discussion of more complex queries to Section 1.5

In SQL a query has the following (simplified) form (components in brackets [ ] are optional):

select [distinct] <column(s)>
from <table>
[ where <condition> ]
[ order by <column(s) [asc|desc]> ]


1.2.1 Selecting Columns
The columns to be selected from a table are specified after the keyword select. This operation is also called projection. For example, the query 

select LOC, DEPTNO from DEPT;

lists only the number and the location for each tuple from the relation DEPT. If all columns should be selected, the asterisk symbol “ ” can be used to denote all attributes. The query

select from EMP;

retrieves all tuples with all columns from the table EMP. Instead of an attribute name, the select clause may also contain arithmetic expressions involving arithmetic operators etc.

select ENAME, DEPTNO, SAL 1.55 from EMP;

For the different data types supported in Oracle, several operators and functions are provided:
• for numbers: abs, cos, sin, exp, log, power, mod, sqrt, +,-, , /, . . .
• for strings: chr, concat(string1, string2), lower, upper, replace(string, search string, replacement string), translate, substr(string, m, n), length, to date, . . .
• for the date data type: add month, month between, next day, to char, . . .

The usage of these operations is described in detail in the SQL*Plus help system (see also Section 2).
Consider the query
select DEPTNO from EMP;

which retrieves the department number for each tuple. Typically, some numbers will appear more than only once in the query result, that is, duplicate result tuples are not automatically eliminated. Inserting the keyword distinct after the keyword select, however, forces the limination of duplicates from the query result.

It is also possible to specify a sorting order in which the result tuples of a query are displayed.

For this the order by clause is used and which has one or more attributes listed in the select clause as parameter. desc specifies a descending order and asc specifies an ascending order (this is also the default order). For example, the query

select ENAME, DEPTNO, HIREDATE from EMP;
from EMP
order by DEPTNO [asc], HIREDATE desc;

displays the result in an ascending order by the attribute DEPTNO. If two tuples have the same attribute value for DEPTNO, the sorting criteria is a descending order by the attribute values of HIREDATE. For the above query, we would get the following output:



1.2.2 Selection of Tuples
Up to now we have only focused on selecting (some) attributes of all tuples from a table. If one is interested in tuples that satisfy certain conditions, the where clause is used. In a where clause simple conditions based on comparison operators can be combined using the logical connectives and, or, and not to form complex conditions. Conditions may also include pattern matching operations and even subqueries (Section 1.5).

Example: List the job title and the salary of those employees whose manager has the number 7698 or 7566 and who earn more than 1500:

select JOB, SAL
from EMP
where (MGR = 7698 or MGR = 7566) and SAL > 1500;

For all data types, the comparison operators =, != or <>,<, >,<=, => are allowed in the conditions of a where clause.

Further comparison operators are:
• Set Conditions: <column> [not] in (<list of values>)
Example: select from DEPT where DEPTNO in (20,30);
• Null value: <column> is [not] null,
i.e., for a tuple to be selected there must (not) exist a defined value for this column.
Example: select from EMP where MGR is not null;
Note: the operations = null and ! = null are not defined!
• Domain conditions: <column> [not] between <lower bound> and <upper bound>
Example: • select EMPNO, ENAME, SAL from EMP
where SAL between 1500 and 2500;
• select ENAME from EMP
where HIREDATE between ’02-APR-81’ and ’08-SEP-81’;


1.2.3 String Operations
In order to compare an attribute with a string, it is required to surround the string by apostrophes, e.g., where LOCATION = ’DALLAS’. A powerful operator for pattern matching is the like operator. Together with this operator, two special characters are used: the percent sign % (also called wild card), and the underline , also called position marker. For example, if one is interested in all tuples of the table DEPT that contain two C in the name of the department, the condition would be where DNAME like ’%C%C%’. The percent sign means that any (sub)string is allowed there, even the empty string. In contrast, the underline stands for exactly one character. Thus the condition where DNAME like ’%C C%’ would require that exactly one character appears between the two Cs. To test for inequality, the not clause is used.

Further string operations are:
• upper(<string>) takes a string and converts any letters in it to uppercase, e.g., DNAME
= upper(DNAME) (The name of a department must consist only of upper case letters.)
• lower(<string>) converts any letter to lowercase,
• initcap(<string>) converts the initial letter of every word in <string> to uppercase.
• length(<string>) returns the length of the string.
• substr(<string>, n [, m]) clips out a m character piece of <string>, starting at position
n. If m is not specified, the end of the string is assumed.
substr(’DATABASE SYSTEMS’, 10, 7) returns the string ’SYSTEMS’.


1.2.4 Aggregate Functions
Aggregate functions are statistical functions such as count, min, max etc. They are used to
compute a single value from a set of attribute values of a column:
count Counting Rows
         Example: How many tuples are stored in the relation EMP?
                       select count( ) from EMP;
         Example: How many different job titles are stored in the relation EMP?
                       select count(distinct JOB) from EMP;
max Maximum value for a column
min Minimum value for a column
         Example: List the minimum and maximum salary.
                       select min(SAL), max(SAL) from EMP;
         Example: Compute the difference between the minimum and maximum salary.
                       select max(SAL) - min(SAL) from EMP;
sum Computes the sum of values (only applicable to the data type number)
         Example: Sum of all salaries of employees working in the department 30.
                       select sum(SAL) from EMP
                       where DEPTNO = 30;
avg Computes average value for a column (only applicable to the data type number)
Note: avg, min and max ignore tuples that have a null value for the specified attribute, but count considers null values.


1.3 Data Definition in SQL
1.3.1 Creating Tables
The SQL command for creating an empty table has the following form:

create table <table> (
<column 1> <data type> [not null] [unique] [<column constraint>],
. . . . . . . . .
<column n> <data type> [not null] [unique] [<column constraint>],
[<table constraint(s)>]
);

For each column, a name and a data type must be specified and the column name must be unique within the table definition. Column definitions are separated by comma. There is no difference between names in lower case letters and names in upper case letters. In fact, the only place where upper and lower case letters matter are strings comparisons. A not null constraint is directly specified after the data type of the column and the constraint requires defined attribute values for that column, different from null.

The keyword unique specifies that no two tuples can have the same attribute value for this column. Unless the condition not null is also specified for this column, the attribute value null is allowed and two tuples having the attribute value null for this column do not violate the constraint.
Example: The create table statement for our EMP table has the form

Remark: Except for the columns EMPNO and ENAME null values are allowed.


1.3.2 Constraints
The definition of a table may include the specification of integrity constraints. Basically two types of constraints are provided: column constraints are associated with a single column whereas table constraints are typically associated with more than one column. However, any column constraint can also be formulated as a table constraint. In this section we consider only very simple constraints. More complex constraints will be discussed in Section 5.1.

The specification of a (simple) constraint has the following form:

[constraint <name>] primary key | unique | not null

A constraint can be named. It is advisable to name a constraint in order to get more meaningful information when this constraint is violated due to, e.g., an insertion of a tuple that violates the constraint. If no name is specified for the constraint, Oracle automatically generates a name of the pattern SYS C<number>.

The two most simple types of constraints have already been discussed: not null and unique. Probably the most important type of integrity constraints in a database are primary key constraints. A primary key constraint enables a unique identification of each tuple in a table.
Based on a primary key, the database system ensures that no duplicates appear in a table. For example, for our EMP table, the specification

create table EMP (
EMPNO number(4) constraint pk emp primary key,
. . . );

defines the attribute EMPNO as the primary key for the table. Each value for the attribute EMPNO thus must appear only once in the table EMP. A table, of course, may only have one primary key. Note that in contrast to a unique constraint, null values are not allowed.
Example:
We want to create a table called PROJECT to store information about projects. For each project, we want to store the number and the name of the project, the employee number of the project’s manager, the budget and the number of persons working on the project, and the start date and end date of the project. Furthermore, we have the following conditions:
- a project is identified by its project number,
- the name of a project must be unique,
- the manager and the budget must be defined.

Table definition:

A unique constraint can include more than one attribute. In this case the pattern unique(<column i>, . . . , <column j>) is used. If it is required, for example, that no two projects have the same start and end date, we have to add the table constraint

constraint no same dates unique(PEND, PSTART)

This constraint has to be defined in the create table command after both columns PEND and PSTART have been defined. A primary key constraint that includes more than only one column can be specified in an analogous way.

Instead of a not null constraint it is sometimes useful to specify a default value for an attribute if no value is given, e.g., when a tuple is inserted. For this, we use the default clause.
Example:
If no start date is given when inserting a tuple into the table PROJECT, the project start date should be set to January 1st, 1995:

PSTART date default(’01-JAN-95’)

Note: Unlike integrity constraints, it is not possible to specify a name for a default.


1.3.3 Checklist for Creating Tables
The following provides a small checklist for the issues that need to be considered before creating a table.
• What are the attributes of the tuples to be stored? What are the data types of the attributes? Should varchar2 be used instead of char ?
• Which columns build the primary key?
• Which columns do (not) allow null values? Which columns do (not) allow duplicates ?
• Are there default values for certain columns that allow null values ?


1.4 Data Modifications in SQL
After a table has been created using the create table command, tuples can be inserted into the table, or tuples can be deleted or modified.


1.4.1 Insertions
The most simple way to insert a tuple into a table is to use the insert statement

insert into <table> [(<column i, . . . , column j>)]
values (<value i, . . . , value j>);

For each of the listed columns, a corresponding (matching) value must be specified. Thus an
insertion does not necessarily have to follow the order of the attributes as specified in the create table statement. If a column is omitted, the value null is inserted instead. If no column list is given, however, for each column as defined in the create table statement a value must be given.
Examples:

insert into PROJECT(PNO, PNAME, PERSONS, BUDGET, PSTART)
values(313, ’DBS’, 4, 150000.42, ’10-OCT-94’);
or
insert into PROJECT
values(313, ’DBS’, 7411, null, 150000.42, ’10-OCT-94’, null);

If there are already some data in other tables, these data can be used for insertions into a new table. For this, we write a query whose result is a set of tuples to be inserted. Such an insert statement has the form

insert into <table> [(<column i, . . . , column j>)] <query>

Example: Suppose we have defined the following table:

create table OLDEMP (
ENO number(4) not null,
HDATE date);

We now can use the table EMP to insert tuples into this new relation:

insert into OLDEMP (ENO, HDATE)
select EMPNO, HIREDATE from EMP
where HIREDATE < ’31-DEC-60’;


1.4.2 Updates
For modifying attribute values of (some) tuples in a table, we use the update statement:

update <table> set
<column i> = <expression i>, . . . , <column j> = <expression j>
[where <condition>];

An expression consists of either a constant (new value), an arithmetic or string operation, or an SQL query. Note that the new value to assign to <column i> must a the matching data type.
An update statement without a where clause results in changing respective attributes of all tuples in the specified table. Typically, however, only a (small) portion of the table requires an update.
Examples:
• The employee JONES is transfered to the department 20 as a manager and his salary is increased by 1000:
update EMP set
JOB = ’MANAGER’, DEPTNO = 20, SAL = SAL +1000
where ENAME = ’JONES’;

• All employees working in the departments 10 and 30 get a 15% salary increase.
update EMP set
SAL = SAL 1.15 where DEPTNO in (10,30);

Analogous to the insert statement, other tables can be used to retrieve data that are used as
new values. In such a case we have a <query> instead of an <expression>.
Example: All salesmen working in the department 20 get the same salary as the manager who has the lowest salary among all managers.

update EMP set
SAL = (select min(SAL) from EMP
where JOB = ’MANAGER’)
where JOB = ’SALESMAN’ and DEPTNO = 20;

Explanation: The query retrieves the minimum salary of all managers. This value then is
assigned to all salesmen working in department 20.

It is also possible to specify a query that retrieves more than only one value (but still only one tuple!). In this case the set clause has the form set(<column i, . . . , column j>) = <query>. It is important that the order of data types and values of the selected row exactly correspond to the list of columns in the set clause.


1.4.3 Deletions
All or selected tuples can be deleted from a table using the delete command:

delete from <table> [where <condition>];

If the where clause is omitted, all tuples are deleted from the table. An alternative command
for deleting all tuples from a table is the truncate table <table> command. However, in this case, the deletions cannot be undone (see subsequent Section 1.4.4).

Example:
Delete all projects (tuples) that have been finished before the actual date (system date):

delete from PROJECT where PEND < sysdate;

sysdate is a function in SQL that returns the system date. Another important SQL function is user, which returns the name of the user logged into the current Oracle session.


1.4.4 Commit and Rollback
A sequence of database modifications, i.e., a sequence of insert, update, and delete statements, is called a transaction. Modifications of tuples are temporarily stored in the database system. They become permanent only after the statement commit; has been issued.

As long as the user has not issued the commit statement, it is possible to undo all modifications since the last commit. To undo modifications, one has to issue the statement rollback;.

It is advisable to complete each modification of the database with a commit (as long as the modification has the expected effect). Note that any data definition command such as  createtable results in an internal commit. A commit is also implicitly executed when the user terminates an Oracle session.


1.5 Queries (Part II)
In Section 1.2 we have only focused on queries that refer to exactly one table. Furthermore, conditions in a where were restricted to simple comparisons. A major feature of relational databases, however, is to combine (join) tuples stored in different tables in order to display more meaningful and complete information. In SQL the select statement is used for this kind of queries joining relations:

select [distinct] [<alias ak>.]<column i>, . . . , [<alias al>.]<column j>
from <table 1> [<alias a1>], . . . , <table n> [<alias an>]
[where <condition>]

The specification of table aliases in the from clause is necessary to refer to columns that have
the same name in different tables. For example, the column DEPTNO occurs in both EMP and DEPT. If we want to refer to either of these columns in the where or select clause, a table alias has to be specified and put in the front of the column name. Instead of a table  alias also the complete relation name can be put in front of the column such as DEPT.DEPTNO, but this sometimes can lead to rather lengthy query formulations.


1.5.1 Joining Relations
Comparisons in the where clause are used to combine rows from the tables listed in the from
clause.
Example: In the table EMP only the numbers of the departments are stored, not their name. For each salesman, we now want to retrieve the name as well as the number and the name of the department where he is working:

select ENAME, E.DEPTNO, DNAME
from EMP E, DEPT D
where E.DEPTNO = D.DEPTNO
and JOB = ’SALESMAN’;

Explanation: E and D are table aliases for EMP and DEPT, respectively. The computation of the query result occurs in the following manner (without optimization):
1. Each row from the table EMP is combined with each row from the table DEPT (this operation is called Cartesian product). If EMP contains m rows and DEPT contains n rows, we thus get n m rows.
2. From these rows those that have the same department number are selected (where E.DEPTNO = D.DEPTNO).
3. From this result finally all rows are selected for which the condition JOB = ’SALESMAN’ holds.

In this example the joining condition for the two tables is based on the equality operator “=”.
The columns compared by this operator are called join columns and the join operation is called an equijoin.

Any number of tables can be combined in a select statement.
Example: For each project, retrieve its name, the name of its manager, and the name of the department where the manager is working:

select ENAME, DNAME, PNAME
from EMP E, DEPT D, PROJECT P
where E.EMPNO = P.MGR
and D.DEPTNO = E.DEPTNO;

It is even possible to join a table with it self:
Example: List the names of all employees together with the name of their manager:

select E1.ENAME, E2.ENAME
from EMP E1, EMP E2
where E1.MGR = E2.EMPNO;

Explanation: The join columns are MGR for the table E1 and EMPNO for the table E2.
The equijoin comparison is E1.MGR = E2.EMPNO.


1.5.2 Subqueries
Up to now we have only concentrated on simple comparison conditions in a where clause, i.e., we have compared a column with a constant or we have compared two columns. As we have already seen for the insert statement, queries can be used for assignments to columns. A query result can also be used in a condition of a where clause. In such a case the query is called a subquery and the complete select statement is called a nested query.

A respective condition in the where clause then can have one of the following forms:
1. Set-valued subqueries

<expression> [not] in (<subquery>)
<expression> <comparison operator> [any|all] (<subquery>)

An <expression> can either be a column or a computed value.

2. Test for (non)existence

[not] exists (<subquery>)

In a where clause conditions using subqueries can be combined arbitrarily by using the logical connectives and and or.

Example: List the name and salary of employees of the department 20 who are leading a project that started before December 31, 1990:

select ENAME, SAL from EMP
where EMPNO in
(select PMGR from PROJECT
where PSTART < ’31-DEC-90’)
and DEPTNO =20;

Explanation: The subquery retrieves the set of those employees who manage a project that started before December 31, 1990. If the employee working in department 20 is contained in this set (in operator), this tuple belongs to the query result set.
Example: List all employees who are working in a department located in BOSTON:

select from EMP
where DEPTNO in
(select DEPTNO from DEPT
where LOC = ’BOSTON’);

The subquery retrieves only one value (the number of the department located in Boston). Thus it is possible to use “=” instead of in. As long as the result of a subquery is not known in advance, i.e., whether it is a single value or a set, it is advisable to use the in operator.

A subquery may use again a subquery in its where clause. Thus conditions can be nested arbitrarily. An important class of subqueries are those that refer to its surrounding (sub)query and the tables listed in the from clause, respectively. Such type of queries is called correlated subqueries.
Example: List all those employees who are working in the same department as their manager (note that components in [ ] are optional:

select from EMP E1
where DEPTNO in
(select DEPTNO from EMP [E]
where [E.]EMPNO = E1.MGR);

Explanation: The subquery in this example is related to its surrounding query since it refers to the column E1.MGR. A tuple is selected from the table EMP (E1) for the query result if the value for the column DEPTNO occurs in the set of values select in the subquery. One can think of the evaluation of this query as follows: For each tuple in the table E1, the subquery is evaluated individually. If the condition where DEPTNO in . . . evaluates to true, this tuple is selected. Note that an alias for the table EMP in the subquery is not necessary since columns without a preceding alias listed there always refer to the innermost query and tables.

Conditions of the form <expression> <comparison operator> [any|all] <subquery> are used to compare a given <expression> with each value selected by <subquery>.
• For the clause any, the condition evaluates to true if there exists at least on row selected by the subquery for which the comparison holds. If the subquery yields an empty result set, the condition is not satisfied.
• For the clause all, in contrast, the condition evaluates to true if for all rows selected by the subquery the comparison holds. In this case the condition evaluates to true if the subquery does not yield any row or value.

Example: Retrieve all employees who are working in department 10 and who earn at least as much as any (i.e., at least one) employee working in department 30:

select from EMP
where SAL >= any
(select SAL from EMP
where DEPTNO = 30)
and DEPTNO = 10;

Note: Also in this subquery no aliases are necessary since the columns refer to the innermost
from clause.

Example: List all employees who are not working in department 30 and who earn more than
all employees working in department 30:

select from EMP
where SAL > all
(select SAL from EMP
where DEPTNO = 30)
and DEPTNO <> 30;

For all and any, the following equivalences hold:

in , = any
not in , <> all or != all

Often a query result depends on whether certain rows do (not) exist in (other) tables. Such
type of queries is formulated using the exists operator.

Example: List all departments that have no employees:

select from DEPT
where not exists
(select from EMP
where DEPTNO = DEPT.DEPTNO);

Explanation: For each tuple from the table DEPT, the condition is checked whether there exists a tuple in the table EMP that has the same department number (DEPT.DEPTNO). In case no such tuple exists, the condition is satisfied for the tuple under consideration and it is selected. If there exists a corresponding tuple in the table EMP, the tuple is not selected.


2 SQL*Plus
Introduction
SQL*Plus is the interactive (low-level) user interface to the Oracle database management system. Typically, SQL*Plus is used to issue ad-hoc queries and to view the query result on the screen. Some of the features of SQL*Plus are:
• A built-in command line editor can be used to edit (incorrect) SQL queries. Instead of this line editor any editor installed on the computer can be invoked.
• There are numerous commands to format the output of a query.
• SQL*Plus provides an online-help.
• Query results can be stored in files which then can be printed.

Queries that are frequently issued can be saved to a file and invoked later. Queries can be parameterized such that it is possible to invoke a saved query with a parameter.
A Minimal User Guide Before you start SQL*Plus make sure that the following UNIX shell variables are properly set (shell variables can be checked using the env command, e.g., env | grep ORACLE):
• ORACLE HOME, e.g., ORACLE HOME=/usr/pkg/oracle/734
• ORACLE SID, e.g, ORACLE SID=prod

In order to invoke SQL*Plus from a UNIX shell, the command sqlplus has to be issued. SQL*Plus then displays some information about the product, and prompts you for your user name and password for the Oracle system.
gertz(catbert)54: sqlplus
SQL*Plus: Release 3.3.4.0.1 - Production on Sun Dec 20 19:16:52 1998
Copyright (c) Oracle Corporation 1979, 1996. All rights reserved.
Enter user-name: scott
Enter password:
Connected to:
Oracle7 Server Release 7.3.4.0.1 - Production Release
With the distributed option
PL/SQL Release 2.3.4.0.0 - Production
SQL>
SQL> is the prompt you get when you are connected to the Oracle database system. In SQL*Plus you can divide a statement into separate lines, each continuing line is indicated by a prompt such 2>, 3> etc. An SQL statement must always be terminated by a semicolon (;). In addition to the SQL statements discussed in the previous section, SQL*Plus provides some
special SQL*Plus commands. These commands need not be terminated by a semicolon. Upper and lower case letters are only important for string comparisons. An SQL query can always be interrupted by using <Control>C. To exit SQL*Plus you can either type exit or quit.


Editor Commands
The most recently issued SQL statement is stored in the SQL buffer, independent of whether the statement has a correct syntax or not. You can edit the buffer using the following commands:
• l[ist] lists all lines in the SQL buffer and sets the current line (marked with an ” ”) to
the last line in the buffer.
• l<number> sets the actual line to <number>
• c[hange]/<old string>/<new string> replaces the first occurrence of <old string> by
<new string> (for the actual line)
• a[ppend]<string> appends <string> to the current line
• del deletes the current line
• r[un] executes the current buffer contents
• get<file> reads the data from the file <file> into the buffer
• save<file> writes the current buffer into the file <file>
• edit invokes an editor and loads the current buffer into the editor. After exiting the editor the modified SQL statement is stored in the buffer and can be executed (command r).

The editor can be defined in the SQL*Plus shell by typing the command define editor = <name>, where <name> can be any editor such as emacs, vi, joe, or jove.


SQL*Plus Help System and Other Useful Commands
• To get the online help in SQL*Plus just type help <command>, or just help to get information about how to use the help command. In Oracle Version 7 one can get the complete list of possible commands by typing help command.
• To change the password, in Oracle Version 7 the command

alter user <user> identified by <new password>;

is used. In Oracle Version 8 the command passw <user> prompts the user for the old/new password.
• The command desc[ribe] <table> lists all columns of the given table together with their data types and information about whether null values are allowed or not.
• You can invoke a UNIX command from the SQL*Plus shell by using host <UNIX command>.
For example, host ls -la *.sql lists all SQL files in the current directory.
• You can log your SQL*Plus session and thus queries and query results by using the command spool <file>. All information displayed on screen is then stored in <file> which automatically gets the extension .lst. The command spool off turns spooling off.
• The command copy can be used to copy a complete table. For example, the command 

copy from scott/tiger create EMPL using select from EMP;

copies the table EMP of the user scott with password tiger into the relation EMPL. The relation EMP is automatically created and its structure is derived based on the attributes listed in the select clause.
• SQL commands saved in a file <name>.sql can be loaded into SQL*Plus and executed using the command @<name>.
• Comments are introduced by the clause rem[ark] (only allowed between SQL statements),
or - - (allowed within SQL statements).

Formatting the Output
SQL*Plus provides numerous commands to format query results and to build simple reports.
For this, format variables are set and these settings are only valid during the SQL*Plus session. They get lost after terminating SQL*Plus. It is, however, possible to save settings in a file named login.sql in your home directory. Each time you invoke SQL*Plus this file is automatically loaded.

The command column <column name> <option 1> <option 2> . . . is used to format columns of your query result. The most frequently used options are:
• format A<n> For alphanumeric data, this option sets the length of <column name> to <n>. For columns having the data type number, the format command can be used to specify the format before and after the decimal point. For example, format 99,999.99 specifies that if a value has more than three digits in front of the decimal point, digits are separated by a colon, and only two digits are displayed after the decimal point.
• The option heading <text> relabels <column name> and gives it a new heading.
• null <text> is used to specify the output of null values (typically, null values are not displayed).
• column <column name> clear deletes the format definitions for <column name>.

The command set linesize <number> can be used to set the maximum length of a single line that can be displayed on screen. set pagesize <number> sets the total number of lines SQL*Plus displays before printing the column names and headings, respectively, of the selected rows.
Several other formatting features can be enabled by setting SQL*Plus variables. The command show all displays all variables and their current values. To set a variable, type set <variable> <value>. For example, set timing on causes SQL*Plus to display timing statistics for each SQL command that is executed. set pause on [<text>] makes SQL*Plus wait for you to press Return after the number of lines defined by set pagesize has been displayed. <text> is the message SQL*Plus will display at the bottom of the screen as it waits for you to hit Return.


3 Application Programming
3.1 PL/SQL
3.1.1 Introduction
The development of database applications typically requires language constructs similar to those that can be found in programming languages such as C, C++, or Pascal. These constructs are necessary in order to implement complex data structures and algorithms. A major restriction of the database language SQL, however, is that many tasks cannot be accomplished by using only the provided language elements.
PL/SQL (Procedural Language/SQL) is a procedural extension of Oracle-SQL that offers language constructs similar to those in imperative programming languages. PL/SQL allows users and designers to develop complex database applications that require the usage of control structures and procedural elements such as procedures, functions, and modules.
The basic construct in PL/SQL is a block. Blocks allow designers to combine logically related (SQL-) statements into units. In a block, constants and variables can be declared, and variables can be used to store query results. Statements in a PL/SQL block include SQL statements, control structures (loops), condition statements (if-then-else), exception handling, and calls of other PL/SQL blocks.
PL/SQL blocks that specify procedures and functions can be grouped into packages. A package is similar to a module and has an interface and an implementation part. Oracle offers several predefined packages, for example, input/output routines, file handling, job scheduling etc. (see directory $ORACLE HOME/rdbms/admin).
Another important feature of PL/SQL is that it offers a mechanism to process query results in a tuple-oriented way, that is, one tuple at a time. For this, cursors are used. A cursor basically is a pointer to a query result and is used to read attribute values of selected tuples into variables. A cursor typically is used in combination with a loop construct such that each tuple read by the cursor can be processed individually.

In summary, the major goals of PL/SQL are to
• increase the expressiveness of SQL,
• process query results in a tuple-oriented way,
• optimize combined SQL statements,
• develop modular database application programs,
• reuse program code, and
• reduce the cost for maintaining and changing applications.

3.1.2 Structure of PL/SQL-Blocks
PL/SQL is a block-structured language. Each block builds a (named) program unit, and blocks can be nested. Blocks that build a procedure, a function, or a package must be named.
A PL/SQL block has an optional declare section, a part containing PL/SQL statements, and an
optional exception-handling part. Thus the structure of a PL/SQL looks as follows (brackets [ ] enclose optional parts):
[<Block header>]
[declare
<Constants>
<Variables>
<Cursors>
<User defined exceptions>]
begin
<PL/SQL statements>
[exception
<Exception handling>]
end;
The block header specifies whether the PL/SQL block is a procedure, a function, or a package.
If no header is specified, the block is said to be an anonymous PL/SQL block. Each PL/SQL block again builds a PL/SQL statement. Thus blocks can be nested like blocks in conventional
programming languages. The scope of declared variables (i.e., the part of the program in which one can refer to the variable) is analogous to the scope of variables in programming languages such as C or Pascal.


3.1.3 Declarations
Constants, variables, cursors, and exceptions used in a PL/SQL block must be declared in the
declare section of that block. Variables and constants can be declared as follows:

<variable name> [constant] <data type> [not null] [:= <expression>];

Valid data types are SQL data types (see Section 1.1) and the data type boolean. Boolean data may only be true, false, or null. The not null clause requires that the declared variable must always have a value different from null. <expression> is used to initialize a variable.
If no expression is specified, the value null is assigned to the variable. The clause constant states that once a value has been assigned to the variable, the value cannot be changed (thus
the variable becomes a constant). Example:
declare
hire date date; /* implicit initialization with null */
job title varchar2(80) := ’Salesman’;
emp found boolean; /* implicit initialization with null */
salary incr constant number(3,2) := 1.5; /* constant */
. . .
begin . . . end;

Instead of specifying a data type, one can also refer to the data type of a table column (so-called anchored declaration). For example, EMP.Empno%TYPE refers to the data type of the column Empno in the relation EMP. Instead of a single variable, a record can be declared that can store a complete tuple from a given table (or query result). For example, the data type DEPT%ROWTYPE specifies a record suitable to store all attribute values of a complete row from the table DEPT.
Such records are typically used in combination with a cursor. A field in a record can be accessed using <record name>.<column name>, for example, DEPT.Deptno.
A cursor declaration specifies a set of tuples (as a query result) such that the tuples can be processed in a tuple-oriented way (i.e., one tuple at a time) using the fetch statement. A cursor declaration has the form

cursor <cursor name> [(<list of parameters>)] is <select statement>;

The cursor name is an undeclared identifier, not the name of any PL/SQL variable. A parameter has the form <parameter name> <parameter type>. Possible parameter types are char, varchar2, number, date and boolean as well as corresponding subtypes such as integer.
Parameters are used to assign values to the variables that are given in the select statement.

Example: We want to retrieve the following attribute values from the table EMP in a tupleoriented way: the job title and name of those employees who have been hired after a given date, and who have a manager working in a given department.

cursor employee cur (start date date, dno number) is
select JOB, ENAME from EMP E where HIREDATE > start date
and exists (select from EMP
where E.MGR = EMPNO and DEPTNO = dno);

If (some) tuples selected by the cursor will be modified in the PL/SQL block, the clause for update[(<column(s)>)] has to be added at the end of the cursor declaration. In this case selected tuples are locked and cannot be accessed by other users until a commit has been issued. Before a declared cursor can be used in PL/SQL statements, the cursor must be opened, and after processing the selected tuples the cursor must be closed. We discuss the usage of cursors in more detail below.
Exceptions are used to process errors and warnings that occur during the execution of PL/SQL statements in a controlled manner. Some exceptions are internally defined, such as ZERO DIVIDE.
Other exceptions can be specified by the user at the end of a PL/SQL block. User defined exceptions need to be declared using <name of exception> exception. We will discuss exception handling in more detail in Section 4.1.5


3.1.4 Language Elements
In addition to the declaration of variables, constants, and cursors, PL/SQL offers various language constructs such as variable assignments, control structures (loops, if-then-else), procedure and function calls, etc. However, PL/SQL does not allow commands of the SQL data definition language such as the create table statement. For this, PL/SQL provides special packages.

Furthermore, PL/SQL uses a modified select statement that requires each selected tuple to be
assigned to a record (or a list of variables).

There are several alternatives in PL/SQL to a assign a value to a variable. The most simple way to assign a value to a variable is

declare
counter integer := 0;
. . .
begin
counter := counter + 1;

Values to assign to a variable can also be retrieved from the database using a select statement

select <column(s)> into <matching list of variables>
from <table(s)> where <condition>;

It is important to ensure that the select statement retrieves at most one tuple ! Otherwise it is not possible to assign the attribute values to the specified list of variables and a runtime error occurs. If the select statement retrieves more than one tuple, a cursor must be used instead. Furthermore, the data types of the specified variables must match those of the retrieved attribute values. For most data types, PL/SQL performs an automatic type conversion (e.g., from integer to real).
Instead of a list of single variables, a record can be given after the keyword into. Also in this
case, the select statement must retrieve at most one tuple !

declare
employee rec EMP%ROWTYPE;
max sal EMP.SAL%TYPE;
begin
select EMPNO, ENAME, JOB, MGR, SAL, COMM, HIREDATE, DEPTNO
into employee rec
from EMP where EMPNO = 5698;
select max(SAL) into max sal from EMP;
. . .
end;

PL/SQL provides while-loops, two types of for-loops, and continuous loops. Latter ones are used in combination with cursors. All types of loops are used to execute a sequence of statements multiple times. The specification of loops occurs in the same way as known from imperative programming languages such as C or Pascal.
A while-loop has the pattern

[<< <label name> >>]
while <condition> loop
<sequence of statements>;
end loop [<label name>] ;

A loop can be named. Naming a loop is useful whenever loops are nested and inner loops are completed unconditionally using the exit <label name>; statement.

Whereas the number of iterations through a while loop is unknown until the loop completes,
the number of iterations through the for loop can be specified using two integers.

[<< <label name> >>]
for <index> in [reverse] <lower bound>..<upper bound> loop
<sequence of statements>
end loop [<label name>] ;

The loop counter <index> is declared implicitly. The scope of the loop counter is only the for loop. It overrides the scope of any variable having the same name outside the loop. Inside the for loop, <index> can be referenced like a constant. <index> may appear in expressions, but one cannot assign a value to <index>. Using the keyword reverse causes the iteration to proceed downwards from the higher bound to the lower bound.

Processing Cursors: Before a cursor can be used, it must be opened using the open statement

open <cursor name> [(<list of parameters>)] ;

The associated select statement then is processed and the cursor references the first selected tuple. Selected tuples then can be processed one tuple at a time using the fetch command fetch <cursor name> into <list of variables>;
The fetch command assigns the selected attribute values of the current tuple to the list of variables. After the fetch command, the cursor advances to the next tuple in the result set. Note that the variables in the list must have the same data types as the selected values. After all tuples have been processed, the close command is used to disable the cursor.
close <cursor name>;

The example below illustrates how a cursor is used together with a continuous loop:

declare
cursor emp cur is select from EMP;
emp rec EMP%ROWTYPE;
emp sal EMP.SAL%TYPE;
begin
open emp cur;
loop
fetch emp cur into emp rec;
exit when emp cur%NOTFOUND;
emp sal := emp rec.sal;
<sequence of statements>
end loop;
close emp cur;
. . .
end;

Each loop can be completed unconditionally using the exit clause:

exit [<block label>] [when <condition>]

Using exit without a block label causes the completion of the loop that contains the exit statement.
A condition can be a simple comparison of values. In most cases, however, the condition refers to a cursor. In the example above, %NOTFOUND is a predicate that evaluates to false if the most recent fetch command has read a tuple. The value of <cursor name>%NOTFOUND is null before the first tuple is fetched. The predicate evaluates to true if the most recent fetch failed to return a tuple, and false otherwise. %FOUND is the logical opposite of %NOTFOUND.

Cursor for loops can be used to simplify the usage of a cursor:

[<< <label name> >>]
for <record name> in <cursor name>[(<list of parameters>)] loop
<sequence of statements>
end loop [<label name>];

A record suitable to store a tuple fetched by the cursor is implicitly declared. Furthermore, this loop implicitly performs a fetch at each iteration as well as an open before the loop is entered and a close after the loop is left. If at an iteration no tuple has been fetched, the loop is automatically terminated without an exit.

It is even possible to specify a query instead of <cursor name> in a for loop:

for <record name> in (<select statement>) loop
<sequence of statements>
end loop;

That is, a cursor needs not be specified before the loop is entered, but is defined in the select
statement.
Example:
for sal rec in (select SAL + COMM total from EMP) loop
. . . ;
end loop;

total is an alias for the expression computed in the select statement. Thus, at each iteration only one tuple is fetched. The record sal rec, which is implicitly defined, then contains only one entry which can be accessed using sal rec.total. Aliases, of course, are not necessary if only attributes are selected, that is, if the select statement contains no arithmetic operators or aggregate functions.

For conditional control, PL/SQL offers if-then-else constructs of the pattern

if <condition> then <sequence of statements>
[elsif ] <condition> then <sequence of statements>
. . .
[else] <sequence of statements> end if ;

Starting with the first condition, if a condition yields true, its corresponding sequence of statements is executed, otherwise control is passed to the next condition. Thus the behavior of this type of PL/SQL statement is analogous to if-then-else statements in imperative programming languages.

Except data definition language commands such as create table, all types of SQL statements can be used in PL/SQL blocks, in particular delete, insert, update, and commit. Note that in PL/SQL only select statements of the type select <column(s)> into are allowed, i.e., selected attribute values can only be assigned to variables (unless the select statement is used in a subquery). The usage of select statements as in SQL leads to a syntax error. If update or delete statements are used in combination with a cursor, these commands can be restricted to currently fetched tuple. In these cases the clause where current of<cursor name> is added
as shown in the following example.

Example: The following PL/SQL block performs the following modifications: All employees having ’KING’ as their manager get a 5% salary increase.

declare
manager EMP.MGR%TYPE;
cursor emp cur (mgr no number) is
select SAL from EMP
where MGR = mgr no
for update of SAL;
begin
select EMPNO into manager from EMP
where ENAME = ’KING’;
for emp rec in emp cur(manager) loop
update EMP set SAL = emp rec.sal 1.05
where current of emp cur;
end loop;
commit;
end;

Remark: Note that the record emp rec is implicitly defined. We will discuss another version of this block using parameters in Section 4.1.6.


3.1.5 Exception Handling
A PL/SQL block may contain statements that specify exception handling routines. Each error or warning during the execution of a PL/SQL block raises an exception. One can distinguish between two types of exceptions:
• system defined exceptions
• user defined exceptions (which must be declared by the user in the declaration part of a
block where the exception is used/implemented)

System defined exceptions are always automatically raised whenever corresponding errors or warnings occur. User defined exceptions, in contrast, must be raised explicitly in a sequence of statements using raise <exception name>. After the keyword exception at the end of a block, user defined exception handling routines are implemented. An implementation has the pattern

when <exception name> then <sequence of statements>;

The most common errors that can occur during the execution of PL/SQL programs are handled by system defined exceptions. The table below lists some of these exceptions with their names and a short description.

Exception name Number Remark


Example:
declare
emp sal EMP.SAL%TYPE;
emp no EMP.EMPNO%TYPE;
too high sal exception;
begin
select EMPNO, SAL into emp no, emp sal
from EMP where ENAME = ’KING’;
if emp sal 1.05 > 4000 then raise too high sal
else update EMP set SQL . . .
end if ;
exception
when NO DATA FOUND – – no tuple selected
then rollback;
when too high sal then insert into high sal emps values(emp no);
commit;
end;

After the keyword when a list of exception names connected with or can be specified. The last when clause in the exception part may contain the exception name others. This introduces the default exception handling routine, for example, a rollback.

If a PL/SQL program is executed from the SQL*Plus shell, exception handling routines may contain statements that display error or warning messages on the screen. For this, the procedure raise application error can be used. This procedure has two parameters <error number> and <message text>. <error number> is a negative integer defined by the user and must range between -20000 and -20999. <error message> is a string with a length up to 2048 characters.

The concatenation operator “||” can be used to concatenate single strings to one string. In order to display numeric variables, these variables must be converted to strings using the function to char. If the procedure raise application error is called from a PL/SQL block, processing the PL/SQL block terminates and all database modifications are undone, that is, an implicit rollback is performed in addition to displaying the error message.

Example:
if emp sal 1.05 > 4000
then raise application error(-20010, ’Salary increase for employee with Id ’
|| to char(Emp no) || ’ is too high’);
4.1.6 Procedures and Functions
PL/SQL provides sophisticated language constructs to program procedures and functions as
stand-alone PL/SQL blocks. They can be called from other PL/SQL blocks, other procedures
and functions. The syntax for a procedure definition is
create [or replace] procedure <procedure name> [(<list of parameters>)] is
<declarations>
begin
<sequence of statements>
[exception
<exception handling routines>]
end [<procedure name>];
A function can be specified in an analogous way
create [or replace] function <function name> [(<list of parameters>)]
return <data type> is
. . .

The optional clause or replace re-creates the procedure/function. A procedure can be deleted
using the command drop procedure <procedure name> (drop function <function name>). In contrast to anonymous PL/SQL blocks, the clause declare may not be used in procedure/ function definitions.
Valid parameters include all data types. However, for char, varchar2, and number no length and scale, respectively, can be specified. For example, the parameter number(6) results in a compile error and must be replaced by number. Instead of explicit data types, implicit types of the form %TYPE and %ROWTYPE can be used even if constrained declarations are referenced.

A parameter is specified as follows:
<parameter name> [IN | OUT | IN OUT] <data type> [{ := | DEFAULT} <expression>]

The optional clauses IN, OUT, and IN OUT specify the way in which the parameter is used.
The default mode for a parameter is IN. IN means that the parameter can be referenced inside the procedure body, but it cannot be changed. OUT means that a value can be assigned to the parameter in the body, but the parameter’s value cannot be referenced. IN OUT allows both assigning values to the parameter and referencing the parameter. Typically, it is sufficient to use the default mode for parameters.

Example: The subsequent procedure is used to increase the salary of all employees who work in the department given by the procedure’s parameter. The percentage of the salary increase is given by a parameter, too.

sumber :
gertz@cs.ucdavis.edu
http://www.db.cs.ucdavis.edu

0 komentar:

Posting Komentar