Overview · What is PL/SQL · Advantages of PL/SQL · Basic Structure of a PL/SQL Block · Anonymous...

Post on 04-Jan-2016

221 views 1 download

Transcript of Overview · What is PL/SQL · Advantages of PL/SQL · Basic Structure of a PL/SQL Block · Anonymous...

Overview  

·       What is PL/SQL·       Advantages of PL/SQL·       Basic Structure of a PL/SQL Block·       Anonymous Block·       Types of Block·       Declaring a Variable·       Constant·       Variable Initialization·       Select Statement·       Execution Control ·       Cursor·       If Statement·       Basic Loop·       For Loop·       While Loop·       Exception Handling·       Procedure·       Function

What is PL/SQL

Increase the expressiveness of SQL, Process query results in a tuple-oriented way, Optimize combined SQL statements, Develop modular database application

programs, Reuse program code, and Reduce the cost for maintaining and changing

applications. 

Advantages of PL/SQL 

  Can include error handling and control

structures

Can be stored and used by various application programs or users

Allows for tighter security by granting privileges for executing stored procedures rather than granting privileges directly on database object

 

Basic Structure of a PL/SQL Block·       Has three sections:

Declarative sectionExecutable sectionException-handling section

·       Syntax:[DECLARE]BEGIN… SQL & other executable statements[EXCEPTION]END;

Structure of PL-SQL block [<Block header>] [declare

<Constants><Variables><Cursors><User defined exceptions>]

begin<PL/SQL statements/ executable commands>[exception<Exception handling>]

end;

Declarative Section   Identified by the DECLARE keyword Used to define variables and constants referenced in the

block Variable:

o Reserve a temporary storage area in memoryo Manipulated without accessing a physical storage medium

Constant:o Its assigned value can’t be changed during execution

Forward execution:o Variable and constants must be declared before they can

be referenced

Executable Section

  Identified by the BEGIN keyword

o Mandatory

o Can consist of several SQL and/or PL/SQL statements

Used to access & manipulate data within the block

 

Exception-handling Section

Identified by the EXCEPTION keyword Used to display messages or identify other actions

to be taken when an error occurs Addresses errors that occur during a statement’s

execution Examples: No rows returned or divide by zero

errors

Types of Blocks 

·       Anonymous block

·       Procedure

·       Function

  

Anonymous Block

  Not stored since it cannot be referenced by

a name Usually embedded in an application

program, stored in a script file, or manually entered when needed

To perform one-time processing activities

 

Declaring a Variable·   Reserves a temporary storage area in the computer’s memory·   Every variable must have:

A nameA data type

Form is <variable> <data type>

· Variables can be initialized·   Variable name can consist of up to 30 characters, numbers,

or special symbols·   Variable name must begin with a character ·  You can use naming conventions, for example v_name to

represent a variable, and c_name to represent a constant. 

Constants

 

·Variables that have a value that does not

change during the execution of the block

·    Optional CONSTANT keyword can be

used to designate a constant in the block’s

declarative section

Variable Initialization   Use DEFAULT keyword or (:=) assignment

operator Variable must be initialized if it is assigned a

NOT NULL constraint Non-numeric data types must be enclosed in

single quotation marks

 

Variable Initialization Examples

ExampleDeclare

pi constant NUMBER(9,7) := 3.1415927; radius INTEGER(5); area NUMBER(14,2);

begin radius := 3; area := pi*power(radius,2);

insert into AREAS values (radius, area);end;/

• The end; line signals the end of the PL/SQL block;• Depending on the tool you use, you may need to add a slash

(/) to execute the PL/SQL block.

%TYPE & %ROWTYPE%TYPE

Takes the data type from the table

Form is

<variable> <table>.<column>%TYPE

%TYPE & %ROWTYPE %ROWTYPE

Creates a record with fields for each column of the specified

tableDECLARE

row_variable table %ROWTYPE;

BEGIN

SELECT column name1, column name2, …………

INTO row_variable

FROM table nameWHERE column name = variable name; 

The variables are then accessed as: row_variable.column name where column name is the name of a column in the table.

Allows programs to adapt as the database changes

Examplecreate table AREAS(

radius number(7,2),

area number(14,2));

