PLSQL Material
PLSQL Material
It was
developed by Oracle Corporation in the early 90's to enhance the capabilities of SQL. PL/SQL is one of
three key programming languages embedded in the Oracle Database, along with SQL itself and Java.
This tutorial will give you great understanding on PL/SQL to proceed with Oracle database and other
advanced RDBMS concepts.
Before proceeding with this tutorial, you should have a basic understanding of software basic concepts
like what is database, source code, text editor and execution of programs, etc. If you already have an
understanding on SQL and other computer programming language, then it will be an added advantage
to proceed.
Features of PL/SQL
PL/SQL has the following features −
Advantages of PL/SQL
PL/SQL has the following advantages −
SQL is the standard database language and PL/SQL is strongly integrated with SQL. PL/SQL
supports both static and dynamic SQL. Static SQL supports DML operations and transaction control
from PL/SQL block. In Dynamic SQL, SQL allows embedding DDL statements in PL/SQL blocks.
PL/SQL allows sending an entire block of statements to the database at one time. This reduces
network traffic and provides high performance for the applications.
PL/SQL gives high productivity to programmers as it can query, transform, and update data in a
database.
PL/SQL saves time on design and debugging by strong features, such as exception handling,
encapsulation, data hiding, and object-oriented data types.
Applications written in PL/SQL are fully portable.
PL/SQL provides high security level.
PL/SQL provides access to predefined SQL packages.
PL/SQL provides support for Object-Oriented Programming.
PL/SQL provides support for developing Web Applications and Server Pages.
In this chapter, we will discuss the Basic Syntax of PL/SQL which is a block-structured language;
this means that the PL/SQL programs are divided and written in logical blocks of code. Each block
consists of three sub-parts –
Declarations
This section starts with the keyword DECLARE. It is an optional section and defines all variables,
cursors, subprograms, and other elements to be used in the program
Executable Commands
This section is enclosed between the keywords BEGIN and END and it is a mandatory section. It
consists of the executable PL/SQL statements of the program. It should have at least one executable
line of code, which may be just a NULL command to indicate that nothing should be executed.
Exception Handling
This section starts with the keyword EXCEPTION. This optional section contains exception(s) that
handle errors in the program.
Every PL/SQL statement ends with a semicolon (;). PL/SQL blocks can be nested within other PL/SQL
blocks using BEGIN and END. Following is the basic structure of a PL/SQL block –
DECLARE
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
<exception handling>
END;
BEGIN
dbms_output.put_line(message);
END;
Hello World
DECLARE
-- variable declaration
BEGIN
/*
*/
dbms_output.put_line(message);
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Hello World
PL/SQL procedure successfully completed.
PL/SQL block
Function
Package
Package body
Procedure
Trigger
Type
Type body
In this chapter, we will discuss the Data Types in PL/SQL. The PL/SQL variables, constants and
parameters must have a valid data type, which specifies a storage format, constraints, and a valid
range of values. We will focus on the SCALAR and the LOB data types in this chapter. The other two
data types will be covered in other chapters.
Scalar:
Pointers to large objects that are stored separately from other data items, such as text, graphic
images, video clips, and sound waveforms.
Composite:
Data items that have internal components that can be accessed individually. For example, collections
and records.
Reference
Pointers to other data items.
Numeric
Numeric values on which arithmetic operations are performed.
Character
Alphanumeric values that represent single characters or strings of
characters.
Boolean
Logical values on which logical operations are performed.
Datetime
Dates and times.
NULLs in PL/SQL
PL/SQL NULL values represent missing or unknown data and they are not
an integer, a character, or any other specific data type. Note that NULL is
not the same as an empty data string or the null character value '\0'. A
null can be assigned but it cannot be equated with anything, including itself.
PL/SQL programming language allows to define various types of variables, such as date time data
types, records, collections, etc. which we will cover in subsequent chapters. For this chapter, let us
study only basic variable types.
The assignment operator
For example −
counter binary_integer := 0;
greetings varchar2(20) DEFAULT 'Have a Good Day';
You can also specify that a variable should not have a NULLvalue using
the NOT NULL constraint. If you use the NOT NULL constraint, you must
explicitly assign an initial value for that variable.
It is a good programming practice to initialize variables properly otherwise,
sometimes programs would produce unexpected results. Try the following
example which makes use of various types of variables −
DECLARE
a integer := 10;
b integer := 20;
c integer;
f real;
BEGIN
c := a + b;
f := 70.0/3.0;
END;
-- Global variables
BEGIN
DECLARE
-- Local variables
BEGIN
dbms_output.put_line('Inner Variable num1: ' || num1);
END;
END;
/
);
Table Created
The following program assigns values from the above table to PL/SQL
variables using the SELECT INTO clause of SQL −
DECLARE
c_id customers.id%type := 1;
c_name customers.name%type;
c_addr customers.address%type;
c_sal customers.salary%type;
BEGIN
FROM customers
WHERE id = c_id;
dbms_output.put_line
('Customer ' ||c_name || ' from ' || c_addr || ' earns ' || c_sal);
END;
Declaring a Constant
A constant is declared using the CONSTANT keyword. It requires an initial
value and does not allow that value to be changed. For example −
PI CONSTANT NUMBER := 3.141592654;
DECLARE
-- constant declaration
-- other declarations
radius number(5,2);
dia number(5,2);
BEGIN
-- processing
radius := 9.5;
dia := radius * 2;
-- output
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Radius: 9.5
Diameter: 19
Circumference: 59.69
Area: 283.53
Numeric Literals
Character Literals
String Literals
BOOLEAN Literals
Numeric Literals
Character Literals
2
'A' '%' '9' ' ' 'z' '('
String Literals
'Hello, world!'
3
'Tutorials Point'
'19-NOV-12'
BOOLEAN Literals
4
TRUE, FALSE, and NULL.
To embed single quotes within a string literal, place two single quotes next
to each other as shown in the following program −
DECLARE
BEGIN
dbms_output.put_line(message);
END;
When the above code is executed at the SQL prompt, it produces the
following result −
That's tutorialspoint.com!
PL/SQL language is rich in built-in operators and provides the following types of operators −
Arithmetic operators
Relational operators
Comparison operators
Logical operators
String operators
Here, we will understand the arithmetic, relational, comparison and logical operators one by one. The
String operators will be discussed in a later chapter − PL/SQL - Strings.
Arithmetic Operators
Following table shows all the arithmetic operators supported by PL/SQL. Let
us assume variable A holds 10 and variable Bholds 5, then −
Show Examples
Operator Description Example
Relational Operators
Relational operators compare two expressions or values and return a
Boolean result. Following table shows all the relational operators supported
by PL/SQL. Let us assume variable A holds 10 and variable B holds 20,
then −
!=
Checks if the values of two operands are
<> (A != B) is
equal or not, if values are not equal then
true.
condition becomes true.
~=
Comparison Operators
Comparison operators are used for comparing one expression to another.
The result is always either TRUE, FALSE or NULL.
Show Examples
Operator Description Example
If x = 10 then, x
The BETWEEN operator tests between 5 and 20
whether a value lies in a returns true, x
BETWEEN specified range. x BETWEEN a between 5 and 10
AND b means that x >= a and returns true, but x
x <= b. between 11 and 20
returns false.
If x = 'm' then, x in
The IN operator tests set
('a', 'b', 'c') returns
membership. x IN (set)
IN Boolean false but x in
means that x is equal to any
('m', 'n', 'o') returns
member of set.
Boolean true.
Logical Operators
Following table shows the Logical operators supported by PL/SQL. All these
operators work on Boolean operands and produce Boolean results. Let us
assume variable A holds true and variable B holds false, then −
Show Examples
Operator Description Examples
** exponentiation
+, - identity, negation
*, / multiplication, division
AND conjunction
OR inclusion
Decision-making structures require that the programmer specify one or more conditions to be
evaluated or tested by the program, along with a statement or statements to be executed if the
condition is determined to be true, and optionally, other statements to be executed if the condition is
determined to be false.
Following is the general form of a typical conditional (i.e., decision making) structure found in most
of the programming languages –
1 IF - THEN statement
The IF statement associates a condition with a sequence
of statements enclosed by the keywords THEN and END
IF. If the condition is true, the statements get executed
and if the condition is false or NULL then the IF statement
does nothing.
IF-THEN-ELSE statement
IF-THEN-ELSIF statement
3
It allows you to choose between several alternatives.
Case statement
nested IF-THEN-ELSE
6
You can use one IF-THEN or IF-THEN-ELSIFstatement
inside another IF-THEN or IF-THEN-ELSIFstatement(s).
There may be a situation when you need to execute a block of code several number of times. In
general, statements are executed sequentially: The first statement in a function is executed first,
followed by the second, and so on.
Programming languages provide various control structures that allow for
more complicated execution paths.
A loop statement allows us to execute a statement or group of statements
multiple times and following is the general form of a loop statement in most
of the programming languages −
3
Execute a sequence of statements multiple times and
abbreviates the code that manages the loop variable.
4
You can use one or more loop inside any another basic
loop, while, or for loop.
i number(1);
j number(1);
BEGIN
END;
When the above code is executed at the SQL prompt, it produces the
following result −
i is: 1 and j is: 1
i is: 1 and j is: 2
i is: 1 and j is: 3
i is: 2 and j is: 1
i is: 2 and j is: 2
i is: 2 and j is: 3
i is: 3 and j is: 1
i is: 3 and j is: 2
i is: 3 and j is: 3
EXIT statement
1
The Exit statement completes the loop and control passes
to the statement immediately after the END LOOP.
CONTINUE statement
2
Causes the loop to skip the remainder of its body and
immediately retest its condition prior to reiterating.
GOTO statement
3
Transfers control to the labeled statement. Though it is not
advised to use the GOTO statement in your program.
To include a single quote inside a string literal, you need to type two single
quotes next to one another. For example,
'this isn''t what it looks like'
Declaring String Variables
Oracle database provides numerous string datatypes, such as CHAR,
NCHAR, VARCHAR2, NVARCHAR2, CLOB, and NCLOB. The datatypes
prefixed with an 'N' are 'national character set'datatypes, that store
Unicode character data.
If you need to declare a variable-length string, you must provide the
maximum length of that string. For example, the VARCHAR2 data type. The
following example illustrates declaring and using some string variables −
DECLARE
name varchar2(20);
company varchar2(30);
introduction clob;
choice char(1);
BEGIN
company := 'Infotech';
choice := 'y';
dbms_output.put_line(name);
dbms_output.put_line(company);
dbms_output.put_line(introduction);
END IF;
END;
When the above code is executed at the SQL prompt, it produces the
following result −
John Smith
Infotech Corporation
Hello! I'm John Smith from Infotech.
To declare a fixed-length string, use the CHAR datatype. Here you do not
have to specify a maximum length for a fixed-length variable. If you leave
off the length constraint, Oracle Database automatically uses a maximum
length required. The following two declarations are identical −
red_flag CHAR(1) := 'Y';
red_flag CHAR := 'Y';
ASCII(x);
1
Returns the ASCII value of the character x.
CHR(x);
2
Returns the character with the ASCII value of x.
CONCAT(x, y);
3
Concatenates the strings x and y and returns the
appended string.
INITCAP(x);
4
Converts the initial letter of each word in x to uppercase
and returns that string.
INSTRB(x);
6
Returns the location of a string within another string, but
returns the value in bytes.
LENGTH(x);
7
Returns the number of characters in x.
LENGTHB(x);
8
Returns the length of a character string in bytes for single
byte character set.
9 LOWER(x);
Converts the letters in x to lowercase and returns that
string.
LTRIM(x [, trim_string]);
11
Trims characters from the left of x.
NANVL(x, value);
12
Returns value if x matches the NaN special value (not a
number), otherwise x is returned.
NLS_INITCAP(x);
13
Same as the INITCAP function except that it can use a
different sort method as specified by NLSSORT.
NLS_LOWER(x) ;
14
Same as the LOWER function except that it can use a
different sort method as specified by NLSSORT.
NLS_UPPER(x);
15
Same as the UPPER function except that it can use a
different sort method as specified by NLSSORT.
NLSSORT(x);
NVL(x, value);
17
Returns value if x is null; otherwise, x is returned.
RTRIM(x [, trim_string]);
21
Trims x from the right.
SOUNDEX(x) ;
22
Returns a string containing the phonetic representation
of x.
SUBSTRB(x);
UPPER(x);
26
Converts the letters in x to uppercase and returns that
string.
Example 1
DECLARE
greetings varchar2(11) := 'hello world';
BEGIN
dbms_output.put_line(UPPER(greetings));
dbms_output.put_line(LOWER(greetings));
dbms_output.put_line(INITCAP(greetings));
END;
When the above code is executed at the SQL prompt, it produces the
following result −
HELLO WORLD
hello world
Hello World
h
d
World
ello World
2
BEGIN
dbms_output.put_line(RTRIM(greetings,'.'));
dbms_output.put_line(LTRIM(greetings, '.'));
END;
When the above code is executed at the SQL prompt, it produces the
following result −
......Hello World
Hello World.....
Hello World
Inside a package
Declarative Part
Executable Part
2
This is a mandatory part and contains statements that
perform the designated action.
Exception-handling
3
This is again an optional part. It contains the code that
handles run-time errors.
Creating a Procedure
A procedure is created with the CREATE OR REPLACE
PROCEDURE statement. The simplified syntax for the CREATE OR REPLACE
PROCEDURE statement is as follows −
CREATE [OR REPLACE] PROCEDURE procedure_name
{IS | AS}
BEGIN
END procedure_name;
Where,
procedure-name specifies the name of the procedure.
[OR REPLACE] option allows the modification of an existing procedure.
The optional parameter list contains name, mode and types of the parameters. IN represents the
value that will be passed from outside and OUT represents the parameter that will be used to
return a value outside of the procedure.
procedure-body contains the executable part.
The AS keyword is used instead of the IS keyword for creating a standalone procedure.
Example
The following example creates a simple procedure that displays the string
'Hello World!' on the screen when executed.
CREATE OR REPLACE PROCEDURE greetings
AS
BEGIN
dbms_output.put_line('Hello World!');
END;
When the above code is executed using the SQL prompt, it will produce the
following result −
Procedure created.
greetings;
END;
/
The above call will display −
Hello World
You can drop the greetings procedure by using the following statement −
DROP PROCEDURE greetings;
IN
OUT
3 IN OUT
a number;
b number;
c number;
BEGIN
IF x < y THEN
z:= x;
ELSE
z:= y;
END IF;
END;
BEGIN
a:= 23;
b:= 45;
findMin(a, b, c);
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Minimum of (23, 45) : 23
BEGIN
x := x * x;
END;
BEGIN
a:= 23;
squareNum(a);
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Square of (23): 529
Positional notation
Named notation
Mixed notation
Positional Notation
In positional notation, you can call the procedure as −
findMin(a, b, c, d);
In positional notation, the first actual parameter is substituted for the first
formal parameter; the second actual parameter is substituted for the
second formal parameter, and so on. So, a is substituted for x, b is
substituted for y, c is substituted for z and d is substituted for m.
Named Notation
In named notation, the actual parameter is associated with the formal
parameter using the arrow symbol ( => ). The procedure call will be like
the following −
findMin(x => a, y => b, z => c, m => d);
Mixed Notation
In mixed notation, you can mix both notations in procedure call; however,
the positional notation should precede the named notation.
The following call is legal −
findMin(a, b, c, m => d);
Creating a Function
A standalone function is created using the CREATE FUNCTIONstatement.
The simplified syntax for the CREATE OR REPLACE
PROCEDURE statement is as follows −
CREATE [OR REPLACE] FUNCTION function_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])]
RETURN return_datatype
{IS | AS}
BEGIN
< function_body >
END [function_name];
Where,
function-name specifies the name of the function.
[OR REPLACE] option allows the modification of an existing function.
The optional parameter list contains name, mode and types of the parameters. IN represents the
value that will be passed from outside and OUT represents the parameter that will be used to
return a value outside of the procedure.
The function must contain a return statement.
The RETURN clause specifies the data type you are going to return from the function.
function-body contains the executable part.
The AS keyword is used instead of the IS keyword for creating a standalone function.
Example
The following example illustrates how to create and call a standalone
function. This function returns the total number of CUSTOMERS in the
customers table.
We will use the CUSTOMERS table, which we had created in the PL/SQL
Variables chapter −
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
RETURN number IS
total number(2) := 0;
BEGIN
FROM customers;
RETURN total;
END;
When the above code is executed using the SQL prompt, it will produce the
following result −
Function created.
Calling a Function
While creating a function, you give a definition of what the function has to
do. To use a function, you will have to call that function to perform the
defined task. When a program calls a function, the program control is
transferred to the called function.
A called function performs the defined task and when its return statement is
executed or when the last end statement is reached, it returns the
program control back to the main program.
To call a function, you simply need to pass the required parameters along
with the function name and if the function returns a value, then you can
store the returned value. Following program calls the
function totalCustomers from an anonymous block −
DECLARE
c number(2);
BEGIN
c := totalCustomers();
END;
/
When the above code is executed at the SQL prompt, it produces the
following result −
Total no. of Customers: 6
Example
The following example demonstrates Declaring, Defining, and Invoking a
Simple PL/SQL Function that computes and returns the maximum of two
values.
DECLARE
a number;
b number;
c number;
RETURN number
IS
z number;
BEGIN
IF x > y THEN
z:= x;
ELSE
Z:= y;
END IF;
RETURN z;
END;
BEGIN
a:= 23;
b:= 45;
c := findMax(a, b);
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Maximum of (23,45): 45
num number;
factorial number;
RETURN number
IS
f number;
BEGIN
IF x=0 THEN
f := 1;
ELSE
f := x * fact(x-1);
END IF;
RETURN f;
END;
BEGIN
num:= 6;
factorial := fact(num);
END;
/
When the above code is executed at the SQL prompt, it produces the
following result −
Factorial 6 is 720
Oracle creates a memory area, known as the context area, for processing an SQL statement, which contains all the
information needed for processing the statement; for example, the number of rows processed, etc.
A cursor is a pointer to this context area. PL/SQL controls the context area through a cursor. A cursor holds the rows
(one or more) returned by a SQL statement. The set of rows the cursor holds is referred to as the active set.
You can name a cursor so that it could be referred to in a program to fetch and process the rows returned by the
SQL statement, one at a time. There are two types of cursors −
Implicit cursors
Explicit cursors
Implicit Cursors
Implicit cursors are automatically created by Oracle whenever an SQL statement is executed, when there is no
explicit cursor for the statement. Programmers cannot control the implicit cursors and the information in it.
Whenever a DML statement (INSERT, UPDATE and DELETE) is issued, an implicit cursor is associated with this
statement. For INSERT operations, the cursor holds the data that needs to be inserted. For UPDATE and DELETE
operations, the cursor identifies the rows that would be affected.
In PL/SQL, you can refer to the most recent implicit cursor as the SQL cursor, which always has attributes such
as %FOUND, %ISOPEN, %NOTFOUND, and %ROWCOUNT. The SQL cursor has additional
attributes, %BULK_ROWCOUNT and %BULK_EXCEPTIONS, designed for use with the FORALLstatement. The
following table provides the description of the most used attributes −
%FOUND
Returns TRUE if an INSERT, UPDATE, or
1
DELETE statement affected one or more rows or a
SELECT INTO statement returned one or more
rows. Otherwise, it returns FALSE.
2 %NOTFOUND
The logical opposite of %FOUND. It returns TRUE
if an INSERT, UPDATE, or DELETE statement
affected no rows, or a SELECT INTO statement
returned no rows. Otherwise, it returns FALSE.
%ISOPEN
3 Always returns FALSE for implicit cursors, because
Oracle closes the SQL cursor automatically after
executing its associated SQL statement.
%ROWCOUNT
4 Returns the number of rows affected by an INSERT,
UPDATE, or DELETE statement, or returned by a
SELECT INTO statement.
Any SQL cursor attribute will be accessed as sql%attribute_name as shown below in the example.
Example
We will be using the CUSTOMERS table we had created and used in the previous chapters.
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
The following program will update the table and increase the salary of each customer by 500 and use the SQL
%ROWCOUNTattribute to determine the number of rows affected −
DECLARE
total_rows number(2);
BEGIN
UPDATE customers
IF sql%notfound THEN
total_rows := sql%rowcount;
END IF;
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
6 customers selected
If you check the records in customers table, you will find that the rows have been updated −
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2500.00 |
| 2 | Khilan | 25 | Delhi | 2000.00 |
| 3 | kaushik | 23 | Kota | 2500.00 |
| 4 | Chaitali | 25 | Mumbai | 7000.00 |
| 5 | Hardik | 27 | Bhopal | 9000.00 |
| 6 | Komal | 22 | MP | 5000.00 |
+----+----------+-----+-----------+----------+
Explicit Cursors
Explicit cursors are programmer-defined cursors for gaining more control over the context area. An explicit cursor
should be defined in the declaration section of the PL/SQL Block. It is created on a SELECT Statement which returns
more than one row.
CURSOR c_customers IS
OPEN c_customers;
CLOSE c_customers;
Example
Following is a complete example to illustrate the concepts of explicit cursors &minua;
DECLARE
c_id customers.id%type;
c_name customerS.No.ame%type;
c_addr customers.address%type;
CURSOR c_customers is
BEGIN
OPEN c_customers;
LOOP
END LOOP;
CLOSE c_customers;
END;
When the above code is executed at the SQL prompt, it produces the following result −
1 Ramesh Ahmedabad
2 Khilan Delhi
3 kaushik Kota
4 Chaitali Mumbai
5 Hardik Bhopal
6 Komal MP
A record is a data structure that can hold data items of different kinds.
Records consist of different fields, similar to a row of a database table.
For example, you want to keep track of your books in a library. You might
want to track the following attributes about each book, such as Title,
Author, Subject, Book ID. A record containing a field for each of these items
allows treating a BOOK as a logical unit and allows you to organize and
represent its information in a better way.
PL/SQL can handle the following types of records −
Table-based
Cursor-based records
User-defined records
Table-Based Records
The %ROWTYPE attribute enables a programmer to create table-
based and cursorbased records.
The following example illustrates the concept of table-basedrecords. We
will be using the CUSTOMERS table we had created and used in the
previous chapters −
DECLARE
customer_rec customers%rowtype;
BEGIN
FROM customers
WHERE id = 5;
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Customer ID: 5
Customer Name: Hardik
Customer Address: Bhopal
Customer Salary: 9000
Cursor-Based Records
The following example illustrates the concept of cursor-basedrecords. We
will be using the CUSTOMERS table we had created and used in the
previous chapters −
DECLARE
CURSOR customer_cur is
FROM customers;
customer_rec customer_cur%rowtype;
BEGIN
OPEN customer_cur;
LOOP
END LOOP;
END;
When the above code is executed at the SQL prompt, it produces the
following result −
1 Ramesh
2 Khilan
3 kaushik
4 Chaitali
5 Hardik
6 Komal
User-Defined Records
PL/SQL provides a user-defined record type that allows you to define the
different record structures. These records consist of different fields.
Suppose you want to keep track of your books in a library. You might want
to track the following attributes about each book −
Title
Author
Subject
Book ID
Defining a Record
The record type is defined as −
TYPE
type_name IS RECORD
( field_name1 datatype1 [NOT NULL] [:= DEFAULT EXPRESSION],
field_name2 datatype2 [NOT NULL] [:= DEFAULT EXPRESSION],
...
field_nameN datatypeN [NOT NULL] [:= DEFAULT EXPRESSION);
record-name type_name;
(title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
book1 books;
book2 books;
Accessing Fields
To access any field of a record, we use the dot (.) operator. The member
access operator is coded as a period between the record variable name and
the field that we wish to access. Following is an example to explain the
usage of record −
DECLARE
(title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
book1 books;
book2 books;
BEGIN
-- Book 1 specification
book1.book_id := 6495407;
-- Book 2 specification
book2.book_id := 6495700;
-- Print book 1 record
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
(title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
book1 books;
book2 books;
END;
BEGIN
-- Book 1 specification
book1.book_id := 6495407;
-- Book 2 specification
book2.book_id := 6495700;
printbook(book1);
printbook(book2);
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700
System-defined exceptions
User-defined exceptions
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
exception1-handling-statements
exception2-handling-statements
exception3-handling-statements
........
exception3-handling-statements
END;
Example
Let us write a code to illustrate the concept. We will be using the
CUSTOMERS table we had created and used in the previous chapters −
DECLARE
c_id customers.id%type := 8;
c_name customerS.Name%type;
c_addr customers.address%type;
BEGIN
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
EXCEPTION
dbms_output.put_line('Error!');
END;
When the above code is executed at the SQL prompt, it produces the
following result −
No such customer!
The above program displays the name and address of a customer whose ID
is given. Since there is no customer with ID value 8 in our database, the
program raises the run-time exception NO_DATA_FOUND, which is
captured in the EXCEPTION block.
Raising Exceptions
Exceptions are raised by the database server automatically whenever there
is any internal database error, but exceptions can be raised explicitly by the
programmer by using the command RAISE. Following is the simple syntax
for raising an exception −
DECLARE
exception_name EXCEPTION;
BEGIN
IF condition THEN
RAISE exception_name;
END IF;
EXCEPTION
statement;
END;
You can use the above syntax in raising the Oracle standard exception or
any user-defined exception. In the next section, we will give you an
example on raising a user-defined exception. You can raise the Oracle
standard exceptions in a similar way.
User-defined Exceptions
PL/SQL allows you to define your own exceptions according to the need of
your program. A user-defined exception must be declared and then raised
explicitly, using either a RAISE statement or the
procedure DBMS_STANDARD.RAISE_APPLICATION_ERROR.
The syntax for declaring an exception is −
DECLARE
my-exception EXCEPTION;
Example
The following example illustrates the concept. This program asks for a
customer ID, when the user enters an invalid ID, the
exception invalid_id is raised.
DECLARE
c_name customerS.Name%type;
c_addr customers.address%type;
ex_invalid_id EXCEPTION;
BEGIN
RAISE ex_invalid_id;
ELSE
FROM customers
WHERE id = c_id;
END IF;
EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('Error!');
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Enter value for cc_id: -6 (let's enter a value -6)
old 2: c_id customers.id%type := &cc_id;
new 2: c_id customers.id%type := -6;
ID must be greater than zero!
Pre-defined Exceptions
PL/SQL provides many pre-defined exceptions, which are executed when
any database rule is violated by a program. For example, the predefined
exception NO_DATA_FOUND is raised when a SELECT INTO statement
returns no rows. The following table lists few of the important pre-defined
exceptions −
Oracle
Exception SQLCODE Description
Error
It is raised when a
null object is
ACCESS_INTO_NULL 06530 -6530
automatically
assigned a value.
It is raised when
none of the choices
in the WHEN clause
CASE_NOT_FOUND 06592 -6592 of a CASE
statement is
selected, and there
is no ELSE clause.
It is raised when
duplicate values are
DUP_VAL_ON_INDEX 00001 -1 attempted to be
stored in a column
with unique index.
It is raised when
attempts are made
to make a cursor
INVALID_CURSOR 01001 -1001 operation that is not
allowed, such as
closing an unopened
cursor.
It is raised when a
program attempts
to log on to the
LOGIN_DENIED 01017 -1017
database with an
invalid username or
password.
It is raised when a
SELECT INTO
NO_DATA_FOUND 01403 +100
statement returns
no rows.
It is raised when a
database call is
NOT_LOGGED_ON 01012 -1012 issued without being
connected to the
database.
It is raised when
PROGRAM_ERROR 06501 -6501 PL/SQL has an
internal problem.
It is raised when a
cursor fetches value
ROWTYPE_MISMATCH 06504 -6504 in a variable having
incompatible data
type.
It is raised when a
member method is
invoked, but the
SELF_IS_NULL 30625 -30625
instance of the
object type was not
initialized.
It is raised when
PL/SQL ran out of
STORAGE_ERROR 06500 -6500
memory or memory
was corrupted.
It is raised when a
SELECT INTO
TOO_MANY_ROWS 01422 -1422
statement returns
more than one row.
It is raised when an
arithmetic,
conversion,
VALUE_ERROR 06502 -6502
truncation, or
sizeconstraint error
occurs.
It is raised when an
attempt is made to
ZERO_DIVIDE 01476 1476
divide a number by
zero.
Triggers are stored programs, which are automatically executed or fired when some events occur.
Triggers are, in fact, written to be executed in response to any of the following events –
Triggers can be defined on the table, view, schema, or database with which the event is associated.
Benefits of Triggers
Triggers can be written for the following purposes −
Auditing
Creating Triggers
The syntax for creating a trigger is −
[OF col_name]
ON table_name
WHEN (condition)
DECLARE
Declaration-statements
BEGIN
Executable-statements
EXCEPTION
Exception-handling-statements
END;
Where,
CREATE [OR REPLACE] TRIGGER trigger_name − Creates or replaces an existing trigger with the trigger_name.
{BEFORE | AFTER | INSTEAD OF} − This specifies when the trigger will be executed. The INSTEAD OF clause is
used for creating trigger on a view.
{INSERT [OR] | UPDATE [OR] | DELETE} − This specifies the DML operation.
[OF col_name] − This specifies the column name that will be updated.
[ON table_name] − This specifies the name of the table associated with the trigger.
[REFERENCING OLD AS o NEW AS n] − This allows you to refer new and old values for various DML
statements, such as INSERT, UPDATE, and DELETE.
[FOR EACH ROW] − This specifies a row-level trigger, i.e., the trigger will be executed for each row being
affected. Otherwise the trigger will execute just once when the SQL statement is executed, which is called a
table level trigger.
WHEN (condition) − This provides a condition for rows for which the trigger would fire. This clause is valid
only for row-level triggers.
Example
To start with, we will be using the CUSTOMERS table we had created and used in the previous chapters −
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
The following program creates a row-level trigger for the customers table that would fire for INSERT or UPDATE or
DELETE operations performed on the CUSTOMERS table. This trigger will display the salary difference between the
old values and new values −
DECLARE
sal_diff number;
BEGIN
END;
When the above code is executed at the SQL prompt, it produces the following result −
Trigger created.
OLD and NEW references are not available for table-level triggers, rather you can use them for record-level
triggers.
If you want to query the table in the same trigger, then you should use the AFTER keyword, because triggers
can query the table or change it again only after the initial changes are applied and the table is back in a
consistent state.
The above trigger has been written in such a way that it will fire before any DELETE or INSERT or UPDATE
operation on the table, but you can write your trigger on a single or multiple operations, for example
BEFORE DELETE, which will fire whenever a record will be deleted using the DELETE operation on the table.
Triggering a Trigger
Let us perform some DML operations on the CUSTOMERS table. Here is one INSERT statement, which will create a
new record in the table −
When a record is created in the CUSTOMERS table, the above create trigger, display_salary_changes will be fired
and it will display the following result −
Old salary:
New salary: 7500
Salary difference:
Because this is a new record, old salary is not available and the above result comes as null. Let us now perform one
more DML operation on the CUSTOMERS table. The UPDATE statement will update an existing record in the table −
UPDATE customers
WHERE id = 2;
When a record is updated in the CUSTOMERS table, the above create trigger, display_salary_changes will be fired
and it will display the following result −
Packages are schema objects that groups logically related PL/SQL types,
variables, and subprograms.
A package will have two mandatory parts −
Package specification
Package Specification
The specification is the interface to the package. It just DECLARES the
types, variables, constants, exceptions, cursors, and subprograms that can
be referenced from outside the package. In other words, it contains all
information about the content of the package, but excludes the code for the
subprograms.
All objects placed in the specification are called public objects. Any
subprogram not in the package specification but coded in the package body
is called a private object.
The following code snippet shows a package specification having a single
procedure. You can have many global variables defined and multiple
procedures or functions inside a package.
CREATE PACKAGE cust_sal AS
END cust_sal;
When the above code is executed at the SQL prompt, it produces the
following result −
Package created.
Package Body
The package body has the codes for various methods declared in the
package specification and other private declarations, which are hidden from
the code outside the package.
The CREATE PACKAGE BODY Statement is used for creating the package
body. The following code snippet shows the package body declaration for
the cust_sal package created above. I assumed that we already have
CUSTOMERS table created in our database as mentioned in the PL/SQL -
Variables chapter.
CREATE OR REPLACE PACKAGE BODY cust_sal AS
c_sal customers.salary%TYPE;
BEGIN
FROM customers
WHERE id = c_id;
END find_sal;
END cust_sal;
/
When the above code is executed at the SQL prompt, it produces the
following result −
Package body created.
BEGIN
cust_sal.find_sal(code);
END;
When the above code is executed at the SQL prompt, it prompts to enter
the customer ID and when you enter an ID, it displays the corresponding
salary as follows −
Enter value for cc_id: 1
Salary: 3000
Example
The following program provides a more complete package. We will use the
CUSTOMERS table stored in our database with the following records −
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 3000.00 |
| 2 | Khilan | 25 | Delhi | 3000.00 |
| 3 | kaushik | 23 | Kota | 3000.00 |
| 4 | Chaitali | 25 | Mumbai | 7500.00 |
| 5 | Hardik | 27 | Bhopal | 9500.00 |
| 6 | Komal | 22 | MP | 5500.00 |
+----+----------+-----+-----------+----------+
-- Adds a customer
PROCEDURE addCustomer(c_id customers.id%type,
c_name customerS.No.ame%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type);
-- Removes a customer
PROCEDURE listCustomer;
END c_package;
When the above code is executed at the SQL prompt, it creates the above
package and displays the following result −
Package created.
c_name customerS.No.ame%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type)
IS
BEGIN
END addCustomer;
BEGIN
WHERE id = c_id;
END delCustomer;
PROCEDURE listCustomer IS
CURSOR c_customers is
BEGIN
name_list.extend;
name_list(counter) := n.name;
END LOOP;
END listCustomer;
END c_package;
The above example makes use of the nested table. We will discuss the
concept of nested table in the next chapter.
When the above code is executed at the SQL prompt, it produces the
following result −
Package body created.
code customers.id%type:= 8;
BEGIN
c_package.listcustomer;
c_package.delcustomer(code);
c_package.listcustomer;
END;
When the above code is executed at the SQL prompt, it produces the
following result −
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish
Customer(8): Subham
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish
A collection is an ordered group of elements having the same data type. Each element is identified by
a unique subscript that represents its position in the collection.
Nested table
Oracle documentation provides the following characteristics for each type of collections −
Can Be
Dense Where
Collection Number of Subscrip Object
or Create
Type Elements t Type Type
Sparse d
Attribute
Associative
Only in
array (or Unbounde String or
Either PL/SQL No
index-by d integer
block
table)
Either
in
Variablesiz PL/SQL
Always
e array Bounded Integer block Yes
dense
(Varray) or at
schema
level
We have already discussed varray in the chapter 'PL/SQL arrays'. In this chapter, we will discuss the PL/SQL tables.
Both types of PL/SQL tables, i.e., the index-by tables and the nested tables have the same structure and their rows are accessed using
the subscript notation. However, these two types of tables differ in one aspect; the nested tables can be stored in a database column and
the index-by tables cannot.
Index-By Table
An index-by table (also called an associative array) is a set of key-value pairs. Each key is unique and is used to locate the
corresponding value. The key can be either an integer or a string.
An index-by table is created using the following syntax. Here, we are creating an index-by table named table_name, the keys of which
will be of the subscript_type and associated values will be of the element_type
table_name type_name;
Example
Following example shows how to create a table to store integer values along with names and later it prints the same list of names.
DECLARE
salary_list salary;
name VARCHAR2(20);
BEGIN
salary_list('Rajnish') := 62000;
salary_list('Minakshi') := 75000;
salary_list('Martin') := 100000;
salary_list('James') := 78000;
-- printing the table
name := salary_list.FIRST;
dbms_output.put_line
name := salary_list.NEXT(name);
END LOOP;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Example
Elements of an index-by table could also be a %ROWTYPE of any database table or %TYPE of any database table field. The
following example illustrates the concept. We will use the CUSTOMERS table stored in our database as −
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
DECLARE
CURSOR c_customers is
name_list c_list;
BEGIN
name_list(counter) := n.name;
dbms_output.put_line('Customer('||counter||'):'||name_lis t(counter));
END LOOP;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Nested Tables
A nested table is like a one-dimensional array with an arbitrary number of elements. However, a nested table differs from an array in
the following aspects −
An array has a declared number of elements, but a nested table does not. The size of a nested table can increase dynamically.
An array is always dense, i.e., it always has consecutive subscripts. A nested array is dense initially, but it can become sparse
when elements are deleted from it.
table_name type_name;
This declaration is similar to the declaration of an index-bytable, but there is no INDEX BY clause.
A nested table can be stored in a database column. It can further be used for simplifying SQL operations where you join a single-
column table with a larger table. An associative array cannot be stored in the database.
Example
The following examples illustrate the use of nested table −
DECLARE
names names_table;
marks grades;
total integer;
BEGIN
total := names.count;
end loop;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Total 5 Students
Student:Kavita, Marks:98
Student:Pritam, Marks:97
Student:Ayan, Marks:78
Student:Rishav, Marks:87
Student:Aziz, Marks:92
Example
Elements of a nested table can also be a %ROWTYPE of any database table or %TYPE of any database table field. The following
example illustrates the concept. We will use the CUSTOMERS table stored in our database as −
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
DECLARE
CURSOR c_customers is
BEGIN
name_list.extend;
name_list(counter) := n.name;
dbms_output.put_line('Customer('||counter||'):'||name_list(counter));
END LOOP;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Collection Methods
PL/SQL provides the built-in collection methods that make collections easier to use. The following table lists the methods and their
purpose −
EXISTS(n)
1
Returns TRUE if the nth element in a collection
exists; otherwise returns FALSE.
COUNT
2
Returns the number of elements that a collection
currently contains.
LIMIT
3
Checks the maximum size of a collection.
FIRST
4
Returns the first (smallest) index numbers in a
collection that uses the integer subscripts.
LAST
5
Returns the last (largest) index numbers in a
collection that uses the integer subscripts.
PRIOR(n)
6
Returns the index number that precedes index n in a
collection.
NEXT(n)
7
Returns the index number that succeeds index n.
8 EXTEND
Appends one null element to a collection.
EXTEND(n)
9
Appends n null elements to a collection.
EXTEND(n,i)
10
Appends n copies of the ith element to a collection.
TRIM
11
Removes one element from the end of a collection.
TRIM(n)
12
Removes n elements from the end of a collection.
DELETE
13
Removes all elements from a collection, setting
COUNT to 0.
DELETE(n)
Removes the nth element from an associative array
14 with a numeric key or a nested table. If the
associative array has a string key, the element
corresponding to the key value is deleted. If n is
null, DELETE(n) does nothing.
DELETE(m,n)
Removes all elements in the range m..n from an
15
associative array or nested table. If m is larger
than nor if m or n is null, DELETE(m,n) does
nothing.
Collection Exceptions
The following table provides the collection exceptions and when they are raised −
A subscript designates an
element that was deleted, or a
NO_DATA_FOUND
nonexistent element of an
associative array.
A database transaction is an atomic unit of work that may consist of one or more related SQL
statements. It is called atomic because the database modifications brought about by the SQL
statements that constitute a transaction can collectively be either committed, i.e., made
permanent to the database or rolled back (undone) from the database.
A successfully executed SQL statement and a committed transaction are not same. Even if an
SQL statement is executed successfully, unless the transaction containing the statement is
committed, it can be rolled back and all changes made by the statement(s) can be undone.
Committing a Transaction
A transaction is made permanent by issuing the SQL command COMMIT. The general syntax
for the COMMIT command is −
COMMIT;
For example,
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
COMMIT;
When a transaction is aborted due to some unprecedented situation, like system failure, the
entire transaction since a commit is automatically rolled back. If you are not using savepoint,
then simply use the following statement to rollback all the changes −
ROLLBACK;
Savepoints
Savepoints are sort of markers that help in splitting a long transaction into smaller units by
setting some checkpoints. By setting savepoints within a long transaction, you can roll back to a
checkpoint if required. This is done by issuing the SAVEPOINTcommand.
The general syntax for the SAVEPOINT command is −
SAVEPOINT < savepoint_name >;
For example
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
SAVEPOINT sav1;
UPDATE CUSTOMERS
ROLLBACK TO sav1;
UPDATE CUSTOMERS
WHERE ID = 7;
UPDATE CUSTOMERS
WHERE ID = 8;
COMMIT;
ROLLBACK TO sav1 − This statement rolls back all the changes up to the point, where you
had marked savepoint sav1.
After that, the new changes that you make will start.
Automatic Transaction Control
To execute a COMMIT automatically whenever
an INSERT,UPDATE or DELETE command is executed, you can set
the AUTOCOMMIT environment variable as −
SET AUTOCOMMIT ON;
You can turn-off the auto commit mode using the following command −
SET AUTOCOMMIT OFF;
There are two classes of date and time related data types in PL/SQL −
DATE
TIMESTAMP
MONTH 01 to 12 0 to 11
HOUR 00 to 23 0 to 23
MINUTE 00 to 59 0 to 59
-12 to 14 (range
accommodates daylight
TIMEZONE_HOUR savings time changes) Not applicable
00 to 59
TIMEZONE_MINUTE Not applicable
Not applicable for DATE
or TIMESTAMP.
DATE
It stores date and time information in both character and number
datatypes. It is made of information on century, year, month, date, hour,
minute, and second. It is specified as −
TIMESTAMP
It is an extension of the DATE data type. It stores the year, month, and day
of the DATE datatype, along with hour, minute, and second values. It is
useful for storing precise time values.
TIMESTAMP WITH TIME ZONE
It is a variant of TIMESTAMP that includes a time zone region name or a
time zone offset in its value. The time zone offset is the difference (in hours
and minutes) between local time and UTC. This data type is useful for
collecting and evaluating date information across geographic regions.
ADD_MONTHS(x, y);
1
Adds y months to x.
LAST_DAY(x);
2
Returns the last day of the month.
MONTHS_BETWEEN(x, y);
3
Returns the number of months between x and y.
NEXT_DAY(x, day);
4
Returns the datetime of the next day after x.
NEW_TIME;
5
Returns the time/day value from a time zone specified by
the user.
ROUND(x [, unit]);
6
Rounds x.
SYSDATE();
7
Returns the current datetime.
8 TRUNC(x [, unit]);
Truncates x.
CURRENT_TIMESTAMP();
1
Returns a TIMESTAMP WITH TIME ZONE containing the
current session time along with the session time zone.
FROM_TZ(x, time_zone);
3
Converts the TIMESTAMP x and the time zone specified by
time_zone to a TIMESTAMP WITH TIMEZONE.
LOCALTIMESTAMP();
4
Returns a TIMESTAMP containing the local time in the
session time zone.
SYSTIMESTAMP();
5
Returns a TIMESTAMP WITH TIME ZONE containing the
current database time along with the database time zone.
SYS_EXTRACT_UTC(x);
6
Converts the TIMESTAMP WITH TIMEZONE x to a
TIMESTAMP containing the date and time in UTC.
TO_TIMESTAMP(x, [format]);
7
Converts the string x to a TIMESTAMP.
TO_TIMESTAMP_TZ(x, [format]);
8
Converts the string x to a TIMESTAMP WITH TIMEZONE.
Examples
The following code snippets illustrate the use of the above functions −
Example 1
SELECT SYSDATE FROM DUAL;
Output −
08/31/2012 5:25:34 PM
Example 2
SELECT TO_CHAR(CURRENT_DATE, 'DD-MM-YYYY HH:MI:SS') FROM DUAL;
Output −
31-08-2012 05:26:14
Example 3
SELECT ADD_MONTHS(SYSDATE, 5) FROM DUAL;
Output −
01/31/2013 5:26:31 PM
Example 4
SELECT LOCALTIMESTAMP FROM DUAL;
Output −
8/31/2012 5:26:55.347000 PM
Interval Functions
S.No Function Name & Description
NUMTODSINTERVAL(x, interval_unit);
1
Converts the number x to an INTERVAL DAY TO SECOND.
2 NUMTOYMINTERVAL(x, interval_unit);
Converts the number x to an INTERVAL YEAR TO MONTH.
TO_DSINTERVAL(x);
3
Converts the string x to an INTERVAL DAY TO SECOND.
TO_YMINTERVAL(x);
4
Converts the string x to an INTERVAL YEAR TO MONTH.
LOOP
dbms_output.put_line(t.table_name);
END LOOP;
END;
DBMS_OUTPUT Subprograms
The DBMS_OUTPUT package has the following subprograms −
DBMS_OUTPUT.DISABLE;
1
Disables message output.
2 DBMS_OUTPUT.ENABLE(buffer_size IN
INTEGER DEFAULT 20000);
Enables message output. A NULL value
of buffer_size represents unlimited buffer size.
DBMS_OUTPUT.NEW_LINE;
5
Puts an end-of-line marker.
DBMS_OUTPUT.PUT(item IN VARCHAR2);
6
Places a partial line in the buffer.
DBMS_OUTPUT.PUT_LINE(item IN
7 VARCHAR2);
Places a line in the buffer.
Example
DECLARE
lines dbms_output.chararr;
num_lines number;
BEGIN
dbms_output.enable;
dbms_output.put_line('Hello Reader!');
num_lines := 3;
dbms_output.get_lines(lines, num_lines);
FOR i IN 1..num_lines LOOP
dbms_output.put_line(lines(i));
END LOOP;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Hello Reader!
Hope you have enjoyed the tutorials!
Have a great time exploring pl/sql!
PL/SQL PL/SQL allows defining an object type, which helps in designing object-oriented database in Oracle. An object
type allows you to create composite types. Using objects allow you to implement real world objects with specific
structure of data and methods for operating it. Objects have attributes and methods. Attributes are properties of an
object and are used for storing an object's state; and methods are used for modeling its behavior.
Objects are created using the CREATE [OR REPLACE] TYPE statement. Following is an example to create a
simple addressobject consisting of few attributes −
(house_no varchar2(10),
street varchar2(30),
city varchar2(20),
state varchar2(10),
pincode varchar2(10)
);
When the above code is executed at the SQL prompt, it produces the following result −
Type created.
(code number(5),
name varchar2(30),
contact_no varchar2(12),
addr address,
When the above code is executed at the SQL prompt, it produces the following result −
Type created.
Instantiating an Object
Defining an object type provides a blueprint for the object. To use this object, you need to create instances of this
object. You can access the attributes and methods of the object using the instance name and the access operator
(.) as follows −
DECLARE
residence address;
BEGIN
END;
When the above code is executed at the SQL prompt, it produces the following result −
Member Methods
Member methods are used for manipulating the attributes of the object. You provide the declaration of a member
method while declaring the object type. The object body defines the code for the member methods. The object body
is created using the CREATE TYPE BODY statement.
Constructors are functions that return a new object as its value. Every object has a system defined constructor
method. The name of the constructor is same as the object type. For example −
The comparison methods are used for comparing objects. There are two ways to compare objects −
Map method
The Map method is a function implemented in such a way that its value depends upon the value of the attributes.
For example, for a customer object, if the customer code is same for two customers, both customers could be the
same. So the relationship between these two objects would depend upon the value of code.
Order method
The Order method implements some internal logic for comparing two objects. For example, for a rectangle object, a
rectangle is bigger than another rectangle if both its sides are bigger.
(length number,
width number,
);
When the above code is executed at the SQL prompt, it produces the following result −
Type created.
BEGIN
END enlarge;
BEGIN
END display;
BEGIN
END measure;
END;
When the above code is executed at the SQL prompt, it produces the following result −
DECLARE
r1 rectangle;
r2 rectangle;
r3 rectangle;
inc_factor number := 5;
BEGIN
r1 := rectangle(3, 4);
r2 := rectangle(5, 7);
r3 := r1.enlarge(inc_factor);
r3.display;
r1.display;
ELSE
r2.display;
END IF;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Length: 8
Width: 9
Length: 5
Width: 7
(length number,
width number,
);
When the above code is executed at the SQL prompt, it produces the following result −
Type created.
BEGIN
END display;
BEGIN
IF(sqrt(self.length*self.length + self.width*self.width)>
return(1);
ELSE
return(-1);
END IF;
END measure;
END;
When the above code is executed at the SQL prompt, it produces the following result −
DECLARE
r1 rectangle;
r2 rectangle;
BEGIN
r1 := rectangle(23, 44);
r2 := rectangle(15, 17);
r1.display;
r2.display;
IF (r1 > r2) THEN -- calling measure function
r1.display;
ELSE
r2.display;
END IF;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Length: 23
Width: 44
Length: 15
Width: 17
Length: 23
Width: 44
The following programs illustrate the inheritance in PL/SQL Objects. Let us create another object named TableTop,
this is inherited from the Rectangle object. For this, we need to create the base rectangle object −
(length number,
width number,
When the above code is executed at the SQL prompt, it produces the following result −
Type created.
BEGIN
return rectangle(self.length + inc, self.width + inc);
END enlarge;
BEGIN
END display;
END;
When the above code is executed at the SQL prompt, it produces the following result −
material varchar2(20),
When the above code is executed at the SQL prompt, it produces the following result −
Type created.
BEGIN
END display;
When the above code is executed at the SQL prompt, it produces the following result −
DECLARE
t1 tabletop;
t2 tabletop;
BEGIN
t1.display;
t2.display;
END;
When the above code is executed at the SQL prompt, it produces the following result −
Length: 20
Width: 10
Material: Wood
Length: 50
Width: 30
Material: Steel
For example,
(length number,
width number,