Académique Documents
Professionnel Documents
Culture Documents
Programming
V1.0
Oracle10g PL/SQL Programming
Legal Notice
Copyrights
Copyright © 2006 SkillBuilders, Inc. All rights reserved. Printed in the United States of
America.
No part of this publication may be reproduced, distributed or displayed in any form or by any
means, or stored in a database, retrieval system or other media without the prior written
permission of SkillBuilders, Inc.
Trademarks
The product/service names mentioned herein are manufacturer/publisher trademarks and are used
only for purposes of identification.
Microsoft, Microsoft Windows 95, Microsoft Windows 98, Microsoft Windows NT, and
Microsoft Windows XP are registered trademarks of Microsoft Corporation. Netscape, Netscape
Navigator, and the Netscape logo are registered trademarks of Netscape Communications
Corporation in the United States and other countries. Oracle, Oracle8i, Oracle9i and Oracle10g
are registered trademarks of Oracle Corporation.
All other brand, product and service names are the trademarks of their respective companies or
owners as mentioned herein.
Disclaimer
Information within this publication is subject to change without notice. Although every
precaution has been taken in the preparation of this book, the publisher and author assume no
responsibility for errors or omissions. The author and SkillBuilders, Inc. make no representation
or warranty with respect to the contents herein and specifically disclaims any implied warranties
of fitness for any particular purpose. SkillBuilders, Inc. disclaims all liability for any direct,
indirect, incidental or consequential, special or exemplary damages resulting from the use of the
information in this document or from the use of any products described in this document.
3 days
Description This class will teach you how to write efficient and scalable PL/SQL programs to
create database-intensive PL/SQL applications. You will learn the critical and
fundamental aspects of PL/SQL language.
Hands-on workshops constitute approximately 50% of the class. As with all of our
courses, this class is highly customizable to your specific training requirements.
Prerequisites You must possess strong programming skills to benefit from this class. (We will not
teach you the basics of programming such as logic flow and conditional logic. We
will, however, teach you how to do it efficiently in PL/SQL.) Experience with a
procedural language (e.g. Java, C or COBOL), SQL and SQL*Plus is required.
Next Courses Advanced PL/SQL Programming, Advanced Queries for Oracle10g Databases,
Oracle10g SQL Tuning for Developers and DBA’s, Oracle10g Database
Administration
Objectives After successfully completing this course, you will be able to:
• Code efficient, scalable PL/SQL programs that include common programming
constructs such as data-typing, variable assignment, flow control, cursor
handling, bulk processing, array processing and error handling
• Create PL/SQL stored procedures that accept and return values or sets of values
• Manage stored procedure dependencies and privileges
• Create PL/SQL functions, including powerful table functions and pipelined table
functions
• Create database triggers for auditing, complex business rule support, simple
replication and more
• Create and maintain simple Oracle packages
• Use the UTL_FILE package to read and write to operating system files.
• Use the UTL_MAIL package to send email from an Oracle database
• Use the DBMS_PROFILER package to profile and tune PL/SQL programs
• Do simple benchmarking of PL/SQL code with the DBMS_UTITLITY package
Bulk DELETE.............................................................................................................5.11
Bulk INSERT..............................................................................................................5.13
10g FORALL Improvements…..................................................................................5.14
Returning into Arrays .................................................................................................5.17
Summary.....................................................................................................................5.18
Bulk Processing Workshop B .....................................................................................5.19
7. Functions..................................................................................................... 7.1
Lesson Objectives .........................................................................................................7.2
What is a Function? ......................................................................................................7.3
Abbreviated Syntax.......................................................................................................7.4
Simple Example............................................................................................................7.5
Calling Functions..........................................................................................................7.6
The Data Dictionary......................................................................................................7.7
Functions Workshop A .................................................................................................7.8
Table Functions.............................................................................................................7.9
Building a Table Function ..........................................................................................7.10
Using a Table Function...............................................................................................7.12
Pipelined Functions.....................................................................................................7.14
Pipelined Example ......................................................................................................7.15
Test Data Generator ....................................................................................................7.16
Functions Workshop B ...............................................................................................7.19
9. Packages .....................................................................................................9.1
Lesson Objectives .........................................................................................................9.2
Concepts........................................................................................................................9.3
Package Benefits...........................................................................................................9.4
Package Benefits Diagram............................................................................................9.5
Package Contents..........................................................................................................9.6
Package Specification Syntax.......................................................................................9.7
Package Specification Example....................................................................................9.8
Package Body Syntax ...................................................................................................9.9
Package Body Example ..............................................................................................9.10
Privileges ....................................................................................................................9.11
Calling Packaged Objects ...........................................................................................9.12
Initialization Code.......................................................................................................9.13
Session Variables........................................................................................................9.14
Package Body Variables .............................................................................................9.15
Packages Workshop A ................................................................................................9.16
Package Overloading ..................................................................................................9.17
Overloading Example .................................................................................................9.18
Packages Workshop B ................................................................................................9.19
Compiling Packages ...................................................................................................9.20
DROP Package ...........................................................................................................9.21
Packages Workshop C ................................................................................................9.22
Supplied Packages ......................................................................................................9.23
Summary.....................................................................................................................9.24
Setup ...........................................................................................................................12.4
DBMS_JOB.SUBMIT................................................................................................12.5
SUBMIT Example ......................................................................................................12.6
Running a Job .............................................................................................................12.7
Cleaning Up Broken Jobs ...........................................................................................12.8
Removing a Job ..........................................................................................................12.9
Changing Job Parameters..........................................................................................12.10
Viewing Job Information ..........................................................................................12.11
Using DBMS_JOB Workshop..................................................................................12.12
Lesson 1
Introduction to PL/SQL
A programmer’s introduction to the
what, why, when and where of
PL/SQL.
1.2
Lesson Objectives
¾ What is PL/SQL?
¾ What is it good for?
¾ Basic structure of a PL/SQL program
¾ Simple examples of common PL/SQL objects
¾ Anonymous block
¾ Procedure
¾ Function In-depth lessons
dedicated to these
¾ Package subjects later in this
¾ Trigger course…
1.3
What is PL/SQL?
¾ PL/SQL = Procedural Language extensions for SQL
¾ Proprietary language for Oracle database
¾ 3rd generation procedural language
¾ variable definition, assignment
¾ conditional processing
¾ IF and CASE
¾ looping constructs
¾ error handling
¾ Seamless integration of SQL, SQL functions
PL/SQL is a procedural language for the ORACLE database. PL/SQL stands for Procedural
Language extensions to SQL. It is a proprietary language; i.e. a PL/SQL program will not run on a
SQL Server database.
As a 3rd generation language, it provides many of the standard capabilities you would expect
including:
¾ Variable definition and assignment
¾ Conditional processing (IF and CASE statements)
¾ Loop constructs
¾ Error handing
It provides seamless integration (embedding) of SQL and SQL functions.
Note that Oracle client-side products such as Oracle Forms also support PL/SQL.
1.4
¾ Compatible datatypes
¾ No conversions
¾ Not great for lots of complex procedural code
¾ However, consider Native Compilation
Because of the tight integration of SQL and PL/SQL, PL/SQL is very good at data manipulation. So if
you are coding a routine that contains lots of SELECT, UPDATE, DELETE and INSERT statements,
with relatively little procedural code, PL/SQL is a good choice. In this course you will see how
PL/SQL does many things automatically for you; e.g. open and close cursors.
Conversely, if you writing complex procedural code that will be repeatedly executed, Java or C might
be a better choice. However, with the PL/SQL Native Compilation feature, PL/SQL is becoming a
consideration even for computationally intensive routines.
1.5
PL/SQL is relatively simple to learn and you’ll only need SQL*Plus to develop, test and deploy
PL/SQL programs.
PL/SQL programs are portable to any Oracle database running on any platform. Rarely, if ever, will
code changes be required. An exception would be if specific OS paths or commands are hard-coded
within a program.
PL/SQL programs are callable from any type of client. If the client can connect to the database, it
can call a PL/SQL procedure or function – and that procedure can return a value or result set to the
caller.
1.6
1.7
Anonymous Blocks
Seamless
integration of SQL
¾ Execute block from SQL*Plus
SQL>
SQL> @copycust
@copycust 33
SQL> declare
SQL> declare
22 v_custno
v_custno number
number :=
:= &1
&1 ;;
33 begin
begin
44 INSERT
INSERT INTO
INTO cust_history
cust_history
55 SELECT
SELECT **
66 FROM
FROM customer
customer Copy customer to
77 WHERE
WHERE cust_no
cust_no == v_custno;
v_custno; the history table
88 end;
end;
99 //
old
old 2: 2: v_custno
v_custno number
number :=:= &1
&1 ;;
new
new 2: 2: v_custno
v_custno number
number :=:= 33 ;;
PL/SQL
PL/SQL procedure successfully completed.
Don’t forget the procedure successfully completed.
slash
© 2006 SkillBuilders, Inc.
Anonymous Blocks are called anonymous because they are not stored on the database – thus they
do not have a name. They are also sometimes referred to as unnamed blocks. However, as this
example illustrates, they can be stored in an operating system file (“COPYCUST.SQL”) Anonymous
blocks are usually executed under SQL*PLUS to:
¾ update table data
¾ produce reports
¾ build database objects
Typically, the code for an anonymous block is placed in a .SQL script file. Note that we follow our
anonymous block with a slash (/) on a line by itself. When we run the script from SQL*Plus (with the
“at” sign), the anonymous block is read into the SQL*Plus buffer and scanned for SQL*Plus
substitution variables. The slash tells SQL*Plus to send the contents of the SQL*Plus buffer to the
server for execution.
Note that the SQL*Plus buffer can hold one and only one SQL command or PL/SQL block.
I have used a SQL*Plus substitution variable in place of the hard coded customer number. Thus, in
this case, this PL/SQL block must be executed from SQL*Plus. Only SQL*Plus understands
SQL*Plus substitution variables!
SQL*Plus Tips
Optionally, use SET ECHO OFF to suppress the display of the anonymous block when executed
from the SQL*Plus command prompt.
Optionally, use SET VERIFY OFF to suppress the display of the “old” and “new” substitution
messages.
Supplemental Notes
Note that the example shown here is for educational purposes only – specifically to illustrate the
block structure of a PL/SQL program. The SQL statement within the BEGIN block could more easily
be executed without being coded within the confines of a PL/SQL block.
1.8
Compile Errors
SQL>
SQL> @copycust
@copycust 66 “*” will be
INSRET INTO cust_history
INSRET INTO cust_history somewhere near
** clause that caused
ERROR error
ERROR atat line
line 4:
4:
ORA-06550: line 4, column
ORA-06550: line 4, column 10: 10:
PLS-00103:
PLS-00103: Encountered
Encountered the
the symbol
symbol "INTO"
"INTO" when
when
expecting one of the following:
expecting one of the following:
:=
:= .. (( @@ %% ;;
ORA-06550:
ORA-06550: line line 8,
8, column
column 1:
1:
PLS-00103:
PLS-00103: Encountered
Encountered the
the symbol
symbol "END"
"END"
While the error message has identified the correct line (line 4 contains INSERT spelled incorrectly),
note the misleading error message.
Later we will see that compile errors in triggers, stored procedures, and stored functions are not
automatically displayed by SQL*Plus. You must specifically display them yourself with the SQL*Plus
SHOW ERRORS command.
1.9
Output to SQL*Plus
¾ Use DBMS_OUTPUT.PUT_LINE to display
text on screen
SQL>
SQL> set
set serveroutput
serveroutput on
on
SQL> begin
SQL> begin
22 dbms_output.put_line('Hello
dbms_output.put_line('Hello World')
World') ;;
33 end
end ;;
44 //
Hello
Hello World
World
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
PL/SQL may display output to SQL*Plus by using the Oracle supplied package procedure called
DBMS_OUTPUT.PUT_LINE. This procedure displays text on the output device (console) in
SQL*Plus.
In order for the output from DBMS_OUTPUT.PUT_LINE to be seen, the SET SERVEROUTPUT on
SQL*Plus command must be executed. You may want to consider putting this command in your
LOGIN.SQL file as this setting reverts to the default (off) when the session ends.
1.10
Procedures
SQL>
SQL> @procedure1
@procedure1
SQL>
SQL> create
create procedure
procedure p1
p1 as
as
22 begin
begin
33 dbms_output.put_line('Hello
dbms_output.put_line('Hello World');
World');
44 end;
end;
55 // Procedure is now
compiled and
Procedure
Procedure created.
created. stored in database
SQL>
SQL> exec
exec p1
p1
Hello
Hello World
World
Call the procedure
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
with the SQL*Plus
completed.
EXECUTE command
Procedures and functions are callable subprograms which are also compiled and stored permanently
in the Oracle server. (The main difference between procedures and functions is that stored functions
must return a value to the caller. Otherwise, they are basically the same. You will learn much more
about this later in this course.)
In the example shown above, I coded a simple stored procedure in file “PROCEDURE1.SQL”. The
procedure is created with the CREATE PROCEDURE statement (refer to the Oracle9i SQL
Reference for more information on this statement; you will learn a lot more about this statement
later in this course). When I run the file, it compiles and stores the stored procedure in the database.
Note that the name of the procedure is “p1”; the name of the OS file that contains the source code is
“PROCEDURE1.SQL”. I use the SQL*Plus EXECUTE command (“exec p1”) to call the stored
procedure.
1.11
Warning:
Warning: Procedure
Procedure created
created with
with compilation
compilation errors.
errors.
SQL>
SQL> show
show errors
errors Use the SQL*Plus
Errors
Errors for
for PROCEDURE
PROCEDURE P1:
P1: SHOW ERRORS
command
LINE/COL
LINE/COL ERROR
ERROR
--------
-------- ------------------------------------------------------
------------------------------------------------------
4/1
4/1 PLS-00103:
PLS-00103: Encountered
Encountered the
the symbol
symbol "END"
"END" when
when expecting
expecting
© 2006 SkillBuilders, Inc.
Compile errors generated by the CREATE PROCEDURE (and CREATE FUNCTION, CREATE
TRIGGER) statements are not automatically displayed on the SQL*Plus screen. These errors are
stored in a data dictionary view called USER_ERRORS. They can be displayed by querying this
view or, as shown in this slide, by using the SQL*Plus SHOW ERRORS command. The complete
text of the error message is:
LINE/COL ERROR
-------- -----------------------------------------------
4/1 PLS-00103: Encountered the symbol "END" when expecting one of the
following: := . ( % ;
The symbol ";" was substituted for "END" to continue.
Supplemental Notes
Note that instead of using DROP PROCEDURE you can add the “OR REPLACE” option to the
CREATE PROCEDURE command:
SQL> @p1
SQL> create or replace procedure p1 as
2 begin
3 dbms_output.put_line('Hello World');
4 end;
5 /
Procedure created.
The DROP statement can be used to drop most Oracle procedural objects, e.g. DROP FUNCTION,
DROP TRIGGER, DROP PACKAGE, DROP PACKAGE BODY etc.
1.13
Functions
SQL>
SQL> @function1
@function1
SQL>
SQL> create
create or
or replace
replace function
function f1
f1 Must identify
22 return char
return char datatype function
33 asas will return
44 begin
begin
55 return
return ('test');
('test');
66 end;
end;
77 //
Call function from
an SQL or PL/SQL
Function
Function created.
created. statement
SQL>
SQL> select
select f1()
f1() from
from dual;
dual;
F1()
F1()
--------------------------------------------
--------------------------------------------
test
test
© 2006 SkillBuilders, Inc.
A PL/SQL function is very similar to a procedure; it is just that the function always returns a value to
the caller and is invoked semantically different from the procedure. Whereas the procedure
invocation is a statement in itself, the function is called within the context of another PL/SQL or SQL
statement.
1.14
Packages...
¾ Package is a group of PL/SQL objects
SQL>
SQL> create
create or
or replace
replace package
package p1
p1 as
as
22 function
function f1f1 return
return char;
char;
33 procedure
procedure proc1;
proc1;
44 end;
end; SQL>
55 // SQL> create
create or
or replace
replace package
package body
body p1
p1 as
as
22 function
function f1
f1 return
return char
char
33 as
as
Package
Package created.
created. 44 begin
begin
55 return
return ('test');
('test');
66 end;
end;
77
88 procedure
procedure proc1
proc1 as
as
99 begin
begin
10
10 dbms_output.put_line('Hello
dbms_output.put_line('Hello World');
World');
11
11 end;
end;
12
12 end;
end;
13
13 //
© 2006 SkillBuilders, Inc.
A package is a group of PL/SQL objects often including procedures and functions. There are many
benefits of packaging, which we will discuss in a subsequent lesson dedicated to packages. For
now, it is just important to understand that PL/SQL objects can be packaged – as opposed to
standalone objects.
Refer to the supplied script PACKAGE1.SQL for a working copy of the code shown here.
1.15
...Packages
¾ Qualify packaged objects with package name
SQL>
SQL> select
select p1.f1
p1.f1 from
from dual;
dual;
F1
F1
----------------------------------
----------------------------------
test
test
1.16
Data Dictionary
¾ Dictionary records existence of PL/SQL
objects
SQL>
SQL> select
select object_name,
object_name, object_type
object_type from
from user_objects
user_objects
22 where
where object_type in ('PROCEDURE', 'FUNCTION');
object_type in ('PROCEDURE', 'FUNCTION');
OBJECT_NAME
OBJECT_NAME OBJECT_TYPE
OBJECT_TYPE
-------------------------
------------------------- ------------------
------------------
F1
F1 FUNCTION
FUNCTION
P1
P1 PROCEDURE
PROCEDURE
The existence of PL/SQL objects (procedures, functions, packages, etc) is recorded in the data
dictionary. USER_OBJECTS contains one row for each object.
1.17
Triggers...
¾ Code tied to a table
¾ Executes automatically when DML executes
SQL>
SQL> @trigger1
@trigger1 Trigger tied to
SQL>
SQL> create
create trigger
trigger customer_name
customer_name CUSTOMER table
22 before
before update
update or
or insert
insert on
on customer
customer
33 for each row
for each row
44 begin
begin
55 /*
/* convert
convert character
character values
values toto upper
upper case
case */
*/
66 :new.lastname
:new.lastname :=:= upper(
upper( :new.lastname
:new.lastname ); );
77 :new.firstname
:new.firstname :=:= upper(
upper( :new.firstname
:new.firstname ); );
88 dbms_output.put_line('trigger
dbms_output.put_line('trigger fired');
fired');
99 end;
end;
10 Use the UPPER
10 // function to convert
Trigger characters inserted
Trigger created.
created. into the database
© 2006 SkillBuilders, Inc.
Triggers are, usually, code associated with a table and are executed automatically when an
appropriate SQL statement is issued against the table. There are also triggers which are associated
with system events such as Startup and Shutdown or DDL such as CREATE and DROP statements.
Other triggers can be created which are associated with user events such as Logon or Logoff.
Triggers are compiled and stored permanently in the Oracle server. Triggers are often used to:
¾ Enforce complex business and/or integrity rules
¾ Audit modifications to a table
¾ Derive column values
¾ Maintain mirror tables
This trigger, called “customer_name”, will execute whenever an INSERT or UPDATE statement is
executed on the DAVE.CUSTOMER table (the schema of the compiler is used for the table, unless
qualified or a synonym exists).
1.18
...Triggers
SQL>
SQL> insert
insert into
into customer
customer
22 (cust_no,
(cust_no, firstname,
firstname, lastname)
lastname)
33 values
values Verification that
44 (3423,
(3423, 'dave',
'dave', 'anderson');
'anderson'); trigger executed
trigger
trigger fired
fired
11 row
row created.
created.
SQL>
SQL> select
select firstname,
firstname, lastname
lastname
22 from customer
from customer
33 where
where cust_no
cust_no == 3423;
3423;
FIRSTNAME
FIRSTNAME LASTNAME
LASTNAME
---------------
--------------- --------------------
-------------------- Characters are
DAVE
DAVE ANDERSON
ANDERSON converted to upper
case
© 2006 SkillBuilders, Inc.
We see that the PUT_LINE procedure displayed the text “trigger fired” when the INSERT statement
executed. This is purely diagnostics. And we see that the trigger did indeed work; the characters
have been converted to upper case characters.
Refer to the supplied script TRIGGER1.SQL for a copy of the code shown in this example.
1.19
SQL*Plus is the traditional tool for PL/SQL development as it is included with all versions of the
Oracle database. You may choose to use a more robust development tool, like Procedure Builder,
which provides a graphical development environment. This product has to be purchased separately
but may be worth the extra cost as it provides many sophisticated debugging features and a better
overall working environment for your development efforts.
There are many third party tools also available such as TOAD from Quest Software. Free limited
feature versions of this product are available at www.toadsoft.com.
1.20
Working in SQL*Plus
¾ SET ECHO ON
¾ Show compiled source on your screen
¾ SET SERVEROUTPUT ON
¾ PUT_LINE calls will be displayed after program returns
control to SQL*Plus
¾ Put in LOGIN.SQL
¾ SHOW ERRORS
¾ Error messages will refer to a line and column number
¾ Oracle Error messages manual is available to help
Debugging your PL/SQL programs can be tedious if you are uncertain of where the error messages
are pointing to. The simplest way to see the errors is to SET ECHO ON prior to the compile of your
source. You will have the program source echoed on your screen with line numbers. If there are any
error messages, it will be simple to ascertain where the error occurred. (You can also get the source
line number from your USER_SOURCE library. You cannot just count lines in your original source file
because the PL/SQL compiler does not count blank lines and some comment lines.)
I recommend that you put the SET ECHO ON and SERT SERVEROUTPUT commands in your
LOGIN.SQL file. This file, when placed in your working directory, will be automatically executed
when you start SQL*Plus. Refer to the sample LOGIN.SQL file supplied with this course for and
example.
For anonymous blocks, the error will be displayed when you try to execute the code. For procedures,
functions, packages and triggers, remember to use the SHOW ERRORS command to display the
error messages.
1.21
Introduction to PL/SQL
Workshops
¾ Hello World
¾ Setup
Workshop – Setup
¾ Run the supplied scripts DDL.SQL and INSERT.SQL to create a series of test tables that will be
needed as you progress through the rest of the course.
Lesson 2
Language Fundamentals
A programmer’s introduction to the
fundamental language elements in
PL/SQL.
2.2
Lesson Objectives
¾ Statements ¾ Variable scope
¾ Symbols ¾ Nested Blocks
¾ Datatypes ¾ IF
¾ Variable declaration ¾ CASE
and assignment ¾ Looping constructs
¾ Declaring PL/SQL ¾ Introduction to Arrays
Records
To some extent, this is a reference chapter. You’ll see relatively large lists of statements, datatypes
and symbols. I recommend that you do not attempt to remember each one as you progress through
this chapter. We’ll incorporate them into examples in the remainder of the course.
However, do use this lesson to acquire a solid grasp of the basic format of the IF, CASE, loop
statements, and a good understanding of arrays. But here again, you’ll see these statements used
throughout the rest of the course.
2.3
PL/SQL Statements
¾ CASE
¾ :=
SQL
¾ IF ¾ SELECT INTO
¾ LOOPs ¾ INSERT Pragmas
¾ EXIT ¾ DELETE ¾ AUTONOMOUS_
¾ TYPE ¾ UPDATE TRANSACTION
¾ FORALL ¾ LOCK TABLE ¾ EXCEPTION_INIT
¾ OPEN FETCH ¾ MERGE
CLOSE ¾ RESTRICT_
¾ CURSOR ¾ CASE REFERENCES
¾ procedure_call; ¾ ROLLBACK
¾ EXECUTE ¾ SAVEPOINT
IMMEDIATE ¾ SET TRANSACTION
¾ RETURN
¾ RAISE
¾ NULL Mini-Workshop
Mini-Workshop
¾ GOTO
© 2006 SkillBuilders, Inc.
Shown here is a list of commonly used statements that can be used within a PL/SQL program. Refer
to the Oracle9i PL/SQL User's Guide and Reference for a complete list and description of each
statement.
Throughout the remainder of this course you will learn the purpose of and see examples of many of
these statements.
You may be wondering, “where are the rest of the SQL statements?” DDL statements such as
CREATE, GRANT, DROP etc. Well, these are DDL statements and cannot be coded directly within
PL/SQL. Use the EXECUTE IMMEDIATE statement to embed DDL statements.
Mini-Workshop
Access chapter 13 of the Oracle9i PL/SQL User's Guide and Reference (R2) and review the
examples of the following LOOP statements:
¾ basic_loop_statement
¾ for_loop_statement
¾ cursor_for_loop_statement
Access to the complete set of Oracle manuals is free at http://technet.oracle.com.
2.4
PL/SQL Symbols
Symbol Purpose
+ - * / Addition, Subtraction, Multiplication,
Division
:= Assignment operator
= Equal to relation
>, < Greater than/less than relation
<= >= Less than/greater than or equal to
<> != ~= ^= Not equal operators
; Statement terminator
, Item separator
” Quoted identifier
' Character string identifier
-- Single line comment.
/* */ Beginning / ending of multi-line comment
List
Listcontinues
continues
© 2006 SkillBuilders, Inc.
Symbol Purpose
. Component selector
( ) Used to control precedence. 5* (2+2)
% Prefix for PL/SQL attributes. emp.name%TYPE
.. Range operator for loops. FOR x in 1..5 LOOP
@ Used to reference remote databases.
select * from emp@hq;
: Used to prefix a host variable.
=> The “arrow”. Use in procedure calls to assign
value to a parameter.
|| Concatenation operator.
<< >> Label.
Refer to chapter 2 of the Oracle9i PL/SQL User’s Guide and Reference for complete details on the
PL/SQL symbols (see “delimiters”).
2.5
PL/SQL
PL/SQL procedure
procedure successfully completed.
LINUX>
LINUX>
successfully select
select ** from
completed. from t;
t;
C1
C1
-------------------------
-------------------------
Peg's
Peg's birthday
birthday present
present
Oracle10g introduces a new technique for identifying enclosing quotes (delimiters) in text literals. It is
supported in SQL statements and PL/SQL statements. This makes coding strings that contain single
quotation marks cleaner and less error-prone.
Use the letter “q” (not case-sensitive) followed by the open quote and the quote delimiter character.
The Oracle10g SQL Reference states that the quote delimiter character can be any character;
however, I find it easiest to use a character that is not used in the literal itself.
If the quote delimiter character is [, {, <, or (, then the closing delimiter must be ], }, > or ),
respectively. Otherwise use the same exact character as the opening and closing quote delimiter
character.
Refer to the section on “Literals” in the Oracle10g SQL Reference manual for more information on
what Oracle calls the “alternative quoting mechanism”.
2.6
PL/SQL datatypes define the format of a variable, constant or parameter (parameters are used to
pass values to and from a procedure or function).
The slide contains a list of commonly used PL/SQL datatypes. In addition to the examples
throughout the remainder of this course, refer to Chapter 3 of the PL/SQL User’s Guide and
Reference for a complete list and description of the datatypes.
Here is a brief description of the datatypes listed here:
¾ NUMBER. Specify number of digits (precision) and number of decimal places (scale) if you
want to store fixed point numbers. Omit precision and scale for floating point numbers.
NUMBER has many subtypes such as DECIMAL and INTEGER; refer to the Oracle
documentation for more information.
¾ CHAR is fixed length character data. The default length of a CHAR variable is 1, the
maximum length is 32767. The database character set determines the internal
representation.
¾ VARCHAR2 is variable length character data. Maximum length is 32767. For better
performance, Oracle pre-allocates 2000 bytes of storage for all VARCHAR2 definitions less
than 2000 bytes (it eliminates “reallocations as different sized strings are allocated to it”,
Tom Kyte, May 2004, http://asktom.oracle.com.)
¾ DATE holds a date/time value.
¾ TIMESTAMP contains a date/time value with fractional microseconds.
¾ TIMESTAMP WITH TIME ZONE adds a time zone component to a TIMESTAMP type.
¾ BOOLEAN variables contains TRUE, FALSE, or NULL and are use in conditional logic, e.g. CASE
and IF statements. e.g. IF VALID_ORDER THEN….
¾ EXCEPTION is used to define a user-defined exception name, for example “customer_not_found”.
Refer to the “Error Handling” lesson for more information.
¾ REF CURSOR is a pointer to a memory cursor. Useful for returning sets of rows to callers /
clients.
¾ RECORD defines a composite type; a collection of other scalar or composite types.
¾ TABLE defines a PL/SQL unbounded array, officially called an “index-by table” or “associative
array”. Refer the examples later in this lesson for more information.
¾ RAW and LONG RAW are binary data. LONG RAW has been deprecated in favor of BLOB.
¾ BLOB is best to use for large binary objects.
¾ LONG and CLOB are large character data objects, better to use newer CLOB.
¾ NCLOB is national character set long character object.
¾ BFILE is an external binary file.
¾ ROWID is a pointer to a table row.
2.8
Declaring Variables…
Comparison
Comparisonisiscase
case
¾ Specify the following: Variable sensitive
sensitive
Variablename
nameisis
¾ name not case sensitive
not case sensitive
¾ datatype
Initial
Initialvalue
value
¾ nullability (optional)
¾ initial value (optional)
SQL>
SQL> declare
declare
22 v_lastname
v_lastname varchar2(20)
varchar2(20) notnot null
null :=
:= 'SMITH';
'SMITH';
33 begin
begin
44 If
If V_Lastname
V_Lastname == 'SMITH'
'SMITH' then
then null;
null; end
end if;
if;
55 end;
end;
66 //
NULL
NULLisisthe
theno-op
no-op
statement
statement
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
© 2006 SkillBuilders, Inc.
Variables are declared in the DECLARE section of the program. Required are name and datatype.
The name, like all Oracle names, must follow these rules:
¾ 1 – 30 alpha-numeric characters
¾ 1st character must be alphabetic
¾ Valid special characters are _, $ and #
¾ Avoid reserved words such as SELECT
In this example, V_LASTNAME is defined with the NOT NULL clause, so it can not contain a null
value. An exception is raised if an initial value is not assigned (see the next page for an example).
Therefore we must assign the variable an initial value ('SMITH‘ in this example). This is done with
the assignment operator (:=) or the DEFAULT keyword.
“NULL” is the PL/SQL no-operation statement. I use it here (see line 4) simply because the BEGIN
block is required, yet I do not want it to do anything – I simply wanted to demonstrate the declaration
and use of a variable.
An exception is raised if a variable defined as NOT NULL is not given a default value:
SQL> declare
2 x number not null;
3 begin
4 null;
5 end;
6 /
x number not null;
*
ERROR at line 2:
ORA-06550: line 2, column 3:
PLS-00218: a variable declared NOT NULL must have an initialization
assignment
2.10
…Declaring Variables
SQL>
SQL> declare
declare
22 v_hiredate1
v_hiredate1 date;
date;
33 v_hiredate2
v_hiredate2 date
date :=
:= sysdate;
sysdate;
44 v_total_sales number(8,2);
v_total_sales number(8,2);
55 v_total_value1
v_total_value1 number(8,2)
number(8,2) := := 0;
0;
66 v_total_value2
v_total_value2 number(8,2) default 0;
number(8,2) default 0;
77 v_order_valid
v_order_valid boolean
boolean :=:= false;
false;
88 v_lastname
v_lastname varchar2(20)
varchar2(20) notnot null
null :=
:= 'Smith';
'Smith';
99 c_co_name constant varchar2(20) := 'SkillBuilders';
c_co_name constant varchar2(20) := 'SkillBuilders';
10
10 begin
begin
11
11 null;
null;
12 end;
12 end;
13
13 //
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
© 2006 SkillBuilders, Inc.
2.11
%TYPE
Datatype
Datatypevariable
variable
using
usingtable
tablecolumn
column
SQL>
SQL> declare
declare
22 v1
v1 customer.lastname%type;
customer.lastname%type;
33 begin
begin
44 select Use
UseSELECT
SELECTINTO
select lastname
lastname into
into v1
v1 INTO
55 from totoretrieve
retrieve11row
row
from customer
customer
66 where
where cust_no
cust_no == 1;
1;
77 dbms_output.put_line(v1);
dbms_output.put_line(v1);
88 end;
end;
99 //
Jones
Jones
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
%TYPE is a great way to datatype a variable. Oracle will use the datatype of the table column,
variable or cursor coded in the %TYPE specification. (You’ll learn more about cursors later.) It is
flexible; if the datatype changes, the new datatype will be picked up when the code is recompiled –
without a source code change.
In this example variable V1 gets the same exact datatype as the LASTNAME column of the
CUSTOMER table.
This example includes the SELECT INTO statement (a form of implicit cursor). Some form of
SELECT is required to access values in a database table (i.e. you cannot just compare to a table
value in an IF or CASE statement without first selecting the data). You’ll learn more about SELECT
INTO and other means of retrieving data later in this course.
See the supplied script TYPE.SQL for a copy of the code shown here.
2.12
PL/SQL Records
¾ A record is a collection of related fields
¾ Similar structure to table row
¾ 4 ways to define records
¾ Table-based
¾ table-name%ROWTYPE
¾ Programmer-defined
¾ Cursor-based
¾ cursor-name%ROWTYPE
¾ Implicit with cursor FOR LOOP
These
Theseare
are
discussed
discussedlater
later
© 2006 SkillBuilders, Inc.
A PL/SQL record provides a way to deal with separate, but related, fields (variables) as a single unit. A
record often has a similar structure to a row in a database table.
There are four ways to define PL/SQL records. We will see examples of table-based and programmer-
defined records in the following pages.
See the supplied script DEFINING_PLSQL_RECORDS.SQL for examples of the four techniques for
declaring variables.
2.13
Records: %ROWTYPE
¾ Define with SQL>
SQL> DECLARE
DECLARE
%ROWTYPE 22 cust_rec
cust_rec customer%rowtype;
customer%rowtype;
33 BEGIN
BEGIN
¾ Record 44 cust_rec.cust_no
cust_rec.cust_no :=:= 234;
234;
matches row 55 cust_rec.lastname
cust_rec.lastname :=:= 'Anderson';
'Anderson';
66 cust_rec.firstname
cust_rec.firstname :=:= 'Dave';
'Dave';
¾ 9i supports 77 INSERT
INSERT INTO
INTO customer
customer
record-based 88 VALUES
VALUES cust_rec;
cust_rec;
99 END;
END;
DML 10
10 //
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
A table-based record is defined with the %ROWTYPE attribute and creates a records that matches the
structure of the table row. i.e., the record has the same number of fields as columns in the table and the
fields have the same name and datatype.
A PL/SQL record defined with %ROWTYPE:
¾ contains the same number of variables as columns in the table
¾ all datatypes match
¾ field names are the same as column names
As we see in this example, the fields in the record are referenced with “dot notation”, for example
“cust_rec.lastname”. Then we can use the entire record in the INSERT (and UPDATE) statements.
As of Oracle9i, a table-based record is a convenient structure for DML operations. Note that the
VALUES clause in the INSERT statement references the record – eliminating the need to code each
variable. The lack of parenthesis is correct syntax when a record is used.
See the supplied script RECORDS.SQL for a working example of this code.
2.14
TYPE
TYPE type_name
type_name IS
IS RECORD
RECORD
(field1
(field1 datatype1
datatype1 {NOT
{NOT NULL}
NULL} [:=
[:= expr1],
expr1],
field2
field2 datatype2
datatype2 {NOT
{NOT NULL}
NULL} [:=
[:= expr2]
expr2]
...);
...);
record_name
record_name type_name;
type_name;
A programmer defined PL/SQL record is a record where each field is explicitly defined by the
programmer. You must first define a record type. Then, you must declare a variable of that type.
The datatype of each field can be:
¾ Scalar types (NUMBER, VARCHAR2, DATE, etc.)
¾ %TYPE, %ROWTYPE or another programmer defined record (yes, Oracle supports nested
records).
¾ Oracle objects (e.g. defined with CREATE TYPE object-name AS OBJECT)
¾ PL/SQL array (more on arrays later in this lesson).
¾ REF CURSOR, i.e. a pointer to a cursor. (more on REF CURSORS later in this lesson).
Parameter descriptions:
type_name Name of record type
field Name of field (variable) in record
datatype Datatype of field in record
There is no limit on the number of fields within the record.
2.15
...Programmer Defined
Records...
CREATE
CREATE OROR REPLACE
REPLACE PACKAGE
PACKAGE custpack
custpack ASAS
TYPE
TYPE cust_info_t
cust_info_t ISIS RECORD
RECORD
(cust_no
(cust_no NUMBER,
NUMBER, Package
Packagecontains
containsaa
first_purchase
first_purchase DATEDATE :=
:= SYSDATE);
SYSDATE); record
recordtype
type
END;
END;
//
CREATE
CREATE OR
OR REPLACE
REPLACE FUNCTION
FUNCTION create_cust
create_cust
RETURN
RETURN custpack.cust_info_t
custpack.cust_info_t Function
Functionreturns
returns
IS
IS aarecord
record
cust_rec
cust_rec custpack.cust_info_t;
custpack.cust_info_t;
BEGIN
BEGIN
SELECT
SELECT s1.NEXTVAL
s1.NEXTVAL INTO
INTO cust_rec.cust_no
cust_rec.cust_no FROM
FROM dual;
dual;
RETURN(cust_rec);
RETURN(cust_rec);
END;
END;
// Example
Example continues.
continues. .. ..
This example shows that a programmer-defined record type can be packaged. Packaging the record
makes the record global, i.e. accessible to any user with execute privilege on the package. Next, we
see that a function can return a record – see the RETURN(cust_rec) statement. (Later you will learn
how to return sets of records!)
Here, I have packaged a record type called CUST_INFO_T. Then, I use that type in a function called
CREATE_CUST. The function returns a record. Note the reference to the TYPE within the function
requires the prefix of the package name, as in “CUSTPACK.CUST_INFO_T”.
This example requires that a sequence called S1 has been created, for example:
CREATE SEQUENCE s1;
See the supplied script RECORD_IN_PACKAGE.SQL for a working example of this code.
2.16
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
© 2006 SkillBuilders, Inc.
Here again we see the definition of a record based on a packaged TYPE. We also see the call to the
function CREATE_CUST, where CREATE_CUST returns a record.
2.17
Language Fundamentals
Workshop A
¾ PL/SQL Records
2.18
Variable Scope
¾ Variables persist in block they are declared
¾ And any embedded sub-blocks
¾ Cannot be referenced in outer block
¾ Can use packages to create “global” or “session”
variables if needed
¾ Easy to pass values
¾ Procedures can have IN and OUT parameters
The scope of a variable is where it can be referenced (i.e. used or seen). When a variable is
declared, it is accessible throughout the PL/SQL block – and any embedded sub-blocks. A variable
cannot be reference in:
¾ An outer (enclosing) block
¾ A called procedure or function (To accomplish this, use either use packaged variables or pass
the procedure or function a value in the call. You will learn both techniques later in the
course.)
¾ A calling procedure or function (To return a value from a procedure, use OUT type variables.
Functions, by design, always return a value)
(Using packages, we can create session (global) variables. This will be discussed in the lesson on
packages later in this course.)
2.19
Nested Blocks
SQL>
SQL> declare
declare
22 v_custno
v_custno NUMBER
NUMBER :=
:= 100;
100;
33 begin
begin
44 dbms_output.put_line(v_custno)
dbms_output.put_line(v_custno) ;;
55 declare
declare
66 v_state
v_state CHAR(2):=
CHAR(2):= 'NY'
'NY' ;;
77 begin
begin
88 dbms_output.put_line
dbms_output.put_line
99 (v_custno
(v_custno |||| v_state)
v_state) ;;
10
10 end
end ;;
11
11 end
end ;;
12
12 //
100
100
100NY
100NY Both variables
Both variables
can
canbe
be
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed. referenced
referencedininthe
the
inner
innerblock
block
© 2006 SkillBuilders, Inc.
A PL/SQL variable can be referenced in blocks nested within the block in which the variable is
defined unless the nested block contains a variable of the same name; then the local version of the
variable is referenced.
In the example, there are two blocks. In the first, we declare a variable, V_CUSTNO. In the second,
we declare another variable, V_STATE. In the inner block, we can reference the V_CUSTNO
variable. Take note that the V_STATE variable cannot be referenced outside the inner block. For
instance, the following code will generate a compile error:
declare
v_custno NUMBER := 100;
begin
dbms_output.put_line(v_custno) ;
declare
v_state CHAR(2):= ‘NY’ ;
begin
this reference dbms_output.put_line (v_custno || v_state) ;
end ;
dbms_output.put_line(v_state) ;
generates error end ;
ERROR at line 10:
ORA-06550: line 10, column 25:
PLS-00201: identifier 'V_STATE' must be declared
ORA-06550: line 10, column 4:
PL/SQL: Statement ignored
2.20
Functions
¾ Most SQL functions can be used in PL/SQL
statements
77 if
if upper(v1)
upper(v1) == 'ANDERSON'
'ANDERSON' then
then
88 null;
null;
99 end More
Moreexamples
examplesinin
end if;
if; the
theError
ErrorHandling
Handling
¾ Specific PL/SQL error-reporting functions lesson
lesson
77 v_msg
v_msg varchar2(1020)
varchar2(1020) default
default sqlerrm;
sqlerrm;
88 v_code
v_code number
number default
default sqlcode;
sqlcode;
Scalar SQL functions such as UPPER, LOWER, INITCAP and SUBSTR can be used in PL/SQL
statements. However, the aggregate functions (AVG, MIN, MAX) and analytic functions (LEAD,
LAG) are not permitted in PL/SQL statements. Of course, the aggregate and analytic functions can
be used in SQL statements embedded in PL/SQL.
Oracle also supplies error-related functions SQLERRM and SQLCODE for use in PL/SQL statements
only. This slide shows an excerpt from a DECLARE block where we use these functions to initialize
local variables. SQLERRM contains the text of the last error message; SQLCODE contains the
Oracle error code. You will learn more about the use of these functions in the lesson on error
handling later in this course.
2.21
Regular Expressions
10g
¾ Like SQL, PL/SQL supports regular
expressions
LINUX>
LINUX> declare
declare
22 v1v1 varchar2(20)
varchar2(20) :=:= 'abcdefg';
'abcdefg';
33 begin
begin
44 if
if regexp_like(v1,
regexp_like(v1, '.*c*')
'.*c*') then
then null;
null; end
end if;
if;
55 v1
v1 :=
:= regexp_replace(v1,
regexp_replace(v1, '.*c*',
'.*c*', 'a');
'a');
66 dbms_output.put_line(v1);
dbms_output.put_line(v1);
77 end;
end;
88 //
aa
aa
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
Like the Oracle 10g SQL compiler, the 10g PL/SQL compiler supports regular expressions.
Oracle’s implementation is IEEE POSIX and Unicode Consortium compliant. Oracle10g provides
many new operators such as:
¾ * - Matches zero or more occurrences
¾ + - Matches one or more occurrences
¾ ? - Matches zero or one occurrence
¾ ^ - Anchors to the beginning of the line
¾ $ - Anchors to the end of line
Oracle 10g Release 2 adds support for Perl expressions, including, but not limited to:
¾ \d – Match a digit character
¾ \D – Match a non-digit character
¾ \w – Match a word character
¾ \W – Match a non-word character
2.23
IF Statement
IF
IF condition
condition THEN
THEN IF
action(s); IF condition
condition THEN
THEN
action(s); action(s);
action(s);
END
END IF;
IF; ELSIF
ELSIF condition
condition THEN
THEN
action(s);
action(s);
ELSIF
ELSIF condition
condition THEN
THEN
action(s);
action(s);
IF
IF condition
condition THEN
THEN [ELSE
[ELSE
action(s);
action(s); action(s);]
action(s);]
ELSE
ELSE END
END IF;
IF;
action(s);
action(s);
END
END IF;
IF;
The IF statement (and CASE statement) can be used for conditional processing. The IF construct
must be terminated with END IF and followed by a semi-colon. You can optionally use ELSE to
provide what to do if the condition is not met.
You may nest IF statements. For example:
IF V_sales_amt = 100 THEN
…
ELSE
IF V_sales_amt < 200 THEN
…
ELSE
…
ENDIF;
ENDIF:
The use of ELSIF allows you to check multiple conditions within one construct.
0 Caution: ELSIF is spelled “ELSIF”, not “ELSEIF”, and not “ELSE IF”. Believe it or not!
There is no limit to the number of ELSIF conditions that can be included in a single construct.
2.24
CASE
¾ Simple CASE
CASE
CASE expression
expression WHEN
WHEN this1
this1 THEN
THEN that1
that1
WHEN
WHEN this2 THEN
this2 THEN that2
that2 .. .. ..
[[ ELSE
ELSE that
that ]]
Exception raised if no
condition true and ELSE
¾ Searched CASE not coded
CASE
CASE WHEN
WHEN condition1
condition1 THEN
THEN return-value1
return-value1
WHEN
WHEN condition2 THEN
condition2 THEN return-value2
return-value2
.. .. ..
[[ ELSE
ELSE return-value
return-value ]]
Oracle9i introduced PL/SQL support for a CASE statement and CASE expression (8i introduced support
for SQL-level CASE). Oracle supports two flavors of CASE, simple and searched.
¾ The simple case expression tests for an equal condition on the supplied value or expression. The
first WHEN value that is equal causes Oracle to return the corresponding THEN value. If none of
the WHEN values match the supplied expression, the ELSE value is returned. If the ELSE is not
coded, NULL is returned.
¾ The searched case (as seen in the previous example) allows multiple comparison expressions (<,
>, <=, >=, BETWEEN, LIKE, IN, IS NULL, etc.). The first TRUE expression causes Oracle to
return the corresponding THEN value. If none of the WHEN values match the supplied expression,
the ELSE value is returned. If the ELSE is not coded, a CASE not found exception is returned.
The WHEN clauses are evaluated sequentially. The 1st TRUE WHEN causes the associated
statement(s) to be executed; The CASE statement then ends (execution continues after the END CASE
clause). If none of the WHEN expressions is true the ELSE statement (if any) will execute.
The CASE statement raises a CASE_NOT_FOUND exception if an ELSE clause is not provided and
none of the WHEN’s are TRUE.
Only one THEN statement (or ELSE statement) is executed for each CASE statement. There is no “fall-
through” as in the C language ‘switch’ statement.
CASE is limited to 128 WHEN/THEN pairs (255 total values). This limit can be overcome by nesting
CASE within CASE.
2.25
Simple CASE
<<salary_test>>
<<salary_test>>
CASE
CASE v_sal
v_sal
WHEN
WHEN 12
12 THEN
THEN
dbms_output.put_line('Salary
dbms_output.put_line('Salary is
is '||v_sal);
'||v_sal);
v_sal
v_sal :=
:= v_sal
v_sal ** 1.2
1.2 ;;
dbms_output.put_line('Salary
dbms_output.put_line('Salary is
is '||v_sal);
'||v_sal);
WHEN
WHEN 14
14 THEN
THEN
dbms_output.put_line('Salary
dbms_output.put_line('Salary is
is '||v_sal);
'||v_sal);
v_sal
v_sal :=
:= v_sal
v_sal ** 1.15
1.15 ;;
dbms_output.put_line('Salary
dbms_output.put_line('Salary is
is '||v_sal);
'||v_sal);
ELSE
ELSE
v_sal
v_sal :=
:= v_sal
v_sal ** 1.1
1.1 ;;
END CASE salary_test;
END CASE salary_test;
Restriction: The case-operand and the when-operands can be any datatype except BLOB, BFILE,
an object type, a PL/SQL record, an index-by-table, a varray, or a nested table.
See supplied script CASE1.SQL for a working example of this CASE expression.
2.26
Searched CASE
create
create or
or replace
replace procedure
procedure searched_case
searched_case
(p1 in number)
(p1 in number) is is
v_switch
v_switch char(1);
char(1);
BEGIN
BEGIN
v_switch
v_switch :=:=
CASE
CASE
WHEN
WHEN p1
p1 == 11 THEN
THEN 'A'
'A'
WHEN
WHEN p1 = 2 THEN 'B'
p1 = 2 THEN 'B'
WHEN
WHEN p1
p1 == 33 THEN
THEN 'C'
'C'
END;
END;
dbms_output.put_line(v_switch);
dbms_output.put_line(v_switch);
END;
END;
Here is an example of a Searched CASE expression. Note the absence of a CASE selector and the
use of Boolean expressions in each WHEN clause.
See supplied script CASE2.SQL for a working example of this CASE expression.
2.27
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
© 2006 SkillBuilders, Inc.
A simple loop repeats the logic contained within the LOOP / END LOOP construct until an
unconditional EXIT statement is executed or a condition specified by the EXIT WHEN clause is met.
Be careful; an infinite loop will occur if the EXIT statement is not executed.
Supplemental Notes
PL/SQL also offers a “WHILE” loop:
WHILE condition LOOP
statement(s);
END LOOP;
The WHILE loop differs from a simple loop in that it checks the condition first before entering the loop
and then continues to execute until the condition is met. When the WHILE condition is met, the loop
exits. In other words, the WHILE loop repeats a sequence of statements until the controlling
condition is no longer TRUE.
2.28
Nested Loops
SQL>
SQL> declare
declare
22 xx number
number := := 0;
0;
33 begin
begin
44 <<a>>
<<a>>
55 LOOP
LOOP
66 dbms_output.put_line('loop
dbms_output.put_line('loop a');
a');
77 <<b>>
<<b>>
88 LOOP
LOOP
99 dbms_output.put_line('loop
dbms_output.put_line('loop b');
b');
10
10 xx :=
:= xx ++ 1;
1;
11
11 EXIT
EXIT aa WHEN
WHEN xx == 2;
2;
12
12 END
END LOOP
LOOP b;b;
13
13 ENDEND LOOP
LOOP a;
a;
14
14 end;
end;
15
15 //
loop
loop aa
loop
loop bb
loop
loop bb
PL/SQL
PL/SQL procedure
procedure successfully
successfully completed.
completed.
© 2006 SkillBuilders, Inc.
Loops can be nested as shown in the example. Note how the inner loop, <<b>>, has the statement
EXIT a WHEN X = 2. This indicates that when when the inner loop <<b>> meets the condition of X =
2, the EXIT WHEN will exit the outer loop A. The default is to exit the current loop.
2.29
Table
Table created.
created.
SQL>
SQL> begin
begin
22 for
for xx in
in 1..100
1..100 loop
loop
33 insert
insert into
into tt values(x);
values(x);
44 end
end loop;
loop;
55 commit;
commit;
6*
6* end;
end;
SQL>
SQL> //
PL/SQL
PL/SQL procedure SQL>
SQL> select
procedure successfully
successfully count(*)
count(*) from
completed.
select
completed. from t;
t;
COUNT(*)
COUNT(*)
----------
----------
100
100
© 2006 SkillBuilders, Inc.
A numeric FOR loop allows you to implement a looping construct without having to be concerned
with an EXIT WHEN as needed in the simple loop. The numeric FOR loop implicitly defines the
index (i.e. loop counter) and exits the loop when the counter exceeds its upper bound. The general
syntax of this statement is :
FOR index IN [reverse] lower_bound..upper_bound LOOP
statement(s);
END LOOP;
The index:
¾ Is implicitly declared in the FOR statement
¾ Cannot be changed
¾ Can be referenced
And yes, you must actually type the two dots (..) between the lower_bound and upper_bound.
2.30
PL/SQL Arrays
¾ Unbounded, memory-based array
¾ Sparse
¾ Index by number or string
¾ Can hold list of values for use in program
¾ Can load with table data
¾ perform lookups
¾ Can be passed as Procedure or Function parameter
TYPE
TYPE table_type_name
table_type_name IS
IS
TABLE
TABLE OF
OF datatype
datatype [NOT
[NOT NULL]
NULL]
INDEX
INDEX BY
BY
[BINARY_INTEGER|VARCHAR2(size)];
[BINARY_INTEGER|VARCHAR2(size)];
Arrays (formally called “associative arrays” or “index-by tables”) are memory-based PL/SQL arrays,
used to store lists of data in a PL/SQL program. This might be helpful for storing data that is repeatedly
scanned – eliminating repetitive access to a database table. It can also be a useful structure for passing
sets of data between PL/SQL programs (though a ref cursor may be better suited for that).
Arrays are arrays of variables where the variable can be a scalar type, a variable defined with %TYPE or
a PL/SQL record.
Associative arrays are unbounded, meaning that they have is no limit to the number of elements in the
array. (actually, the limit is -2,147,483,647 to +2,147,483,647, or 4.3 billion rows. However, we
consider them to be unbounded because you’ll run out of memory before you will ever reach the limit.)
Associate arrays are also considered sparse, in that they do not require a sequential number of rows.
I.e. there can be gaps between element 1 and the second element; the second element might be 5.
Associative arrays require an index. The index can be BINARY_INTEGER (a number) or, with Oracle9i,
a VARCHAR2 field.
Arrays can be useful:
¾ load with table data and perform efficient lookups
¾ Passing data to another program
2.31
Similar to a programmer-defined PL/SQL record, using an array is a two-step process. First, an array
TYPE needs to be defined, then an instance of the array type is created, using the TYPE as the
datatype.
This example creates a simple array of VARCHAR2 fields called “array1”. Use an index when you
reference an element in a PL/SQL table, for example “array1(v_index)”. A subscript can be a variable,
an expression, a string (if the INDEX BY VARCHAR2 is specified in the TYPE declaration).
This example uses three array methods: FIRST, COUNT and NEXT. These are functions that work on
(i.e. provide information about or modify) the array. Turn to the next page for a description of these
methods. (Note that in the Oracle9i PL/SQL User’s Guide and Reference these are referred to as
“collection methods”; arrays are one type of collection.)
See the supplied script ARRAY.SQL for a working example of this code.
2.32
Array Methods
¾ Built-in functions and procedures that act on arrays
¾ COUNT
¾ DELETE
t_table.DELETE(n);
t_table.DELETE(n);
¾ EXISTS
¾ FIRST, LAST IF
IF t_table.EXISTS(n)
t_table.EXISTS(n) THEN
THEN ...
...
¾ NEXT
¾ PRIOR v_index
v_index :=
:= t_table.FIRST;
t_table.FIRST;
¾ TRIM
v_index
v_index :=
:= t_table.NEXT(v_index);
t_table.NEXT(v_index);
These “methods” are Oracle-supplied procedures and functions that act on arrays. They are all invoked
in one of the two ways:
¾ array.method if the method applies to the whole collection, e.g. array1.count.
¾ array.method(index) -- if it works on single element in the array, e.g. array1.delete(v_index).
Here is a brief description of the methods. Refer to chapter 5 of the Oracle9i PL/SQL User’s Guide
and Reference for a complete description.
¾ COUNT – returns the number of “used” entries in the collection. (For Varrays, that is equal to
LAST)
¾ DELETE – Procedure to deletes a single row, all rows or a range of rows. When used without an
argument, deletes all rows. Has several formats:
array1.delete -- deletes all elements from the collection.
array1.delete(4) -- deletes the fourth element.
array1.delete(4,7) -- deletes elements 4 through 7.
array1.delete(7,2) -- does nothing.
array1.delete(-1) -- does nothing, not even raise an exception!
If an element to be deleted is empty, DELETE does not raise an exception.
¾ EXISTS(n) – Function to determine to see if the element exists. Returns TRUE or FALSE.
¾ FIRST , LAST – Function that returns the index of the first row in a array.
Notes continue on the next page…
¾ LAST – Function that returns the index to the last row in a array.
¾ NEXT - Returns the index of the next row in an array. Returns null when at last row of the array.
¾ PRIOR - Returns the index of the previous row in an array.
¾ TRIM – Procedure to remove elements at the end of a collection. Has two forms:
array1.trim -- removes the last element from the array (nulls do count as valid elements).
array1.trim(4) -- removes last 4 (including not null) elements from the end of the array. Calling
with a number bigger than COUNT raises SUBSCRIPT_BEYOND_COUNT.
2.34
Language Fundamentals
Workshop B
¾ Arrays
Workshop – Arrays
To practice your skills with PL/SQL arrays, write a PL/SQL procedure to do the following:
1. Load a PL/SQL array with 100 hundred random values (use the DBMS_RANDOM.RANDOM()
function). Use sequential numbers 1..100 for the index.
2. Display the count of how many elements exist.
3. Display the values of the first and last elements of the array.