create table RADIUS_VALS(

radius number(7,2));

Example (%TYPE)Declare

pi constant NUMBER(9,7) := 3.1415927; radi areas.radius%type; a areas.area%type ;

begin radi := 4; a := pi*power(radi,2);

insert into AREAS values (radi, a);end;/

PL/SQL procedure successfully completed.

Example (%ROWTYPE )Declare

pi constant NUMBER(9,7) := 3.1415927; a areas%rowtype ;

begin a.radius := 6; a.area := pi*power(a.radius,2);

insert into AREAS values (a.radius, a.area);end;/

SELECT Statement

The SELECT statement may be used in a block ofcode but the following example will return an error:

BEGINSELECT Cust_idFROM Customer;

END;

Correct form is:select <column(s)> into <matching list of variables> from <table(s)>

SELECT Statement

Requires use of INTO clause to identify variableassigned to each data element    Syntax:

SELECT columnname [, columnname, …]INTO variablename [, variablename, …]FROM tablenameWHERE condition;

SELECT Statement Example

DECLARE

S_Cust_id VARCHAR2(12);

S_Cust_name VARCHAR2(12);

S_Cust_dob DATE;

BEGIN

Select Cust_id, Cust_name, Cust_dob

Into S_Cust_id, S_Cust_name, S_Cust_dob

From Customer

Where Cust_id = 'C00000000005';

DBMS_OUTPUT.PUT_LINE('CustomerName:'||

S_Cust_name || 'Customer Date of Birth: ' || S_Cust_dob);

END;

/

Terminal ResponseSET SERVEROUTPUT ON;

DBMS_OUTPUT.PUT_LINE();

Form of argument ('Salary is: ' || salary)

Example: DBMS_OUTPUT.PUT_LINE('Name:‘|| fname);

 

Problem of previous Select It is important to ensure that the select statement

retrieves at most one tuple! Otherwise it is not possible to assign the attribute values

to the specified list of variables and a runtime error occurs.

If the select statement retrieves more than one tuple, a cursor must be used instead.

Furthermore, the data types of the specified variables must match those of the retrieved attribute values.

For most data types, PL/SQL performs an automatic type conversion (e.g., from integer to real).

Cursors

When a query returns multiple rows, defining

a cursor allows us to» process beyond the first row returned

» keep track of which row is currently being processed

Cursors are defined and manipulated using» DECLARE

» OPEN

» FETCH

» CLOSE

Declaring Cursors

Syntax·       Cursor name - similar to a pointer variable·       There is no INTO clause·       Example

CURSOR <cursor name> IS <select-expression>; 

CURSOR emp_cursor ISSELECT employee_id, employee_nameFROM employeeWHERE employee_name LIKE 'E%';

Cursors

Opening a Cursor

Opens a cursor (which must be closed) Gets the query result from the database The rows returned become the cursor's current active set

Sets the cursor to position before the first row. This becomes the current row.

NOTE - You must use the same cursor name if you want data from that cursor.

OPEN <cursor name>;

OPEN emp_cursor;

Fetching A Row

SyntaxMoves the cursor to the next row in the current active set

Assigns values to the host variables

FETCH <cursor name>

INTO <host variables>;

 

FETCH emp_cursor

INTO e_id, e_name;

Closing the Cursor

Closes the cursor (which must be open) There is no longer an active set Reopening the same cursor will reset it to

point to the beginning of the returned table

CLOSE <cursor name>;

CLOSE emp_cursor;

Fetching A Row

CURSOR ExampleDECLARE

CURSOR emp_cursor ISSELECT employee_id, employee_nameFROM employeeWHERE employee_name LIKE 'E%';emp_val emp_cursor%ROWTYPE;

BEGINOPEN emp_cursor;FETCH emp_cursor INTO emp_val;DBMS_OUTPUT.PUT_LINE(emp_val.employee_id);CLOSE emp_cursor;

END;/

Examplecreate table AREAS(

radius number(7,2),

area number(14,2));

create table RADIUS_VALS(

radius number(7,2));

ExampleDeclare

Pi constant NUMBER(9,7) := 3.1415927; area NUMBER(14,2); cursor rad_cursor is select * from

RADIUS_VALS; rad_val rad_cursor%ROWTYPE;

begin open rad_cursor; fetch rad_cursor into rad_val; area := pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); close rad_cursor;

end;/

Explanation When the rad_cursor cursor is opened, the query

declared for that cursor is executed and the records to be returned are identified.

Next, records are fetched from the cursor. In the Declarations section, the rad_val variable is

declared to anchor its datatypes to the rad _cursor cursor.

When you fetch a record from the cursor into the rad_val variable, you can still address each column value selected via the cursor’s query.

When the cursor’s data is no longer needed, you can close the cursor.

ExampleYou can even base %TYPE definitions on

cursors.cursor rad_cursor is

select * from RADIUS_VALS;

rad_val rad_cursor%ROWTYPE;

rad_val_radius rad_val.Radius%TYPE;

In the example, the rad_val variable inherits the datatypes of the result set of the rad_cursor cursor.

The rad_val_radius variable inherits the datatype of the Radius column within the rad_val variable

Cursor Properties

Cursors have four attributes that can be used

In program:

 

–%FOUND, %NOTFOUND : a record can/cannot be fetched from the cursor

–%ISOPEN : the cursor has been opened

–%ROWCOUNT : the number of rows fetched from the cursor so far

Execution Control Decision: IF statement

executes statements based on a condition

Loops: Basic loop

Executes statements until condition in EXIT clause is TRUE

FOR loop

Uses counter

WHILE loop

Executes statements until condition is FALSE

IF Statement Syntax:

IF <condition 1> THEN

<command 1>

ELSIF <condition 2> THEN

<command 2>

ELSE

<command 3>

END IF;

Flow Chart of IF-THEN-ELSE

IF Statement

Basic Loop

Syntax:

LOOP

Statements;

EXIT [WHEN condition];

END LOOP;

 

Flow chart of Loop

Basic Loop

FOR Loop

Syntax:

FOR counter IN [reverse] lower_limit .. upper_limit

LOOP

sequence of statements;

END LOOP;

For Loop The loop counter is declared implicitly. The scope of the loop counter is only the

for loop. It overrides the scope of any variable

having the same name outside the loop. Inside the for loop, counter can be

referenced like a constant. counter may appear in expressions, but

one cannot assign a value to counter.

For Loop

Using the keyword reverse causes the iteration to proceed downwards from the higher bound to the lower bound.

A loop can be named. Naming a loop is useful whenever loops are nested and inner loops are completed unconditionally using the

exit <label name>; statement

Flow Chart of For Loop

FOR Loop

WHILE Loop

Syntax: 

WHILE condition LOOP

Statements;

END LOOP;

Flow Chart of While Loop

WHILE Loop

Simple Loopsdeclare

pi constant NUMBER(9,7) := 3.1415927;

radius INTEGER(5);

area NUMBER(14,2);

begin

radius := 3;

Loop

area := pi*power(radius,2);

insert into AREAS values (radius, area);

radius := radius+1;

exit when area >100;

end loop;

end;

For Loopsdeclare

pi constant NUMBER(9,7) := 3.1415927;

radius INTEGER(5);

area NUMBER(14,2);

begin

/* Specify the criteria for the number of loop executions. */

for radius in 1..7 loop

area := pi*power(radius,2);

insert into AREAS values (radius, area);

/* Signal the end of the loop. */

end loop;

end;

/

For Loopsdeclare

pi constant NUMBER(9,7) := 3.1415927;

radius INTEGER(5);

area NUMBER(14,2);

begin

for radius in reverse 7..1 loop

area := pi*power(radius,2);

insert into AREAS values (radius, area);

end loop;

end;

/

Simple While Loopdeclare

pi constant NUMBER(9,7) := 3.1415927;

radius INTEGER(5);

area NUMBER(14,2);

begin

radius := 3;

while area<100

loop

area := pi*power(radius,2);

DBMS_OUTPUT.PUT_LINE(concat('Radius is:',radius));

DBMS_OUTPUT.PUT_LINE(concat('Areas is:', area));

radius := radius+1;

end loop;

end;

/

Nested Loops

   Any type of loop can be nested inside

another loop Execution of the inner loop must

becompleted before control is returned to the outer loop

 

Nested Loops

Continue

You can use the continue statement within loops to exit the current iteration of the loop and transfer control to the next iteration.

For example, if you iterate through a set of counter values, you can skip specific values without exiting the loop entirely.

The two forms of the continue statement are continue and continue when.

The when portion provides the condition to be evaluated.

If the condition is true, the current iteration of the loop will complete and control will pass to the next iteration.

Continuedeclare

pi constant NUMBER(9,7) := 3.1415927;

radius INTEGER(5);

area NUMBER(14,2);

begin

radius := 1;

loop

if radius < 5 then

continue;

end if;

area := pi*power(radius,2);

insert into AREAS values (radius, area);

radius := radius+1;

exit when area >100;

end loop;

end;

Continue whendeclare

pi constant NUMBER(9,7) := 3.1415927;

radius INTEGER(5);

area NUMBER(14,2);

begin

radius := 1;

loop

continue when radius < 5;

area := pi*power(radius,2);

insert into AREAS values (radius, area);

radius := radius+1;

exit when area >100;

end loop;

end;

Case You can use case statements to control the branching logic

within your PL/SQL blocks. For example, you can use case statements to assign values

conditionally or to transform values prior to inserting them. case CategoryName

when ‘SCIFI' then ‘Science Fiction' when 'ADV' then 'Adventure' when ‘ANIM' then 'Animation '

else CASE_NOT_FOUND end

The keyword case begins the clause. The when clauses are evaluated sequentially. The else keyword within the case clause works similarly to

the else keyword within an if - then clause.

Simple Cursor Loops

You can use the attributes of a cursor—such as whether or not any rows are left to be fetched—as the exit criteria for a loop.

In the following examples, a cursor is executed until no more rows are returned by the query.

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

The associated select statement then is processed and the cursor references the first selected tuple.

Selected tuples then can be processed one tuple at a time using the fetch command

Simple Cursor Loops The fetch command assigns the selected attribute values of the

current tuple to the list of variables. After the fetch command, the cursor advances to the next tuple

in the result set. Note that the variables in the list must have the same data

types as the selected values. After all tuples have been processed, the close command is

used to disable the cursor. Each loop can be completed unconditionally using the exit

clause:

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

Simple Cursor Loops Using exit without a block label causes the completion of the

loop that contains the exit statement The condition refers to a cursor. To determine the status of the

cursor, the cursor’s attributes are checked. Cursors have four attributes you can use in your program:

%FOUND- A record can be fetched from the cursor. %NOTFOUND- No more records can be fetched from the cursor. %ISOPEN - The cursor has been opened. %ROWCOUNT - The number of rows fetched from the cursor so far.

The %FOUND, %NOTFOUND, and %ISOPEN cursor attributes are Booleans; they are set to either TRUE or FALSE.

You can evaluate their settings without explicitly matching them to values of TRUE or FALSE.

Simple Cursor Loops DECLARE

CURSOR emp_cursor IS

SELECT employee_id, employee_name, sal FROM employee

WHERE employee_name LIKE 'E%';

emp_val emp_cursor%ROWTYPE;

emp_sal emp_cursor.sal%TYPE

BEGIN

OPEN emp_cursor;

LOOP

FETCH emp_cursor INTO emp_val;

EXIT WHEN emp_cursor%NOTFOUND;

emp_sal := emp_val.sal;

DBMS_OUTPUT.PUT_LINE(emp_val.employee_id);

END LOOP;

CLOSE emp_cursor;

END;

/

Simple Cursor LoopDeclare

pi constant NUMBER(9,7) := 3.1415927;

area NUMBER(14,2);

cursor rad_cursor is select * from RADIUS_VALS;

rad_val rad_cursor%ROWTYPE;

begin

open rad_cursor;

loop

fetch rad_cursor into rad_val;

exit when rad_cursor%NOTFOUND;

area := pi*power(rad_val.radius,2);

DBMS_OUTPUT.PUT_LINE(concat('Radius is:',rad_val.radius));

DBMS_OUTPUT.PUT_LINE(concat('Areas is:', area));

end loop;

close rad_cursor;

End;

Simple Cursor Loops In the example above, %NOTFOUND is a

predicate that evaluates to false if the most recent fetch command has read a tuple.

The value of <cursor name>%NOTFOUND is null before the first tuple is fetched.

The predicate evaluates to true if the most recent fetch failed to return a tuple, and false otherwise.

%FOUND is the logical opposite of %NOTFOUND.

Cursor FOR Loops • A Cursor FOR loop uses the results of a query

to dynamically determine the number of times the loop is executed.

• In a Cursor FOR loop, the opening, fetching, and closing of cursors is performed implicitly;

• You do not need to explicitly specify these actions.

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

Cursor FOR LoopsDECLARE

CURSOR emp_cursor IS

SELECT employee_id, employee_name, sal

FROM employee

WHERE employee_name LIKE 'E%';

BEGIN

for emp_val in emp_cursor

LOOP

emp_sal := emp_val.sal;

DBMS_OUTPUT.PUT_LINE(emp_val.employee_id);

END LOOP;

END;

/

Fetches the current row to emp_val

Cursor FOR Loops • In a Cursor FOR Loop, there is no open or fetch

command. • A record suitable to store a tuple fetched by the cursor

is implicitly declared. • Note that emp_val is not explicitly declared in the block.• Furthermore, this loop implicitly performs a fetch at

each iteration as well as an open before the loop is entered and a close after the loop is left.

• If at an iteration no tuple has been fetched, the loop is automatically terminated without an exit.

Cursor FOR Loops • The command for emp_val in emp_cursor implicitly

opens the emp_cursor cursor and fetches a value into the emp_val variable.

• When no more records are in the cursor, the loop is exited and the cursor is closed.

• In a Cursor FOR loop, there is no need for a close command. • It is even possible to specify a query instead of <cursor

name> in a for loop:- for sal_rec in (select SAL + COMM total from EMP) loop

- . . . ;- end loop;

Cursor FOR Loops • Except data definition language commands such as

create table, all types of SQL statements: delete, insert, update, and commit can be used in PL/SQL blocks

• Note that in PL/SQL only select statements of the type select <column(s)> into are allowed, i.e., selected attribute values can only be assigned to variables (unless the select statement is used in a subquery).

• The usage of select statements as in SQL leads to a syntax error.

Cursor For Loopdeclare

pi constant NUMBER(9,7) := 3.1415927;

area NUMBER(14,2);

cursor rad_cursor is

select * from RADIUS_VALS;

begin

/* If a record can be fetched from the cursor, then fetch it into the rad_val variable. If no rows can be fetched, then skip the loop. */

for rad_val in rad_cursor

loop

area := pi*power(rad_val.radius,2);

DBMS_OUTPUT.PUT_LINE(concat('Radius is:',rad_val.radius));

DBMS_OUTPUT.PUT_LINE(concat('Areas is:', area));

end loop;

end;

/

Cursor Update If some tuples selected by the cursor will be modified in

the PL/SQL block, the clause for update [(<column(s)>)] has to be added at the end of the cursor declaration.

In this case selected tuples are locked and cannot be accessed by other users until a commit has been issued.

If update or delete statements are used in combination with a cursor, these commands can be restricted to currently fetched tuple.

In these cases the clause where current of<cursor name> is added as shown in the following example.

Cursor Update (Error!) All employees having ’KING’ as their manager get a 5% salary increase. Note that the record emp_rec is implicitly defined. //check below

Declare

manager EMP.MGR%TYPE;

cursor emp_cur (mgr no number) is

select SAL from EMP

where MGR = mgr no

for update of SAL;

Begin

for emp_rec in emp cur(manager) loop

select EMPNO into manager from EMP where ENAME = ’KING’;

update EMP set SAL = emp_rec.sal * 1.05

where current of emp_cur;

end loop;

commit;

end;

Procedure

• Sophisticated business rules and application logic can be stored as procedures within Oracle

• You may group procedures and other PL/SQL commands into packages.

You may experience performance gains when using procedures for two reasons:

The processing of complex business rules may be performed within the database—and therefore by the server.

 Because the procedural code is stored within the database and is fairly static, you may also benefit from the reuse of the same queries within the database

Procedure ·     Also called “Stored Procedures”·     Named block·     Can process several variables·     Returns no values

·     Interacts with application program using IN, OUT, or INOUT parameters

Valid parameters include all data types. However, for char, varchar2, and number no length

and scale, respectively, can be specified. For example, the parameter number (6) results in a

compile error and must be replaced by number

Procedure Basic Syntax CREATE [OR REPLACE] PROCEDURE name

[( argument [IN|OUT|IN OUT] datatype

[{, argument [IN|OUT|IN OUT] datatype }] )]

AS

/* declaration section */

BEGIN

/* executable section - required*/

EXCEPTION

/* error handling statements */

END;

/

Some Details Parameter direction: The optional clauses IN, OUT,

and IN OUT specify the way in which the parameter is used. The default mode is IN» IN (default) : means that the parameter can be referenced inside the procedure body, but it cannot be changed» OUT: means that a value can be assigned to the parameter in the body, but the parameter’s value cannot be referenced. The OUT qualifier signifies that the procedure passes a value back to the caller through this argument» IN OUT: allows both assigning values to the parameter and referencing the parameter.

Some Details IN OUT: A value must be specified for this argument

when the procedure is called, and the procedure will return a value to the caller via this argument

Executing procedures» EXECUTE <name>(<parameters>)» EXECUTE <name>;

A procedure can be deleted using the command

drop procedure <procedure name> drop function <function name>

 

Procedure ExampleCreate Procedure Insert_Customer(customerid IN varchar2)

As

BEGIN

insert into customer

values(customerid,Null, Null, Null, Null);

END;

/

Execute Insert_Customer(‘c_67’);

Function

 ·    Named block that is stored on the Oracle

server

·    Accepts zero or more input parameters

·    Returns one value

 

Function Basic SyntaxCREATE [OR REPLACE] FUNCTION name

[( argument datatype

[{, argument datatype}] )]

RETURN datatype

AS

/* declaration section */

BEGIN

/* executable section - required*/

EXCEPTION

/* error handling statements */

END;

/

Function ExampleCREATE OR REPLACE FUNCTION getBDate (customerid VARCHAR2)RETURN DATEAS

v_bdate customer.cust_dob%TYPE;BEGIN

SELECT cust_dob INTO v_bdateFROM customerWHERE cust_id = customerid;RETURN v_bdate;

END;/

select getBDate('C00000000005')) from dual;

Function Example

CREATE OR REPLACE

PROCEDURE show_date(c_id VARCHAR2)

AS

BEGIN

DBMS_OUTPUT.PUT_LINE(getBDate(c_id));

END;

/

Execute show_date('C00000000005');

Exception Handling

A PL/SQL block may contain statements that specify Exception handling routines.

Each error or warning during the execution of a PL/SQL block raises an exception.

One can distinguish between two types of exceptions:

·       system defined exceptions

·       user defined exceptions

System Defined Exceptions

System defined exceptions are always automatically raised

whenever corresponding errors or warnings occur.

User Defined Exceptions

User defined exceptions, in contrast, must be raised explicitly

in a sequence of statements using raise <exception name>.

After the keyword exception at the end of a block, user defined

exception handling routines are implemented.

An implementation has the pattern

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

Exception Handlingdeclare pi constant NUMBER(9,7) := 3.1415927; radius INTEGER(5); area NUMBER(14,2); some_variable NUMBER(14,2);begin radius := 3; loop some_variable := 1/(radius-4); area := pi*power(radius,2); insert into AREAS values (radius,

area); radius := radius+1; exit when area >100; end loop; end;

User Defined Exceptions • Because the calculation for some_variable involves division, you may

encounter a situation in which the calculation attempts to divide by zero—an error condition

• The second time through the loop, the radius variable has a value of 4—and the calculation for some_variable encounters an error:

• ERROR at line 1:• ORA-01476: divisor is equal to zero• ORA-06512: at line 9

• Because an error was encountered, the first row inserted into AREAS is rolled back, and the PL/SQL block terminates.

• You can modify the processing of the error condition by adding an Exception Handling section to the PL/SQL block, as shown next

Exception Handlingdeclare pi constant NUMBER(9,7) := 3.1415927; radius INTEGER(5); area NUMBER(14,2); some_variable NUMBER(14,2);begin radius := 3; loop some_variable := 1/(radius-4); area := pi*power(radius,2); insert into AREAS values (radius, area); radius := radius+1; exit when area >100; end loop; exception when ZERO_DIVIDE

then insert into AREAS values (0,0); end;

Exception Handlingdeclare

emp_sal NUMBER(10,3);

Emp_no VARCHAR2(12);

too_high_sal exception;

begin

select EMPLOYEE_ID, SALARY into emp_no, emp_sal

from EMPLOYEE where EMPLOYEE_NAME = ’E_Y’;

if emp_sal * 1.05 > 2000 then raise too_high_sal;

end if;

exception

when NO_DATA_FOUND

then DBMS_OUTPUT.PUT_LINE(‘No data found’);

when too_high_sal then DBMS_OUTPUT.PUT_LINE(‘High Salary’);

end;

/

Exception Handling• When the PL/SQL block encounters an error, it scans the

Exception Handling section for the defined exceptions.

• After the keyword when a list of exception names, connected with or can be specified.

• In addition to the system-defined exceptions and user defined exceptions, you can use the when others clause to address all exceptions not defined within your Exception Handling section.

• This introduces the default exception handling routine, for example, a rollback.

Exception HandlingIt is also possible to use procedure raise_application_error.

This procedure has two parameters

<error number> and <message text>.

<error number> is a negative integer defined by the user and must range between -20000 and -20999.

<error message> is a string with a length up to 2048 characters.

If the procedure raise application error called from a PL/SQL block, processing the PL/SQL block terminates and all database modifications are undone, that is, an implicit rollback is performed in addition to displaying the error message.

Exception Handlingdeclare

emp_sal NUMBER(10,3);

Emp_no VARCHAR2(12);

begin

select EMPLOYEE_ID, SALARY into emp_no, emp_sal

from EMPLOYEE where EMPLOYEE_NAME = ’E_Y’;

if emp_sal * 1.05 > 2000

then raise_application_error(-20010, ’Salary is too high for ’ || to_char(Emp no) );

end if;

end;

/

Exception Handling• The concatenation operator “||” can be used to concatenate

single strings to one string. • In order to display numeric variables, these variables must

be converted to strings using the function to_char. • Once an exception is encountered, you cannot return to your

normal flow of command processing within the Executable Commands section.

• If you need to maintain control within the Executable Commands section, you should use if conditions to test for possible exceptions before they are encountered by the program, or create a nested block with its own local exception handling.

Compilation Errors

 

Loading a procedure or function may cause compilation errors.

    SHOW ERRORS; gives the errors

    To get rid of procedures or functions:

DROP PROCEDURE <name>;

DROP FUNCTION <name>;

 

Debugging PL/SQL

• The SQL*Plus show errors command displays all the errors associated with the most recently created procedural object.

• This command checks the USER_ERRORS data dictionary view for the errors associated with the most recent compilation attempt for that object.

• Show errors displays the line and column number for

each error, as well as the text of the error message. • To view errors associated with previously created

procedural objects, you may query USER_ERRORS directly

Debugging PL/SQL• If any errors were encountered during the creation of

the OVERDUE_CHARGES function , the lines in the code that resulted in the error conditions would be returned by the query.

select Line, /*Line number of the error. */Position, /*Column number of the error.*/Text /*Text of the error message.*/from USER_ERRORS where Name = 'OVERDUE_CHARGES' and Type = 'FUNCTION'order by Sequence;

• Valid values for the Type column are VIEW, PROCEDURE, PACKAGE, FUNCTION, and PACKAGE BODY

Debugging PL/SQL

• In addition to the debugging information provided by the show errors command, you may use the DBMS_OUTPUT package,

• It is automatically installed when you create an Oracle database

PUT Puts multiple outputs on the same linePUT_LINE Puts each output on a separate lineNEW_LINE Used with PUT; signals the end of the current output

line

• To track the variable’s value, you may use a command similar to the one shown

DBMS_OUTPUT.PUT_LINE ('Owed:'||Owed_Amount);

Viewing Source Code of Procedure

The source code for existing procedures, functions, packages, and package bodies can be queried from the following data dictionary views:

○ USER_SOURCE For procedural objects owned by the user○ ALL_SOURCE For procedural objects owned by the user or

to which the user has been granted access○ DBA_SOURCE For all procedural objects in the database

Select information from the USER_SOURCE view via a query

select Text

from USER_SOURCE

where Name = 'NEW_BOOK'

and Type = 'PROCEDURE'

order by Line;

Output of above query is:TEXT-----------------------------------------------------------------procedure NEW_BOOK (aTitle IN VARCHAR2, aPublisher IN VARCHAR2, aCategoryName IN VARCHAR2)asbegin insert into BOOKSHELF (Title, Publisher, CategoryName, Rating) values (aTitle, aPublisher, aCategoryName, NULL); delete from BOOK_ORDER where Title = aTitle;end;○ the USER_SOURCE view contains one record for each line of the

NEW_BOOK procedure so should be ordered by with Line.

Compiling PL/SQL• Oracle compiles procedural objects when they are created. • Procedural objects may become invalid if the database

objects they reference change. • The next time the procedural objects are executed, they

will be recompiled by the database. • You can avoid this run-time compiling—and the

performance degradation it may cause—by explicitly recompiling the procedures, functions, and packages.

• To recompile a procedure, use the alter procedure command, as shown in the following listing.

• The compile clause is the only valid option for this command.

• Alter function/procedure OVERDUE_CHARGES compile;

Packages It is essential for a good programming style that logically

related blocks, procedures, and functions are combined into modules

Each module then provides an interface which allows users and designers to utilize the implemented functionality.

PL/SQL supports the concept of modularization by which modules and other constructs can be organized into packages.

A package consists of a package specification and a package body.

The package specification defines the interface that is visible for application programmers, and the package body implements the package specification

Packages When creating packages, the package

specification and the package body are created separately.

Thus, there are two commands to use: create package for the package specification, and create package body for the package body.

Both of these commands require that you have the CREATE PROCEDURE system privilege.

If the package is to be created in a schema other than your own, then you must have the CREATE ANY PROCEDURE system privilege

Packages Here is the syntax for creating package specifications:

create [or replace] package [ user. ] package[authid {definer | current_user} ]{is | as} package specification ;

A package specification consists of the list of functions, procedures, variables, constants, cursors, and exceptions that will be available to users of the package.

A package body contains the blocks and specifications for all of the public objects listed in the package specification.

The package body may include objects that are not listed in the package specification; such objects are said to be private and are not available to users of the package.

Private objects may only be called by other objects within the same package body.

Packages A procedure or function implemented in a package can

be called from other procedures and functions using the statement <package name>.<procedure name>[(<list of parameters>)].

Additional functions, procedures, exceptions, variables, cursors, and constants may be defined within the package body,

but they will not be available to the public unless they have been declared within the package specification (via the create package command).

execute BOOK_INVENTORY.NEW_BOOK('ONCE REMOVED');

Packages If a user has been granted the EXECUTE

privilege on a package, then that user can access any of the public objects that are declared in the package specification.

Packages are groups of procedures, functions, variables, and SQL statements grouped together into a single unit.

To execute a procedure within a package, you must first list the package name, and then list the procedure name, as shown previously Execute BOOK_INVENTORY.NEW_BOOK('ONCE REMOVED');

Packages Packages allow multiple procedures to use the same

variables and cursors. Procedures within packages may be either available to

the public (as is the NEW_BOOK procedure in the prior example) or private, in which case they are only accessible via commands from within the package (such as calls from other procedures).

Packages may also include commands that are to be executed each time the package is called, regardless of the procedure or function called within the package.

Thus, packages not only group procedures but also give you the ability to execute commands that are not procedure specific.

Packages Oracle offers several predefined packages and

procedures that can be used by database users and application developers.

A set of very useful procedures is implemented in the package DBMS_OUTPUT.

Procedure DBMS_OUTPUT.ENABLE DBMS_OUTPUT.DISABLE DBMS_OUTPUT.PUT(<string>) DBMS_OUTPUT.PUT LINE(<string>) DBMS_OUTPUT.NEW

 

THANK YOU