0% found this document useful (0 votes)
10 views

Total_plsql[1]

PL/SQL is an extension of SQL that incorporates programming structures and subroutines, allowing for both server-side and client-side development. It features a block structure for code organization, supports various data types, and includes control structures for branching and looping. PL/SQL also provides robust error handling through exceptions, enabling developers to manage errors effectively in their applications.

Uploaded by

Sumit Tomar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Total_plsql[1]

PL/SQL is an extension of SQL that incorporates programming structures and subroutines, allowing for both server-side and client-side development. It features a block structure for code organization, supports various data types, and includes control structures for branching and looping. PL/SQL also provides robust error handling through exceptions, enabling developers to manage errors effectively in their applications.

Uploaded by

Sumit Tomar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 40

PL/SQL

Procedural language extensions to SQL(PL/SQL)


1) PL/SQL extends sql by adding programming structures and subroutines available in any high level
language.
2) PL/SQL can be used for both server side and client side development.
3) PL/SQL has syntax and rules that determine how programming statements work together.
4) Any PL/SQL block or subroutine is processed by PL/SQL engine.
5) The sql stmt processor is always located on the oracle server and hence all the sql stmts are
processed on server only.
Advantages:
1) Completely portable.
2) Support for sql and Support for object oriented programming.
3) Higher productivity, high performance and tight security.
4) Tight integration with oracle products.
PL/SQL Programming Tool:
Oracle SQL Developer is a graphical tool that can be used to write PL/SQL code.
Block Structure Approach:
 PL/SQL defines a block structure for writing executable units of code. Maintaining and debugging
the code is easier with such a well-defined structure. You can easily understand the flow and
execution of the program unit.
 Basic parts of PL/SQL block are
 Declarative part (optional) (Memory management): Used to define user defined types, variables
and similar items.
 Executable Part (mandatory) (logical): contains operational code for program. Items in
declarative part are manipulated here.
 Exceptional handling part (optional) (Runtime Intelligence): any exceptions that are raised
during the program execution are handled here.

PL/SQL block:
 Simple PL/SQL block:  Nested PL/SQL block:
Declare Declare
Variable declarations, Variable declarations,
Cursor declarations, Cursor declarations,
User defined exceptions User defined exceptions
Begin Begin
Sql statements Declare
Pl/sql statements Variable declarations,
Exception Cursor declarations,
End; User defined exceptions
Begin
Sql statements
Pl/sql statements
Exception
End;
Exception
End;
 PL/SQL Block Types:
Block name Description:
Anonymous Anonymous blocks are unnamed blocks. They are declared inline at the point in an
Blocks Application where they are to be executed and are compiled each time the application
is executed. These blocks are not stored in the database. They are passed to the PL/SQL
engine for execution at runtime.
Named All the features as specified by the anonymous block. But it contains a name called a
Blocks header. It’s not reusable and not permanent. They give the specifications of the named
spaces. These blocks are convenience for variable management. These blocks make
pl/sql more clear and readable.
Sub Subprograms are complementary to anonymous blocks. They are named pl/sql blocks
programmed that are stored in the database. Because they are named and stored, you can invoke
Blocks them whenever you want, depending on your application. You can declare them either
as procedures or as functions.

PL/SQL Variables
 With pl/sql, you can declare variables and then use them in sql and procedural statements. Variables
are mainly used for storage of data and manipulation of stored values.
 Variables are used to store values temporarily. You can use the values stored in these variables for
processing and manipulating data. Variables can store any PL/SQL object, such as variables, types,
cursors and subprograms.
 Reusability is another advantage of declaring variables. After the variables are declared, you can use
them repeatedly in an application by referring to them multiple times in various statements.
 Variable name declaration have following requirements.
o must start with a letter
o can include letters or numbers
o can include special characters - such as $,_ and #
o must not contain more than 30 characters and not include reserved words
 You can use variables in various ways:
o declare and initialize variables in the declaration section
o use variables and assign new values to them in executable section
o pass variables as parameters to pl/sql subprograms
o use variables to hold the output of a pl/sql subprogram
 You must declare all pl/sql identifiers in the declaration section before
Referencing them in the pl/sql block.
Syntax: identifier [CONSTANT] datatype [NOT NULL] [:=|DEFAULT expr];
Identifier: it is the name of the variable.
Constant: it constrains the variable so that its value cannot change. Constants must be initialized.
Specify it is a scalar, composite, reference or LOB data type.
Not null: it constrains the variable so that it must contain a value. Not null values must be initialized.
Expr: It is any pl/sql expression that can be a literal expression, another variable, or an expression
involving operators and functions.
 Declare
v_hiredates DATE;
v_deptno NUMBER(2) NOT NULL := 10;
V_location VARCHAR2(13) := 'Atlanta';
c_comm Constant Number := 1400;
 PL/sql supports these four data type categories, which you can use these data types declare
variables, constants, and pointers:
Scalar These datatypes hold a single value. All datatypes other than object oriented data
types.
Composite Exactly equivalent structures in C language. They contain internal elements that
are either scalar or composite.
Reference These hold values, called pointers, which point to a storage location.
LOB These hold values, called locators, which specify the location of large objects - such
as graphics images - that are stored outside the table.

 Guidelines for declaring and initializing PL/SQL variables.


o follow naming conventions
o use meaningful and appropriate identifiers for variables
o the constant keyword must precede the type specified
o initialize the variable to an expression
o qualify objects with the same name with labels
o do not use column names as identifiers
o impose the not null constraint
Comments in PL/SQL:
1) -- => single line comment
2) /* multiple line comment */
Assigning values to the variables:
1. By using assignment operator (:=)
2. By selecting or fetching database values using INTO clause.
Select ename into v_ename
3. By passing it as an OUT or INOUT parameter to a subprogram.
Presenting data on the screen:
1. For producing the output on the screen we need assistance of DBMS_OUTPUT package. This
package enables us to display output from pl/sql blocks and subprograms.
2. The procedure put_line outputs information to a buffer in the SGA.
3. DBMS_OUTPUT.PUT_LINE(‘Message’);
PL/SQL variable properties:
References to variables are resolved according to these properties.
1. Scope:
 It is a primary component which tells whether the identifier is in usage or not.
 Once the scope of the variable is lost, it means that the life of the variable is no more.
 All variables loose there scope as soon as the pl/sql block ends or terminates.
2. Visiblilty:
 It is a region from which we can reference the identifier using an unqualified name.
PL/SQL Control Structures:
 Control structures are the most important pl/sql extensions to sql.
 To write programs that reflect the real requirements, we need branching, selection & looping.
 Branching statements:
Simple IF: IF condition1 Then IF monthly_value <= 4000 THEN
Statements ILevel := 'Low Income';
End IF; End IF;
Else….IF: IF condition1 Then IF monthly_value <= 4000 THEN
Statements ILevel := 'Low Income';
ELSE ELSE
Statements ILevel := 'High Income';
End IF; End IF;
ELSIF….: IF condition1 Then IF monthly_value <= 4000 THEN
Statements ILevel := 'Low Income';
ELSIF condition2 Then ELSIF monthly_value > 4000 and monthly_value
Statments <= 7000 THEN
ELSIF condition3 Then ILevel := 'Avg Income';
Statments ELSE
ELSE ILevel := 'High Income';
Statements END IF;
End IF;

 Unconditional Branching:
o “GOTO” provides the ability to jump through a program from one place to another.
o Goto can be used with complex Exception Handlers in nested blocks, to make the execution
section more readable.
o It is better to have limited usage of ‘Goto’ in programming block.
 Goto label_name:
o “EXIT” statement is most commonly used to terminate LOOP statements
 Exit [WHEN Boolean_condition];
 Iterations:
Simple Loop: LOOP LOOP
{.statements.} monthly_value := daily_value * 31;
EXIT WHEN EXIT WHEN monthly_value > 4000;
boolean_condition; END LOOP;
END LOOP;
While Loop: WHILE condition WHILE monthly_value <= 4000
LOOP LOOP
{.statements.} monthly_value := daily_value * 31;
END LOOP; END LOOP;
For Loop: FOR loop_counter IN [REVERSE] FOR Lcntr IN 1..20
lowest_number..highest_number LOOP
LOOP LCalc := Lcntr * 31;
{.statements.} END LOOP;
END LOOP; --------------------------------------------------------------
FOR Lcntr IN REVERSE 1..15
LOOP
LCalc := Lcntr * 31;
END LOOP;

 You use a simple loop when you don’t know how many times you need to loop.
 You would use a WHILE Loop when you are not sure how many times you will execute the loop
body. Since the WHILE condition is evaluated before entering the loop, it is possible that the loop
body may not execute even once.
 You would use a FOR Loop when you want to execute the loop body a fixed number of times.
 The variable used in the for loop need not be initialized or declared. By default for loop increments
by one. For loop is used only for numbers.
 Nested for loops are, for loop inside a for loop.

Attribute Data Types:


 Two types of attribute datatypes: %type and %rowtype
 When there is a frequent change in the data types of the columns in the table use attribute data
types. Attribute data types takes the data types of columns in a table and assign them to pl/sql
variables.
1) %type: This is used when you are specifying a single column data type.
P_name varchar2(10); //This is declaring datatype directly
P_name emp.ename%type;
2) %rowtype: This is used when multiple column datatypes are specified in a single pl/sql variable.
P_emp emp%rowtype;

Exceptions:
 An exception is a pl/sql error that is raised during the execution of a code block. A pl/sql block
always terminates when an exception is raised, but you can define an exception handler in the
optional EXCEPTION section of the block.
 The exception handler is pl/sql code that specifies some action to take before the block ends.
 Typically exceptions are raised as a result of the following:
o An error generated by the system such as an “out of memory” or “duplicate value” error
o A user action error
o A warning from the application to the user
 In oracle, pl/sql exceptions can be grouped into three distinct categories:
o Predefined oracle server exceptions
o Non predefined oracle server exceptions
o User defined exceptions
 An exception can either be raised implicitly by the oracle server or explicitly by the program. An
exception is raised implicitly, or automatically, by the oracle server when an oracle error occurs. You
do not have to create any code to raise such exceptions.
 A predefined oracle server exception may be raised implicitly, but you do not need to declare it. A
non predefined oracle server exception can also be raised implicitly, but must be declared within the
declarative section.
 Depending on the business functionality your program is implementing, you may have to explicitly
raise an exception by issuing the RAISE statement within the pl/sql block. All user defined exceptions
must be raised explicitly.
 Any exception, raised implicitly or explicitly, can be handled
o By trapping it with a handler
 Pl/sql exceptions can be trapped and responded to using an exception handler, as defined in the
Exception section of a pl/sql block. If the exception is raised in the executable section of the
block, processing moves to the exception handler in the Exception section of the block, and the
pl/sql block terminates successfully.
o By propagatin it to the calling environment
 If an exception is raised and there is no corresponding exception handler, the pl/sql block
terminates with failure and the exception is propagated to the calling environment that is
invoking the pl/sql program.
 The exception handler mechanism allows you to cleanly separate your error processing code from
your executable statements. It also implements an event driven model, as opposed to a linear code
model, for error processing in pl/sql. A specific exception is raised in some way and it is handled by
the same exception handler.
Code structure for trapping exceptions:
 Each handler consist of WHEN clause, which specifies an exception name, followed by a sequence of
statements to be executed when that exception is raised. You can include any number of handlers
within an exception section to handle specific exceptions.
Exception Exception
When exception1 Then When no_data_found Then
Statement1; Statement1;
When excpetion2 Then When too_many_rows Then
Statement2; Statement2;
When Others Then When OTHERS Then
Statement3; Statement3;

 The terms exception1 and exception2, refer to the standard name of a predefined exception or the
name of a user defined exception declared within the declarative section.
 The terms statment1,2 refer to standard pl/sql or sql statements.
 The others clause is an optional exception handling clause that traps any exceptions that have not
been explicitly handled.
 Any exceptions not specified in the Exception section are not trapped unless you use the Others
exception handler, which, if it is used, must be the last exception handler that is defined.
 Some of the predefined exception names include:
Access_Into_null Cursor_already_open Program_error
Too_many_rows Zero_divide Case_not_found
Invalid_cursor No_data_found Not_logged_on
Trapping non predefined exceptions in pl/sql:
 To trap non predefined oracle error, u must declare first. The declared exception is raised implicitly.
 In pl/sql, the PRAGMA EXCEPTION_INIT clause tells the compiler to associate an exception name
with an oracle error number. This allows you to refer to any internal exception by name and to write
a specific handler for it.
 In common with many other programming languages, PRAGMA in PL/SQL is a keyword that signifies
a compiler directive, which is not processed as a pl/sql block is executed. Rather, it directs the
compiler to associate all instances of the exception name you provide with a specific oracle server
exception number.
 This is the syntax for declaring, associating and referencing a non predefined oracle server exception
in a pl/sql block.
Declare Declare
Exception1 EXCEPTION; Insert_excep Exception;
Pragma Exception_Init Pragma Exception_init
(exception1, -oracle_err_no) (insert_excep, -01400);
Begin Begin
……… Insert into dept(dept_id, dept_name) values (280, null);
Exeption Exception
When exception1 Then When insert_excep Then
Statement1; Dbms_output.put_line(‘Insert Operation Failed’);
End; End;

 You declare the name of the exception in the declarative section by specifying an identifier for the
exception followed by the Exception keyword.
 After declaring an exception, you must associate it with a specific oracle server error number using
the program exception_init function. The arguments to this function are the exception name
followed by a valid oracle error number, which is always negative
 The declared exception can be referenced in the Exception section using the same syntax as for
predefined oracle exceptions. So statement1 will only be executed if the error with the number
oracle_err_no occurs.
 In the above example, you decide to display an error message, giving details of the error, and
complete this SQL block. When you execute this block, the error -01400 occurs and is converted to
the exception you declared(insert_excep), which is trapped by the corresponding exception handler,
causing the error message to be displayed.
Handling User defined exceptions:
 A user defined exception is an error that is defined by the programmer. It need not be an oracle
error – it could be a data error, for example. Many problems that users encounter while using an
application are specific to that application. Defining exceptions enables you to give names to
otherwise anonymous system errors and specify how they should be handled.
 Suppose you want users of an application to update department names in the Departments table.
You want the user to supply the department number and the new name. You decide to define an
exception to deal with error conditions in the input data. If the department number supplied by the
user doesn’t exist, you want to raise a user defined exception.
Declare
Invalid_departement EXCEPTION;
Name varchar2(20) := ‘&name’;
Deptno Number := &deptno;
Begin
Update departments set department_name = name where department_id = deptno;
If sql%notfound then
Raise invalid_department;
End IF;
Commit;
Exception
When invalid_department Then
Dbms_output.put_line(‘No such department id.’);
End;
 You use the RAISE statement to raise the exception explicitly within the executable section of the
block. Once the exception is raised, control passes immediately to the Exception section of the block
so any code following the Raise statement is not executed. In this case, the exception is raised if the
department ID entered by the user does not exist.
 You can use the When Others clause in the Exception section of a pl/sql block to trap unhandled
exceptions. Two functions can be included in the clause to determine the error code and error
message associated with the exception.
 The two functions are
o SQLCODE: You use the sqlcode function to return the oracle error number for internal
exceptions. You can assign it to a NUMBER variable.
o SQLERRM: You use the sqlerrm function to return the message associated with the oracle
error number. It returns character data.
Handling exceptions in Nested Blocks:
 You can use nested blocks, or subblocks, to handle exceptions in Pl/sql. When an exception is
handled in a subblock, the block terminates normally and control passes back to the enclosing block
following the subblocks END statement.
 This functionality means that you can enclose statements requiring exclusive error handling inside
their own block. In addition, by handling exceptions within subblokcs, you ensure that any remaining
executable actions in the enclosing block can still execute.
Declare Declare
Qty_on_hand Number; Qty_on_hand Number;
Begin Begin
Select quantity_on_hand into qty_on_hand Begin
From inventories where product_id = 100; Select quantity_on_hand into qty_on_hand
Update product _information set product_status From inventories where product_id = 100;
= decode(qty_on_hanbd, 0, 0, product_status) Exception
Where product_id = 100; When no_data_found Then
Exception Qty_on_hand := 1;
When no_data_found Then End;
Null; Update product _information set product_status
End; = decode(qty_on_hanbd, 0, 0, product_status)
Where product_id = 100;
Exception
When no_data_found Then
Null;
End;

 In this example, if the select statement retrieves no rows, pl/sql raises an exception, which is dealt
with in the exception section of the block. The update command in the executable section is
bypassed because, once the exception is raised, control passes immediately to the Exception section
of the block.
 In the second you enclose the select statement in a subblock with its own exception section. In this
case, if the select statement returns no rows, the update command will still execute because the
exception is handled in the exception section of the subblock.
Raise_application_error procedure:
 You use the raise_application_error procedure to raise application specific errors in your application.
The procedure allows you to communicate a predefined exception interactively by returning a
nonstandard error code and error message.
 One advantage of using raise_application_error instead of raise – which can also be used to raise an
application specific, explicitly declared exception is that you can create and associate an error
message with the raised exception.
 When an application calls a raise_application_error procedure from an executing stored
subprogram, raise_application_error ends the subprogram and returns the error number and
message that you’ve specified to the application. The error number and message can be trapped like
any oracle error.
Syntax: raise_appliation_error(error_number, message[,{True | False}]);
 In the syntax for the procedure, you follow raise_application_error with the error number and error
message. The error number that you specify for the exception must be between -20999 to -
20000.The message you supply must be a character string of up to 2048 bytes long.
 You can also optionally specify a Boolean parameter to indicate whether you want to add the error
to any already on the stackt (TRUE) or replace the existing errors(False, the default).

Cursors:
 You can include sql statements that return a single row in a pl/sql block. The data retrieved by the
sql statement should be held in variables using the INTO clause.
 The oracle sever allocates a private memory area called the context area for processing sql
statements. The sql statement is parsed and processed in this area. Information required for
processing and information retrieved after processing are all stored in this area. You have no control
over this area because it is internally managed by the oracle server.
 A cursor is a pointer to the context area. In other words, it is a pointer to the private memory area
allocated by the oracle server.
 A cursor is used to handle the result set of a select statement. However, this cursor is an implicit
cursor and is automatically managed by the oracle server.
 When the executable block issues a sql statement, pl/sql creates an implicit cursor.
 There are two types of cursors:
o Implicit: An implicit cursor is created and managed by the oracle server. You do not have
access to it. The oracle server creates this cursor when it has to execute a sql statement.
o Explicit: A cursor that is declared by programmers is called an explicit cursor. As a
programmer, you may want to retrieve multiple rows from a database table, have a pointer
to each row that is retrieved, and work on the rows one at a time. In such cases, you can
declare cursors explicitly depending on your business requirements. You declare an explicit
cursor in the declarative section of a pl/sql block.
Implicit Cursors:
 Sql cursor attributes enable you to evaluate what happened when an implicit cursor was last used.
You can use these attributes in pl/sql statements but not in sql statements.
 You can test the sql%rowcount, sql%found, sql%notfound and sql%isopen attributes in the
executable section of a block to gather information after the appropriate DML command executes.
 Pl/sql does not return an error if a dml statement does not affect rows in the underlying table.
However, if a select statement does not retrieve any rows, pl/sql returns an exception.
 All the attributes are prefixed with sql. These cursor attributes are used with implicit cursors that are
automatically created by pl/sql for which you do not know the names. Therefore, you use sql instead
of the cursor name.
 The sql%notfound attribute is opposite to sql%found. This attribute may be used as the exit
condition in a loop. It is useful in Update and delete statements when no rows are changed because
exceptions are not returned in these cases.
 Sql%found is a Boolean attribute that evaluates to True if the most recent sql statement returned at
least one row.
 Sql%notfound is a Boolean attribute that evaluates to True if the most recent sql statement did not
return even one row.
 Sql%rowcount is an integer value that represents the number of rows affected by the most recent
sql statement.
 Sql%isopen is an Boolean attribute that evaluates to True if the cursor is open. For implicit cursor
this attribute is always false.
Explicit Cursors:
 The oracle server uses work areas, called private sql areas, to execute sql statements and store
processing information. You can use explicit cursors to name a private sql area and to access its
stored information.
 You declare explicit cursors in pl/sql when you have a select statement that returns multiple rows.
You can process each row returned by the select statement.
 The set of rows returned by a multiple row query is called the active set. Its size is the number of
rows that meet your search criteria. Here an explicit cursor points to the current row in the active
set. This enables a program to process the rows one at a time.
 These are the functions performed by an explicit cursor:
o It can perform row by row processing beyond the first row returned by a query.
o It keeps track of the row that is currently being processed.
o It enables the programmer to manually control explicit cursors in the pl/sql block.
 The steps for using an explicit cursor are
o Defining the structure of the query: The first step is to define the structure of the query. In
the declarative section of a pl/sql block, you declare the cursor by naming it and defining the
structure of the query to be associated with it.
Cursor <cursorname> is <select statement>
o Opening the cursor: After declaring the cursor, you need to open the cursor to identify the
active set of rows. The OPEN statement executes the query and binds any variables that are
references. Rows identified by the query are called the active set and are available for
fetching.
Open <cursorname>
o Fetching data from the cursor: The third step involves fetching data from the cursor. After
each fetch, you test the cursor for any existing row. If there are no more rows to process,
you must close the cursor.
Fetch <cursorname> into <variable>;
o Closing the cursor: The fourth step involves closing the cursor. The close statement releases
the active set of rows. You can reopen the cursor to establish a fresh active set.
Close <cursorname>
 A pl/sql program opens a cursor, processes rows returned by a query, and then closes the cursor.
The cursor marks the current position in the active set.
 You perform these steps to control explicit cursors in a pl/sql program:
o Open: The open statement executes the query associated with the cursor, identifies the
active set, and positions the cursor at the first row. The open statement is included in the
executable section of the pl/sql block.
o Fetch: The fetch statement retrieves the current row and advances the cursor to the next
row until there are no more rows or a specified condition is met.
o Close: The close statement releases the cursor.
 In the syntax to declare a cursor, cursor_name is the pl/sql identifier, and the select_statement is
used to identify the select statement without an into clause.
CURSOR cursor_name IS select statement;
 The active set of a cursor is determined by the select statement in the cursor declaration. It is
mandatory to have an INTO clause for a select statement in pl/sql. However the select statement in
the cursor declaration cannot have an Into clause. This is because you are only defining a cursor in
the declarative section and not retrieving any rows into the cursor.
 You need to consider these guide lines while declaring a cursor:
o Do not include the INTO clause in the cursor declaration because it appears later in the fetch
statement.
o If processing rows in a specific sequence is required, use the order by clause in the query.
o The cursor can be any valid select statement, including joins, sub queries and so on.
DECLARE
Cursor c_emp_cursor IS
Select employee_id, last_name From employees where dept_id = 30;
Begin
Open c_emp_cursor;
Loop
Fetch c_emp_cursor into empno, lnae;
Exit when c_emp_cursor%notfound;
Dbms_output.put_line(v_empno || ‘ ‘ || v_lname);
End loop;
Close c_emp_cursor;
End;

……..
 Open is an executable statement that performs these operations:
o It dynamically allocates memory for a context area.
o It parses the select statement
o It binds the input variables and sets the values for the input variables by obtaining their
memory addresses
o It identifies the active set – the set of rows that satisfy the search criteria – rows in the
active set are not retrieved into variables when the open statement is executed, the fetch
statement retrieves the rows from the cursor to the variables.
o It positions the pointer to the first row in the active set.
 The fetch statement retrieves the rows from the cursor one at a time. After each fetch, the cursor
advances to the next row in the active set. You can use the %notfound attribute to determine
whether the entire active set has been retrieved.
 The fetch statement performs these operations:
o It reads the data for the current row into the output pl/sql variables
o It advances the pointer to the next row in the active set
 The close statement disables the cursor, releases the context area, and undefined the active set. You
should close the cursor after completing the fetch statement processing. You can reopen the cursor
if required. A cursor can be reopened only if it is close. If you attempt to fetch data from a cursor
after it is been closed, then an Invalid cursor exception is raised.
 Although it is possible to terminate the pl/sql block without closing cursors, you should ensure to
close any cursor that you declare explicitly to free up resources. There is a maximum limit on the
number of open cursors per session, which is determined by the open_cursors parameter in the
database parameter file – open_cursors = 50 by default.
 You can define record that have the structure of columns in a table by using %rowtype. You can also
define a record based on the selected list of columns in an explicit cursor. This is convenient for
processing the rows of the active set, because you can simply fetch into the record. Therefore, the
values of the row are loaded directly into the corresponding fields of the record.
 You can fetch data from cursors by using a simple loop, however, you can also use the cursor FOR
loop to process rows in an explicit cursor. It is a shortcut because the cursor is opened, a row is
fetched once for each iteration in the loop, the loop exits when the last row is processed, and the
cursor is closed automatically. The loop itself is terminated automatically at the end of the iteration
where the last row is fetched. In the cursor for loop, the record is implicitly declared.
 Syntax:
FOR record_name IN cursor_name LOOP
Statement1;
…………….
END LOOP;
 In the syntax for declaring a cursor FOR loop, record_name is the name of the implicitly declared
record and the cursor_name is the pl/sql identifier for the previously declared cursor.
 You need to consider these guidelines for declaring a cursor for loop:
o Do not declare the record that controls the loop; it is declared implicitly
o Test the cursor attributes during the loop, if required
o Supply the parameters for a cursor, if required, in parenthesis following the cursor name in
the for statement.
 For loop cursor:
Declare
Cursor c_emp_cursor is
Select employee_id, last_name from employees where department_id = 30;
Begin
For emp_record IN c_emp_cursor LOOP
Dbms_output.put_line(emp_record.employee_id || ‘ ‘ || emp_record.last_name);
END LOOP;
END;
 The above example code that was used to show a simple loop to fetch the data from the cursors has
been rewritten here to use the cursor FOR loop. In this code, the emp_record is the record that is
implicitly declared. You can access the fetched data with the implicit record. In the code, no
variables are declared to hold the fetched data using the INTO clause. The code does not have OPEN
and CLOSE statements to open and close the cursor, respectively.
For loops using subqueries:
Begin
For emp_record in (select employee_id, last_name from employee where dept_id = 30)
Loop
Dbms_output.put_line(emp_record.employee_id || ‘ ‘ || emp_record.last_name);
END LOOP;
END;
 In this code, note there is no declarative section in the pl/sql block. The difference between the
cursor for loops using subqueries and the cursor for loops using subqueries and the cursor for loop
lies in the cursor declaration. If you are writing cursor for loops using subqueries, you need not
declare the cursor in the declarative section. You have to provide the select statement that
determines the active set in the loop itself. This sample code is used to illustruate a cursor FOR loop
using subqueries.
 As with implicit cursors, there are explicit cursor attributes for obtaining status information about a
cursor. When appended to the cursor variable name, these attributes return useful information
about the execution of a cursor manipulation statement.
 You cannot reference cursor attributes directly in a sql statement.
 The four attributes are %isopen, %notfound, %found and %rowcount
 You can use the %isopen attribute and then fetch the records if the cursor is open.
 You use the %rowcount cursor attribute to, process an exact number of rows and fetch the rows in a
loop and determine when to exit the loop.
Using cursors with parameters:
 You can pass parameters to a cursor when the cursor is opened and the query is executed. This
means that you can open and close an explicit cursor several times in a block, returning a different
active set on each occasion. For each execution, the previous cursor is closed and reopened with a
new set of parameters. Here is the syntax for cursor declaration using parameters.
CURSOR cursor_name [(parameter_name datatype, …..}]
IS
Select statement;
 Each formal parameter in the cursor declaration must have a corresponding actual parameter in the
OPEN statement. The parameter notation does not offer greater functionality; it simply allows you
to specify input values easily and clearly. This is particularly useful when the same cursor is
referenced repeatedly.
Open cursor_name(parameter_value….);
 Declare
Cursor c_emp_cursor (deptno Number) IS
Select employee_id, last_name from employees where department_id = deptno;

Begin
Open c_emp_cursor(10);
….
Close c_emp_cursor;
Open c_emp_cursor(20);

 In the sample code, the OPEN statements open the cursor and return different active sets.
 You can also pass parameters to the cursor that is used in a cursor for loop.
Declare
Cursor c_emp_cursor(p_deptno Number, p_job varchar2) is
Select ….
Begin
For emp_record IN c_emp_cursor(10, ‘sales’) LOOP…..

REF CURSORS:
 Cursor variables are like C or pascal pointer, which hold the memory location or address of some
item instead of the item itself. Thus, declaring a cursor variable creates a pointer, not an item.
 In pl/sql a pointer has the data type REF X, where REF is short for REFERENCE and X stands for a class
of objects. A cursor variable has the REF cursor data type.
 Like a cursor, a cursor variable points to the current row in the result set of a multirow query.
However, cursors differ from cursor variables in the same way as constants differ from variables.
 A cursor is static, but a cursor variable is dynamic because it is not tied to a specific query. You can
open a cursor variable for any type compatible query. This gives you more flexibility.
 Cursor variables are available to every Pl/sql client. For example, you can declare a cursor variable in
a pl/sql host environment such as an oracle call interface(OCI) or Pro*C program, and then pass it as
an input host variable or bind variable to pl/sql.
 Moreover, application development tools such as oracle forms and oracle reports, which have a
pl/sql engine, can use cursor variables entirely on the client side. The oracle server also has a pl/sql
engine. You can pass cursor variables back and forth between an application and server through
remote procedure calls(RPCs).
 You use cursor variables to pass query result sets between pl/sql stored subprograms and various
clients. Neither pl/sql nor any of its clients owns a result set; they simply share a pointer to the
query work area in which the result set is stored.
 A query work area remains accessible as long as any cursor variable points to it. Therefore, you can
pass the value of a cursor variable freely from one scope to another.
 If you have a pl/sql engine on the client side, calls from client to server impose no restrictions. For
example, you can declare a cursor variable on the client side, open and fetch from it on the server
side, and then continue to fetch from it back on the client side.
 You can also reduce network traffic by having a pl/sql block open or close several host cursor
variables in a single round trip.
 A cursor variable holds a reference to the cursor work area in the program global area(PGA) instead
of addressing it with a static name. Because you address this area by a reference, you gain the
flexibility of a variable.
 To define a REF cursor, you perform two steps:
o You define a REF CURSOR type
o You declare cursor variables of that type
 You can define REF CURSOR types in any pl/sql block, subprogram, or package using this syntax
TYPE ref_type_name IS REF CURSOR [RETURN return_type];
 Ref_type_name is a type specifier used in subsequent declarations of cursor variables.
 Return_type represents a record or a row in a database table.
 In this sample code, you specify a return type that represent a row in the database table dept.
Declare
TYPE deptcurtyp is REF CURSOR RETURN departments%rowtype;
Dept_cf deptcurtyp;
 Ref cursor types can be either strong(restrictive) or weak(nonrestrictive). In this sample code, a
strong REF CURSOR type definition specifies a return type, but a weak definition does not.
Declare
Type empcurtyp is ref cursor return employees%rowtype; ---strong
Type genericcurtyp is ref cursor; -- weak
 There are two REF cursor types:
o Strong REF cursor: These types are less error prone because the pl/sql compiler lets you
associate a strongly typed cursor variable only with type compatible queries.
o Weak REF cursor: Weak ref cursor types are more flexible because the compiler lets you
associate a weakly typed cursor variable with any query.
 After you define a REF CURSOR type, you can declare cursor variables of that type in any pl/sql block
or subprogram. This is the syntax to declare a cursor variable of the defined type.
Ref_cv ref_type_name;
 You can declare cursor variables as the formal parameters of functions and procedures. In this
sample code, you define the REF CURSOR type EMPCURTYP, and then declare a cursor variable of
that type as the formal parameter of a procedure.
Declare
Type empcurtype is ref cursor return emp%rowtype;
Procedure open_emp_cv(emp_cv IN OUT empcurtyp) IS…..
Processing multirow queries
 You use three statements to process a dynamic multirow quey: OPEN-FOR, Fetch & Close:
o You open a cursor variable for a multirow query
o You fetch rows from the result set one at a time
o When all the rows are processed, you close the cursor variable.
 The open-for statement associates a cursor variable with a multirow query, executes the query,
identifies the result set, positions the cursor to point to the first row of the results set, and then sets
the rows processed count kept by %rowcount to zero.
 Unlike the static form of open-for, the dynamic form has an optional using clause. At run time, bind
arguments in the using clause replace corresponding placeholders in the dynamic select statement.
This is the syntax for the open for statement.
Open {cursor_variable | :host_cursor_variable) FOR dynamic_string
[USING bind_argument [, bind_argument]…
 Cursor_vairable is a weakly typed cursor variable, which is without a return type.
 Host_cursor_variable is a cursor variable declared in a pl/sql host environment such as an oci prog
 Dynamic string is a string expression that represents a multirow query.
 Declare
Type empcurtyp is REF CURSOR; --define weak ref cursor type
Emp_cv empcurtyp; --declare cursor variable
My_ename varchar2(15);
My_sal number := 1000;
Begin
Open emp_cv for --- open cursor variable
‘select last_name, salary From employees where salary > :s’ using my_sal;
…..
End;
 In this sample code, the syntax declares a cursor variable and then associates it with a dynamic
select statement that returns rows from the employees table.
 Any bind arguments in the query are evaluated only when the cursor variable is opened. Therefore,
to fetch rows from the cursor using different bind values, you must reopen the cursor variable with
the bind arguments set to their new values.
 The fetch statement returns a row from the result set of a multirow query, assigns the values of a
select list items to corresponding variables or fields in the INTO clause, increments the count kept by
% rowcount, and advances the cursor to the next row. This is the syntax for Fetch statement.
Fetch {cursor_variable | :host_cursor_varibale} INTO {define_varaible … | record};
 Loop
Fetch emp_cv into my_ename, my_sal; -- fetch next row
Exit when emp_cv%notfound; --exit loop when last row is fetched
---process row
End loop;
 In the above example, the rows are fetched from the cursor variable emp_cv into define variables
my_ename and my_sal.
 For each column value returned by the query associated with the cursor variables, there must be a
corresponding type compatible variable or field in the into clause. You can use a different into clause
on separate fetches with the same cursor variable. Each fetch retrieves another row from the same
result set. If you try to fetch from a closed or never opened cursor variable, pl/sql raises the
predefined exception invalid_cursror.
 The close statement disables a cursor variable. After this, the associated result set is undefined. This
is the syntax for the close statement.
Close {cursor_variable} | :host_cursor_variable};
 Loop
Fetch emp_cv into my_ename, my_sal;
Exit when emp_cv%notfound; --exit loop when last row is fetched
---process row
End loop;
CLOSE emp_cv; --- close cursor variable.
 In the above example, when the last row is processed, the emp_cv cursor variable is closed.
 If you try to close an already closed or never opened cursor variable, pl/sql raises invalid_cursor.

Modularization:
 PL/SQL is a block structured language. You can take advantage of this fact to write cleaner, more
efficient code. For example, you can reuse blocks of code instead of rewriting them every time they
are needed. The breaking up of large blocks of code into smaller, more manageable blocks – or
modules – is called modularization.
 Modularization improves
o Data integrity, reusability, security and clarity of code
o Management and maintenance of code
o Performance and reliability of code.
 PL/SQL provides a number of different structures that allow you to modularize code. By combining
these structures you can build entire applications.
 Some of the modular structures provided by pl/sql include triggers, functions, procedures,packages.
Procedure:
 A procedure is a named block of code that can accept parameters and perform one or more actions.
You can invoke a procedure as often as you want by using its name in the executable section of
other pl/sql code blocks.
 When developing stored procedures, it is good to practice to
o Write code in an editor or word processor first and save it as a sql script file
o Load the file into a development tool, such as isql *plus
o Compile and store the procedure
o Then execute the procedure as needed
 The syntax for creating procedure is currently displayed. It is comprised of a number of elements.

Create or replace procedure procedure_name Create or replace procedure raise_salary


[parameter1 [mode] datatype, (id IN employees.employee_id%type,
Parameter2 [mode] datatype….)] Percent IN NUMBER)
IS|AS IS
[local_variable_declarations;…] Begin
BEGIN Update employees
---actions; Set salary = salary * (1 + percent/100)
END [Procedure_name]; Where employee_id = id;
End raise_salary;

 To remove a procedure update_time


Drop procedure update_time;
 You can view procedures that you created yourself by querying the USER_SOURCE data dictionary
table. Provided you have the required permissions, you can view procedures created by others by
querying the ALL_SOURCE data dictionary table.
Understanding Parameters:
 You use parameters to pass values between stored procedures and the executable statements that
call them.
 Parameters are similar to local variables. You define the name, mode and data type of each
parameter when creating a stored procedure. You generally don’t initialize them until you call the
procedure.
 A parameters mode determines how it can be used. There are three parameter modes in PL/SQL:
1) In: You use the IN mode to pass a read-only value into a procedure without returning a value.
For example, you could use an IN parameter in a procedure that recalculates and updates
salaries in an employees table. Such a procedure would not need to return a value to the calling
statement. Id you don’t specify a mode when creating a procedure, the parameter defaults to
the IN mode. You can give IN parameters a default value when declaring a procedure.
2) IN OUT: You use the IN OUT mode to pass a value from a calling statement into a procedure and
then back to the calling statement. The value can be modified by the procedure before it is
returned. For example, you could use an IN OUT parameter in a procedure that takes in a string
of lowercase text and then outputs it as uppercase text.
You cannot give IN OUT parameters a default value when declaring a procedure.
3) OUT: You use the OUT mode to pass a value from a procedure back to the statement that called
it. An OUT parameter is similar to a function’s return value. For example, you could use an OUT
parameter in a procedure that retrieved data from a table. You could then modify this data in
the executable statement that called the procedure. You cannot give OUT parameters a default
value when declaring a procedure.
 There are two kinds of parameter in PL/SQL:
1) Actual Parameters: These are found in the parameter list of a statement calling a stored
procedure. They can be literals, variables, or expressions. In the current example, a variable
called emp_id is initialized. The value of emp_id and the literal value 100 are then passed to a
procedure called raise_sal.
2) Formal Parameters: These are declared in the parameter list of a procedure when it is created.
You specify the name, mode, and data type of each parameter in the parameter list but not the
value. The value is not specified until the procedure is called. In the current example, a
procedure called raise_salary is created with two formal parameters called id and percent
respectively.
Actual Formal
Declare Create or replace procedure raise_salary
Emp_ID := 100; (id IN employees.employee_id%type,
Begin Percent IN NUMBER)
Raise_sal(emp_id,200) IS
End; Begin
/ Update employees
Set salary = salary * (1 + percent/100)
Where employee_id = id;
End raise_salary;

Executing procedures with multiple parameters:


 When an application with multiple parameters is run, there are three methods to specify the values
of the parameters. These include
o Positional: This notation lists the actual parameters in the same order that the formal
parameters are declared.
o Named: This notation lists the actual parameters in arbitrary order and uses an association
operator to relate a named formal parameter with its actual parameter.
o Combination: Combination notation lists the first actual parameters by their position and
the remainder as named.
 Positional notation uses the relative positions of the actual parameters to specify the values of the
comparative formal parameters. In the below example , you would like to pass a value of 10 to the
location_id parameter, and a value of 20 to the department_id parameter. Because the parameters
are associated using the positioning of parameters, the association is made implicitly.

Procedure Header: Execute add_dept (location_id, department_id);


Procedure Call: add_dept(10,20);
 Named notation uses the pl/sql association operator(=>) to explicitly associate the actual parameter
with the formal parameter. Here the loc parameter, which is declared as the second formal
parameter, is referenced by name in the call, where it is associated with the actual value of 2400.
Create or replace procedure add_dept(
Name IN department.departments_name%TYPE,
Loc IN departments.location_id%TYPE) IS
BEGIN
Insert into departments(department_id, department_name, location_id) values
(departments_seq.NEXTVAL, name, loc);
END add_dept;
/
Execute add_dept(loc => 2400, name => ‘Education’);
 Combination notation allows you to mix positional and named notation.
Execute add_dept(‘Advertising’, loc => 1200);
 When using combination notation, you put any positional parameters in front of the named
parameters. This is because the positional notation uses the first parameter as an initial point of
reference for keeping track of positions.
Default values for parameters:
 When default values are assigned to formal parameters, you can call the procedure without
supplying an actual parameter value for the parameter.
 The below code uses two methods of assigning a default value to an IN parameter:
o The assignment operator(:=) for the name parameter.
o The default option for the loc parameter

Create or replace procedure add_dept(


Name IN department.departments_name%TYPE := ‘Unknown’,
Loc IN departments.location_id%TYPE DEFAULT 1700) IS
BEGIN
Insert into departments(department_id, department_name, location_id) values
(departments_seq.NEXTVAL, name, loc);
END add_dept;
 Now you can invoke the add_dept procedure in three ways.
o You can assign default values for each parameter by not explicitly specifying any value for the
parameter.
EXECUTE add_dept;
o You can use a combination of position and named notation to assign values using this code
EXECUTE add_dept(‘Advertising’, loc => 1200);
o You can use default value for the name parameter and the supplied value for the loc parameter
by adding this code to the p/sql statement:
EXECUTE add_dept(loc => 1200);
 You can invoke procedures by using
o Anonymous blocks
o Another procedure or pl/sql subprogram.
 Once you have created and stored a procedure, this can be invoked from another procedure. In the
below example, the process_dept procedure uses a cursor to process all the records in the
departments table and pass each departments id to the add_dept procedure. This results in a new
department, HR, being added.
Create or replace procedure process_dept IS
Cursor dept_cursor IS
Select department_id from departments;
Begin
For dept_rec IN dept_cursor Loop
Add_dept(dept_rec.department_id, ‘HR’);
End Loop;
Comit;
End process_dept;

Handling Exceptions in Stored Procedures:


 When you develop procedures that are called from other procedures, handled and unhandled
exception have an effect on the transaction and the calling procedure.
 When an exception is raised in a called procedure, the control immediately goes to the exception
section of that block. An exception is considered handled if the exception section provides a handler
for the exception raised then the control resumes in the calling procedure.
 When a exception is raised in a called procedure, control immediately goes to the exception section
of that block. If the exception does not provide a handler for the raised exception, then it is not
handled. In this case the control comes to the calling procedure and the exception is handled in the
exception section of the calling procedure.

Functions:
 A PL/SQL function is a named block that returns a value. In general, when you invoke a function, it
accepts an input value, carries out operations on it, and returns an output value.
 If you want to use a function repeatedly, you can store it in the database as a schema object. It is
then referred to as a stored function.
 In addition to storing a function in the database, you can create and store it in a client-side
application.
 A PL/SQL function is similar to a procedure. However, there are a number of important difference
between them:
o Execution: You invoke a function as part of an expression. For example, you can call a function
as part of a PL/SQL expression or a sql statement. You invoke a procedure as a PL/SQL
statement – using an anonymous block or another procedure, for example.
o Returning Values: A function must always return a single value to the calling environment. A
procedure can pass zero or more values to and from the calling environment. It can return
values in its output parameters.
o The RETURN Keyword: To return a value, a function must include a RETURN clause in the
declarative section and at least one RETURN statement in the executable section. A procedure
does not have a RETURN clause in the declarative section, but it may contain a RETURN
statement in the executable section, even if it does not return a value.
 Functions that are called by SQL statements should not contain OUT or IN OUT mode parameters. A
function that includes output parameters can be used in a PL/SQL procedure or block, but not in SQL
statements.
 Like a procedure, a function includes a declarative section, an executable section, and an optional
exception-handling section.
 Here is an example of a function called tax. In this case, it does not include an exception handling
section. The function returns the tax contribution of each employee that works in the department
with an ID number of 100 when you enter the employee’s salary.
Create or replace function tax(value in number) return number is
Begin
Return(value * 0.08);
End tax;
/
Select employee_id, last_name, salary, tax(salary) from employees where department_id = 100;
 The above sql section calls and displays the values returned by the function for each employee. This
section shows that the function is called by a select statement, along with the employee_id,
last_name, and salary columns.
 There are number of advantages associated with creating and calling stored pl/sql functions:
o Referencing: You can reference stored pl/sql functions from the same locations as sql
expressions. For example, you can insert a user-defined pl/sql function anywhere a built in sql
function, such as upper(), can be inserted.
o Calculations: You can create user-defined pl/sql functions to carry out calculations that are too
complex or awkward to implement with sql code. It also enables the creation of functions that
are otherwise unavailable with sql.
o Data Independence: Pl/sql functions increase the independence of user data by processing
complex data analysis in the oracle server instead of retrieving and processing the data within
the application.
o Efficient queries: You can make sql queries more efficient by including pl/sql functions in a
query rather than in the specific applications.
o Manipulation of new types of data: You can simplify the manipulation of new types of data –
latitude and longitude, for example – by encoding character strings and creating pl/sql
functions to perform calculations on the strings.
o Reusability and maintainability: Pl/sql functions are reusable and simple to maintain and
update. When a function is validated, it can be reused indefinitely in a number of different
applications. If your data processing requirements change, you only need to update the
function once to affect all of its instances.
 You can include multiple RETURN statements in a function usually within an IF statement. Invoking
a function that contains multiple RETURN statements only executes one of them because after the
function returns a single value, the block is not processed any further.
 To create a pl/sql function, you use the CREATE FUNCTION statement, which
o Declares a list of parameters
o Returns a single value
o Defines the actions to be carried out by the function
 The syntax to create a function is below. It comprises a number of elements.
Create or replace function function_name Create or replace function get_sal
[(parameter1 [mode1] datatype1,…)] (id employees.employee_id%TYPE)
RETURN datatype IS|AS RETURN number IS
[local_variable_declarations; …] Sal employees.salary%TYPE := 0;
BEGIN BEGIN
--actions; Select salary into sal from employees
RETURN expression; Where employee_id = id;
END [function_name]; RETURN sal;
END get_sal;

 You can invoke stored PL/SQL functions in a number of ways:


o As part of a pl/sql expression
 Declare sal employees.salary%type;
Begin
Sal := get_sal(100);
END;
o As a parameter to another subprogram
 Execute dbms_output.put_line(get_sal(100);
o As an expression in a sql statement
 Select job_id, get_sal(employee_id) from employees;
 You can call a user-defined pl/sql function from any sql expression where you can call a single row,
built in function.
Select employee_id, tax(salary) from employees
Where tax(salary) > (select max(tax(salary) from employees where department_id = 30)
Order by tax(salary) desc;
 You cannot call a user defined function from the check constraint clause of the create table or alter
table statements.
 You also cannot assign the default value of a column to a user defined function.
 To call a user defined function using sql, it must first fulfill a number of requirements. These depend
on whether you want to call the function from
o A sql expression: To call a function from a sql expression, the function must be stored in the
database. In addition, its IN parameters and output parameters must be set to sql data types,
and not pl/sql specific data types, such as Boolean, record or table.
o A sql statement: To call a function from a sql statement, the parameters of the function must
use positional notation and not named notation. You also need to own or have the Execute
privilege on the function to call it. You cannot call a stored procedure from a sql statement
unless its invoked from a function that fulfils the above requirements.
 To delete an existing stored function from your database
DROP FUNCTION get_sal;
 You can use a number of oracle data dictionary tables to display information about user-defined
pl/sql functions like, user_source, all_source and user_objects tables.

Packages:
Overview of packages:
 Packages are discrete units of pl/sql code that enable you to bundle related pl/sql types, variables,
data structures, exceptions, and subprograms together for convenience. They are usually used to
bundle related procedures and functions together.
 For example, an employee_salaries package might contain procedures and functions, which
calculate wage rates, bonus schemes and tax data.
 A package usually consists of two parts stored separately in the database – a specification, which is
the actual package, and a body, which contains all the functionality. The body section is optional.
 A package itself cannot be parameterized or nested. Once you’ve written and compiled a package,
its contents can be shared by many applications.
 When you reference a package for the first time, the entire package is loaded. Because of this no
time is lost or disk input/output (i/o) used up the next time you make a reference to the same
package.
 Packages have several benefits. They are
o Enable applications to be enhanced and maintained more easily.
o Help improve the performance of an application
o Are not affected by application functionality issues.
 Its considered best practice to always construct applications using packages. Even if you only want
to perform one procedure for a type of functionality, its likely that, in the future, you will want to
add another – if not more than one.
 A package has two parts –
o Package Specification: The specification defines how a package is to be used. For example, it
may specify the programs that are to be used or what cursors may be opened. It is the
interface between executable code and your applications. It might include declarations for
public types, variables, constants, exceptions, cursors, or subprograms. It might also include
PRAGMAs, which are directives to the compiler.
o Package Body: The package body must contain the code required to implement
subprograms or other elements declared in the specification. The package body may also
define its own subprograms and other pl/sql constructs, such as types, variables, constants,
exceptions and cursors. It’s also possible to have no package body – for example, if the
specification doesn’t declare any subprograms, there may be no need for a body.
 The specification and package body consist of public and private components.
 Any components declared in the specification are considered public components. This means they
are available to any programs outside the package. In other words, the specification defines a public
application programming interface (API), which means, effectively, that its components can be
referenced by programs in an Oracle server environment that is external to the package, as well as
internal ones.
 Subprograms and other elements in the package body are regarded as private components and can
be referenced as private components and can be referenced only by other constructs within the
same package body. Private components can reference the public components of any package.
 Disadvantage in procedures:
Create or replace procedure customer_id(customer_id_in IN customer.customer_id%TYPE) IS
Name_and_id varchar2(20)
Begin
Select cust_last_name || ‘,’ || customer_id INTO name_and_id From customers
Where customer_id = customer_id_in;
End;
 Suppose you want to query the customers table for last names of customers and customer IDs. You
want to display the results by merging the last name with the ID, separated by a comma – for
example “Andrews, 125”. This code fragment details how you would do this using a standalone
procedure, not a package.
 The above code will return the results you want. However, because the length of the name_and_id
variable is hardcoded to 20 spaces, it could be problematic if the cust_last_name column were to be
expanded.
 Another problem with this code is that the format of the output is restricted to “last name, ID”, and
you may require a different format.
Package Specification: Package Definition:
Create or replace package customer_pkg as Function name_and_id(
Subtype name_and_id_t IS varchare2(200); Last_in customer.cust_last_name%TYPE,
Id_in customer.customer_id%TYPE)
Function name_and_id( RETURN name_and_id_t
Last_in customer.cust_last_name%TYPE, IS
Id_in customer.customer_id%TYPE) Begin
RETURN name_and_id_t Return last_in || ‘,’ || id_n;
End;
Function name_and_id( Function name_and_id(
Customer_id_in IN customer.customer_id%TYPE) Customer_id_in IN customer.customer_id%TYPE)
Return name_and_id_t; Return name_and_id_t
End customer_pkg; IS
Retval name_and_id_t;
Begin
Select name_and_id(cust_last_name, customer_id) into retval
From customers where customer_id = customer_id_in;
Return retval;
End;
End customer pkg;

 In order to overcome these problems, you should consider using a package. This involves writing
one definition of a data type, one representation of the formula, and one version of the query,
which can be reused as many times as you want.
 First you create a specification with a new data type called name_and_id_t.
 Then you declare a function called name_and_id that accepts a customers last name and if and
returns them. You write a second function, also called name_and_id, which accepts a primary key
for a customer and returns a las name and ID. You then end the package specification.
 Having completed the package specification, you can then create the package body, which
implements the specification, to produce the same results as the previous standalone procedure.
Visibility of components:
 The degree to which a component is available to other components and objects is referred to as its
visibility. The visibility of components depend on whether they are locally or globally declared, and a
components’s visibility affects how its used and referenced.
Package Specification(Public): Package Body(Private):
Variable_1; Variable_2
Subprogram_1; Subprogram_2 is
Begin….End;
Subprogram_1 is
Variable_3
Begn … End;

 A locally defined component is visible within the structure in which its declared. Locally defined
components are found in the package body. For example, variables defined in a subprogram can be
referenced within that subprogram and are not visible to external components. In the displayed
example, the variable, varaiable_3, can be used in the subprogram_1.
 Other local components, such as private package variables that are declared in a package body, can
be referenced by other components in the same package body and are not visible to any
subprograms or objects outside the package. In the displayed example, the variable – variable_2 –
can be used by the subprograms – subprogram_1 and subprogram_2 – within the package body but
not outside the package.
 Globally declared components, found in the specification, are visible both internally and externally
to the package, such as in example:
o Variable_1: A public variable that is declared in a package specification can be referenced
and changed outside the package. In this example, variable_1 can be referenced externally.
o Subprogram_1: A package subprogram in the specification can be called by external
programs. In this example, subprogram_1 can be called from, say, another block of code
that is external to the package.
Creating a package specification:
 All packages have a specification section and most packages have a body section. In order to
develop a particular package, you must decide what code to put into each section. You may also
include code to enable oracle to initialize the package.
 There are some additional, general guidelines for developing packages. You should save two sql files
– one for the specification and one for the body – in case you need to modify one or the other, or
reuse the package with a different body.
 Also, you should be aware that when you load your package, oracle stores the specification and
body separately. This means you don’t affect schema objects that call or reference a body
subprogram when you modify the implementation of that subprogram.
 And, if you don’t declare any subprograms in the specification, a package body will not be required.
However, you must always have a package specification.
 You can declare variables and constants of most data types in a package specification. Private
variables are declared in the body.
 Data structure declarations are allowed, such as record or collection types, and you can also declare
procedure and function headers, as long as you complete the code for these in the body. You can
also include an explicit cursor and put the related query in the body – or you can have the entire
cursor in the specification.
 CREATE [OR REPLACE] PACKAGE package_name IS|AS
Public type and variable declarations
Subprogram specifications
END [package_name];
 To create a package specification, you use the Create Package command. You can include or replace
if you are overwriting an existing specification. You also use the IS or AS keywords to define it. You
must include a package name in the CREATE PACKAGE statement. This must be unique among
objects within the owing schema. You can also include the package name in the END statement but
this is optional.
 You declare you public variables, constants, cursors, exceptions, user defined types, and subtypes in
the specification. You can also initialize a specification variable with a constant value or formula. This
enables oracle to initialize the package – otherwise, the variable is initializes as NULL by default.
 In the subprogram specifications, you specify the public procedure or function declarations. You
include only the headers followed by a semicolon. The actual implementation is included in body.
 Create or replace package bonus_pkg IS
Std_bonus Number := 0.10;
Procedure reset_bonus(new_bonus Number);
End bonus_pkg;
Creating a package body:
 In the package body, you write all the code that’s necessary to complete the procedures declared in
the specification. If no procedures were declared in the specification, theres no need for a package
body.
 You need a package body if
o The package specification contains a cursor declaration with a return clause.
o The package specification contains a procedure or function declaration.
o You want to execute code in the initialization section of the package body.
 Here is the syntax of package body.
Create [or replace] package body package_name IS|AS
Private type and variable declarations
Subprogram bodies
[Begin initialization statements]
End [package_name];
 You use the create package body statement to create a package body, and you can also use the or
replace statement if a package body of the same name already exists. You include the package
name, making sure it’s the same as in the specification, and you can include this name in the end
statement if you want. However, this is optional.
 Public variables and other public components are declared in the specification, but private variables,
constants, cursors, exceptions, user defined types, and subtypes are declared in the package body.
 Subprograms in the body implement private or public procedures or functions in full. The order of
implementation is important – if you want to reference a variable or subprogram in any component,
you must declare it first so you need to order your components appropriately. And, for convenience,
you may decide to define all private variables and subprograms before defining public subprograms.
 You may include an optional block of initialization code that executes when the package is first
referenced.
 Create a package body for the specification you created earlier.
Create or replace package body bonus_pkg is
Function validate(bonus number) return Boolean is max_bonus employees.bonus_pct%type;
Begin
Select max(bonus_pct) into max_bonus from employees;
Return (bonus between 0.0 and max_bonus);
End validate;
Procedure reset_bonus (new_bonus Number) is begin
If validate(new_bonus) then
Std_bonus := new_bonus;
Else raise_application_error(-20210, ‘Bad bonus’);
End If;
End reset_bonus;
Invoking package subprograms:
 Once a package is loaded into the database and stored there, you may want to invoke its public or
private subprograms. You can do this directly from within the package.
 You can also invoke a package’s subprograms from another program that is external to the package.
In this case, you can invoke public subprograms only, and you also need to indicate the package
name. You use the syntax package_name.subprogram.
 Using a package name when invoking a subprogram from within the package is optional. Pl/sql will
automatically resolve the reference.
 Suppose you have created a package, called bonus_pkg, containing a validate function. You want to
call this function from within a procedure, called reset_bonus, which you are developing within the
same package.
Create or replace package body bonus_pkg is
Procedure reset_bonus(new_bonus number) is
Begin
If validate(new_bonus) then
Std_bonus := new_bonus;
Else
End if;
End reset_bonus;
End bonus_pkg;
 If a procedure, reset_bonus, is owned by a different user schema – say for the user, tonya chavis –
you can call this. You must prefix the qualified package procedure with the schema name, Chavis.
Execute chavis.bonus_pkg.reset_bonus(0.15)
Viewing and removing packages:
 All the source code for pl/sql packages is stored in data dictionary tables if you need to maintain or
modify them. The code is available in the USER_SOURCE and ALL_SOURCE tables.
 When a package is no longer required, you can use a sql statement to remove it. All packages have
two parts – a specification and a body. You have the option of removing the entire package.
Alternatively, you can remove just the package body, leaving the package specification.
 To remove the entire package – both the package specification and the body – you use a particular
syntax: Drop package package_name;
 You also use the drop statement when removing the package body.
Drop package body package_name;
Overloading subprograms:
 The overloading feature in pl/sql enables you to develop two or more packaged subprograms with
the same name. You can use the same name for different subprograms provided their formal
parameters differ in number, order, or data type family. The overloading feature is very useful
because it allows the same operation to be applied to objects of different types.
Create or replace package overload_package IS
Procedure proc1(x number);
Procedure proc1(x varchar2, y number);
Procedure proc1(x varchar2);
End overload_package;
 The overloading feature can be used with local subprograms, package subprograms, and type
methods, but not with standalone subprograms.
 You should consider using overloading for a number of reasons like flexibility, user friendliness and
scalability.
 There are certain cases when the overloading feature cant and shouldn’t be used. If you use the
overloading feature in any of these instances, a runtime error will be returned.
o You cannot overload two subprograms if their parameters differ only in the parameter
passing modes.
Procedure overloadme(p_theparameter in number);
Procedure overloadme(p_theparameter out number);
o You cannot overload two functions based on their return type only.
Fucntion overloadmetoo return date;
Fucntion overloadmetoo return number;
o The parameters of overloaded functions must differ by family type. In this example, the char
and varchar2 data types are in the same family type.
Procedure overloadchar(p_theparameter in char);
Procedure overloadchar(p_theparameter in varchar2);
 The program compiler attempts to find a declaration that matches a call. It searches the current
scope first, and then, if necessary, searches in successive enclosing scopes. The compiler stops
searching if it finds one or more subprogram declarations in which the name matches the name of
the called subprogram.
 For similarly named subprograms at the same level of scope, the compiler needs an exact match in
number, order, and data type between the actual and formal parameters.
Forward declaration in a pl/sql package:
 In general, pl/sql is like other block structured languages and does not allow forward references.
You must declare an identifier before using it. For example, a subprogram must be declared before
you call it.
 Coding standards often require that subprograms be kept in alphabetical sequence to make them
easy to find. In this code, for example, you may encounter problems where the calc_rating
procedure cannot be referenced because it has not yet been declared.
Create or replace package body forward_pkg is
Procedure award_bonus(….) is
Begin
Calc_rating(….); ---illegal reference
End;
Procedure calc_rating(…..) is
Begin ….. End;
End forward_pkg;
 You can solve illegal reference problems by reversing the order of the two procedures. However,
this solution does not work if the coding rules require subprograms to be declared in alphabetical
order.
 The solution in this case is to use forward declarations provided in pl/sql. A forward declaration
enables you to declare the heading of a subprogram – that is, the subprogram specification
terminated by a semicolon.
Procedure calc_rating(………); -- forward declaration.
 Forward declarations help to
o Define subprograms in a logical or alphabetical order.
o Define mutually recursive subprograms, which are programs that call each other directly or
indirectly
o Group and logically organize subprograms in a package body
Functions of the PL/SQL wrapper:
 The pl/sql wrapper is a standalone utility that converts pl/sql source code into portable object code.
It allows you to deliver pl/sql applications without exposing your source code, which may contain
proprietary algorithms and data structures.
 The wrapper converts the readable source code into unreadable code. By hiding application
internals, it prevents misuse of your application.
 In terms of practical applications, a wrapper might be used by a company to distribute any pl/sql
based software that it sells over the internet.
 The distributed code may be executed as normal, but customers are unable to see the actual source
code. Its important to remember though that the wrapped code is usually much larger than the
source code from which it is generated.
 Wrapped code, such as pl/sql stored programs, has several notable features, It
o Is platform independent
o Permits dynamic loading
o Permits dynamic binding
o Offers dependency checking
o Supports importing and exporting
 The wrapper is an operating system executable called WRAP. To run the wrapper, you enter the
command at your operation system prompt using the syntax.
$ WRAP INAME = input_file_name [ONAME = output_file_name]
 Elements in command line syntax to run the wrapper are
$ WRAP INAME = student.sql ONAME = student.plb
o The Iname argument is required
o The default extension for the input file is .sql, but u can use any extension.
o The oname argument is optional in the command line syntax.
o The default extension for the output file is .plb – which stands for pl/sql binary although the
output file is not really a binary file. You can specify any extension for the output file.
 After the wrapper file is created, you execute the PLB file from isql*plus to compile and store the
wrapped version of the source code in the same way that you would execute sql script files.
$@ORACLE_HOME/wrap/example.plb
 There is a difference between the original pl/sql source code in an input file and the wrapped code.
Original PL/SQL Wrapped PL/SQL
Create package banking is Create package banking
Min_bal := 100; Wrapped
No_funds Exception; 012abc436e…….

End banking;
 When it is wrapped, an object type, package, or subprogram takes the form of header, followed by
the word wrapped, and then followed by the unreadable body.
 In order to run the wrapper efficiently, it is recommended that you follow several guidelines in
specifying argument, spaces, the input file, case sensitivity, the output file, no spaces around INAME
and ONAME.
 The input file can contain any combination of sql statements. However, the pl/sql wrapper wraps
only a distinct number of Create statements:
Type, type body, package, package body, function, procedure.
 All other sql create statements are passed intact to the output file like table, trigger and index.
 Other important guidelines that you should adhere to include only wrapping the package body and
not the package specification. This ensures that other developers have the information they need to
use the package without exposing its implementation.
 The output file should not be edited because its contents are not readable and editing this file could
potentially render it invalid. To change a wrapped object, you need to modify the original source
code and wrap the code again.
 If your input file contains syntactic errors, the pl/sql wrapper detects and reports them . However,
the wrapper cannot detect semantic errors because it does not resolve external references. For
example, the wrapper does not support an error if the table or view amp does not exist.
 However, the pl/sql compiler resolves external references. Therefore semantic errors are reported
when the wrapper output file (.plb file) is compiled.
 Wrapping the body and not the specification of a package or object type gives other developers the
information they need to use the package without exposing its implementation.

Triggers:
 A trigger is a pl/sql block or procedure associated with a table, view, schema, or database. Triggers
execute implicitly whenever a particular event takes place.
 There are two different types of triggers – application and database.
 An application trigger fires whenever an event occurs within a particular application.
 A database trigger fires whenever a data event, such as a DML event, or a system event, such as a
logon or shutdown, occurs on a schema or database. Triggers represent an important element of a
well designed application built on the oracle database.
 Database triggers perform a number of key functions:
o Validation on alterations to tables.
o Automatic database maintenance
o Setting rules for acceptable database administration
 A programmer designs triggers to perform related actions and to centralize global actions. You can
use database triggers
o As alternatives to features provided by the oracle server.
o If your requirements are more complex or more simple than those provided by the oracle
server.
o If your requirements are not provided by the oracle server at all
 The syntax for creating a trigger is
Create [or replace] trigger trigger_name
{Before | After |Instead of } triggering_event
[referencing_clause]
[When trigger_condition]
[For each row]
Trigger_body;
 The trigger_name element in the syntax refers to the name of the trigger.
 The triggering_event element in the syntax specifies the event that fires the trigger. This can even
include a specific table or view.
 The referencing_clause element in the syntax is used to refer to the data in the row currently being
modified by a different name.
 The trigger_condition element in the syntax in the When clause, if present, is evaluated first, and the
body of the trigger is executed only when this condition evaluates to True.
 Suppose you are updating your employee records on a regular basis. You could use a trigger like the
below example, which inserts a record into the employees_history table every time there is an
update on a row in the employees table.
Create or replace trigger emphisttrigger
Before update on employees
For each row
Begin
Insert into employees_history values (:new.employee_id, :new.first_name, :new.last_name,
:new.email, sysdate);
End emphisttrigger;
Enhancements provided by triggers:
 You can develop database triggers to augment features that cannot otherwise be executed by the
oracle server.
 The following features of triggers are useful in business scenarios:
Security Auditing Referential integrity
Table replication Derived data Event logging

Triggers and Events:


 Application triggers execute implicitly whenever a particular data manipulation language(dml) event
occurs within an application. Applications developed with oracle forms developer would use triggers
extensively.
 There are five main types of triggers:
o DML statement triggers: DML triggers are capable of firing whenever a record is added into,
updated in, or deleted from a table. These triggers are available to perform validation, audit
changes, set default values, and even disallow a number of dml operations.
DML triggers could be used, for example, to populate an audit table when any inserts,
updates, or deletes are performed on a base table.
o DDL statement triggers: DDL triggers fire on the execution of DDL statements. These triggers
are versatile enough to perform auditing and guard against certain DDL statements
occurring. DDL triggers could be used, for example, to record details of any DROP TABLE
commands that are run.
o Database event triggers: Database event triggers fire on startup or shutdown of the
database, or when a user logs on or off, and whenever an oracle error occurs. These triggers
provide a way of tracking activity in the database. Database event triggers could be used, for
example, to record when users log on and log off from the database.
o Instead of triggers: These triggers are basically alternatives to DML triggers. Instead of
triggers fire when inserts, updates, and deletes are about to take place. Your code specifies
what to do instead of these DML operations. Instead of triggers administer views but not
tables. They are capable of making non updateable views updateable and of overriding the
conduct of views that are updateable.
o Suspended statement triggers: Statements that encounter space problems due to a full
tablespace or an exceeded quota can enter suspended mode until the issue is addressed.
Triggers can be set to provide automatic alerts to a problem. Suspended statement triggers
could be used, for example, to notify the dba of why a particular statement has been
suspended.
DML trigger types:
 Triggers are procedures that run implicitly when an insert, update, or delete statement is issued
against the associated table or, in some cases, against a view, or when database system actions
occur. These procedures can be written in pl/sql or java and stored in the database, or they can be
written as C callouts.
 DML triggers fire when records are inserted into, updated within, or deleted from a particular table.
They are the most common type of triggers, particularly for developers. Other trigger types are used
mainly by DBAs.
 There are a variety of options to consider with DML triggers. They are capable of firing before or
after a DML statement, or before or after each row is processed within a statement.
 DML triggers can fire for INSERT, UPDTE, or Delete statements, or combinations of three.
 There are a number of ways of configuring DML triggers. In addressing the needs of your
environment, you need to ask, for example, whether a trigger should fire once for the entire DML
statement or once per row involved in the statement.
 You can specify that the trigger will execute once for every row affected by the triggering statement,
such as a multiple row Update, or once for the triggering statement, regardless of the number of
rows it affects. Each specification will have a different result:
o Statement Trigger: A statement trigger is fired once on behalf of the triggering event, even if
no rows are affected at all. Statement triggers are useful if the trigger action does not
depend on the data from rows that are affected or on data provided by the triggering event
itself. An example would be a trigger that performs a complex security check on the user.
o Row Trigger: A row trigger fires each time the table is affected by the triggering event. If the
triggering event affects no rows, a row trigger is not executed. Row triggers are useful if the
trigger action depends on data of rows that are affected or on data provided by the
triggering event itself.
 This code shows an example of a statement trigger that fires after the DML statement.
Create or replace trigger dept_table After delete on departments
Begin
Dbms_output.Put_line(‘After delete trigger fired’);
End;
 Adding the below code make the above a row level trigger.
For Each Row
 When configuring a DML trigger, you will need to specify when a trigger fires. There are a number of
ways of configuring DML triggers. In establishing what suits in your own environment, you need to
know wheter.
o The triggers should fire before or after the entire statement completes or before each row
processes
o The triggers should fire for inserts, updates, deletes or a combination of all
 There are three options to consider when specifying when a trigger will fire:
 Before: The before trigger timing a frequently used in the following situations:
o Determining whether the triggering statement should be allowed to complete
o Deriving column values before completing an insert or update statement
o Initializing global variables or flags, and validating complex business rules
 After: The after trigger is frequently used in the following situations:
o Completing the triggering statement before executing the triggering action
o Performing different actions on the same triggering statement if a Before trigger is already
present.
 Instead Of: This trigger offers a transparent way of modifying views that cannot be modified directly
through DML statements because a view is not always modifiable. You can write appropriate DML
statements inside the body of an Instead Of trigger to perform actions directly on the tables
underlying the views.
Comparing triggers and stored procedures:
 Database triggers are invoked implicitly. Commit, Rollback and Savepoint statements are not
allowed within a trigger body. Although it is possible to commit or roll back indirectly by calling
procedure, it is not recommended because of side effects to transactions.
 Stored procedures, on the other hand, are invoked explicitly. And COMMIT, ROLLBACK, and
SAVEPOINT statements are permitted within the procedure body. In addition, mutating table
problems are more easily handled by using PL/SQL tables in stored procedures.
 Triggers are fully compiled when the CREATE TRIGGER command is issued and the executable code
is stored in the data dictionary. If errors occur during the compilation of a trigger, the trigger is still
created.
 Given that triggers are invoked implicitly on objects, they are easy to implement when you wish to
link an activity with a database table. Also, in cases where you'd like to carry out activities based on
database events, such as logging on and off, system triggers are the best solution. However, in
certain situations, triggers are unsuitable. For example, triggers are not suitable for transactions
because transaction control statements are not allowed in triggers. In addition, they are not suitable
for highly complex operations because of their limit size of 32 Kb.
 INSTEAD OF triggers can only be used on views so if you need this functionality to work on a table,
you should use a stored procedure.
Trigger Execution Mode:
 When you create a trigger, you can specify whether it will be executed once for every row affected
by the triggering statement (such as a multiple row update) or once for the triggering statement, no
matter how many rows it affects.
 The type of trigger you create determines if the body executes for each row or only once for the
triggering statement.
 Two types of DML triggers: Statement triggers, row triggers.
 A dml trigger comprises two parts:
Create Trigger trigger_name
{Before | After | Instead Of} triggering_event
Decalre
Begin
End;
 A triggering event: A trigger event, which can be an INSERT, update or delete statement, determines
which dml statement causes the trigger to execute.
 A triggering body: The trigger body defines the action to be performed when the triggering event is
issued. The pl/sql block can contain sql and pl/sql statements, and can define pl/sql constructs such
as variables, cursors, exceptions, and so on.
 A single DML statement can potentially fire up to four types of triggers:
o Before statement triggers
o After statement triggers
o Before row triggers
o After row triggers
 There are three stages in the trigger execution model. The first stage is to execute all Before
statement triggers. This prevents the triggering operation from succeeding if a certain condition is
violated. The second stage is to excecute row triggers for each row affected. This involves executing
all Before row and after row triggers, executin the DML statement, and performing integrity
constraint checking. The third stage is to execute all After statement triggers.
 Integrity constraints specify the convention to be followed for a particular column in a table. For
example, the integrity constraints of a department_id column may be that the value is not null.
 For the execution model to operate, all actions and checks performed as a result of a dml trigger
must not compromise these constraints.
 If an exception is raised within a trigger and the exception is not explicitly handled, an error message
displays and all actions performed because of the original sql statement are rolled back (including
actions performed by firing triggers). This guarantees that integrity constraints can never be
compromised by triggers.
 When designing triggers, you should also consider that excessive use of triggers can result in
complex interdependencies, which may be difficult to maintain. So you should only use trigger when
necessary and be aware of recursive and cascading effects.
 Also creating stored procedures or packaged procedures that are invoked in the trigger body causes
lengthy trigger logic, which can adversely affect database performance.
 You create a DML statement or row triggers using the below syntax
Create or replace trigger trigger_name Create or replace trigger secure_emp
Timing Before insert on employees
Event1 [or event2 or event3] Begin
On object_name If(to_char(sysdate,’dy’) in (‘SAT’,’SUN’)) or
(to_char(sysdate,’hh24:mi’) not between ’08.88 and
[referencing old as old | new as new]
’18.00’) Then
For each row Raise_application_error(-20500, ‘you may insert’ ||
[when (condition)]) ‘into employees table only during’ || ‘business hours.’);
Trigger body End if;
…………….. End;
 Trigger_name element uniquely identifies the trigger. The timing element indicates when the trigger
fires in relation to the triggering event. The values are Before, After or Instead Of. The event
element identifies the DML operation causing the trigger to fire. The values are Insert, update [of
column], and delete. The object_name element indicates the table or view associated with the
trigger.
 For row triggers you can specify.
o A referencing clause to choose a correlation name for referencing the old and new values of
the current row (the default values are old and new)
o For each row to designate that the trigger is a row trigger
o A when clause to apply a conditional predicate, in parentheses, which is evaluated for each
row to determine whether or not to execute the trigger body.
 The trigger_body element is the action perforemed by the trigger, implemented as either
o An anonymous block with a declare or begin clause and an end clause.
o A call clause to invoke a standalone or packaged stored procedure such as call
my_procedure;
 You can combine several triggering events into one by taking advantage of the special conditional
predicates inserting, updating and deleting within the trigger body.
If deleting then raise_application_error() End if;
If inserting then raise_appliation_error() End If;
If updating then raise_appliation_error() End If;
DML row trigger:
 A row trigger fires each time a related table is affected by the triggering event. If the triggering event
affects no rows, a row trigger is not executed. Row triggers are useful if the trigger action depends
on data of rows that are affected or data provided by the triggering event itself.
 This differs from a statement trigger, which is fired once on behalf of the triggering event, even if no
rows are affected at all.
Instead of trigger:
 The syntax used to create an instead of trigger is simiilare to the syntax for statement and row
triggers.
Create [Or replace] trigger trigger_name
Instead of
Event1 [or event2 or event3] on object_name
[[referencing old as old | new as new]
For each row
[when (condition)]]
Trigger_body
 With instead of triggers, the oracle server fires the trigger instead of executing the triggering
statement. You can write insert, update or delete statements against a view, and the instead of
trigger works invisibly in the background to ensure that the right actions take place. This trigger is
used to perform an insert, update or delete operation directly on the underlying tables.
 A view cannot be modified by normal DML statements if the view query contains set operators,
group functions, clauses – such as group by, Connect By, and Start the distinct operator, or joins.
 For example, if a view consists of more than one table, an insert t the view may entail an insertion
into one table and an update to another.
 So you write an instead of trigger that fires when you create an event against the view. Instead of
the original insertion, the trigger body executes, which results in an insert, delete, or update of data
in multiple tables.
 You can create an Instead of trigger to maintain the base table on which a view is based.
 The example illustrates an employee being inserted into the emp_details view, whose query is
based on the employees and departments tables. The new_emp_dept (instead of ) trigger executes
in place of the insert operation that caused the trigger to fire. The Instead of trigger then issues the
appropriate insert and update statements to the base tables used by the emp_details view.
Insert into emp_details values (9001, ‘Abbott’, 3000, 10, ‘Administration’);
 Therefore, instead of inserting the new employee record into the employees table, the following
code is executed;
o Instead of insert into emp_details
o Insert into new_emps
o Update new_depts
Database and schema level triggers:
 Triggers that are based on data manipulation language(dml) statements, such as insert and select,
are defined on a specific table or view.
 However, you can also define triggers that are fired when a particular system event or user event
occurs.
 System event triggers can be defined at two levels depending on the type of event that fires them:
o Database level: Some system event triggers, such as those fired when a database shuts
down or starts up, are always defined at the database level. Triggers defined at the database
level fire for all users.
o Schema Level: Some system event triggers can be defined at the schema level. Examples
include triggers fired when a user logs on or off and triggers fired by server error messages.
If a trigger is defined on a schema, it only fires if the triggering event involves that particular
schema.
 You can develop triggers in pl/sql that fire when specific system events occur.
 With the After and Before trigger clauses, you can specify that you want a system event trigger to
fire before or after these events:
o After Servererror: You enter after servererror to cause the oracle server to fire the trigger
when as erver error message is logged. You can define this type of trigger at the database
level or the schema level.
o After Logon: You enter After Logon to cause the oracle server to fire the trigger whenever a
user logs on to the database or schema.
o Before Logoff: You enter Before Logoff to cause the oracle server to fire the trigger before a
user logs off the database or schema.
o After Startup: You enter After Startup to cause the oracle server to fire the trigger after the
database has been started. This type of trigger can only be defined at the database level.
o Before Shutdown: You enter Before Shutdown to cause the oracle server to fire the trigger
before the database is shut down. This type of trigger can only be defined at the database
level.
 You use this syntax to create a system event trigger.
Create or replace trigger trigger_name
[database_evernt1 [or database_event2 or..]]
On {database | schema}
Trigger_body
 Create or replace trigger user_logon
After logon on schema
Begin
Insert into log_trig_table(user_id, log_date, action) values (user,sysdate, ‘logging on’);
End;
 After servererror on schema
 Before shutdown on database
 After startup on database
Triggers on a DDL statement:
 Triggers fired by Data Definition Language(DDL) statements can be defined at the database level or
the schema level.
 A ddl trigger is fired when a specified ddl statement is executed.
 A number of ddl statements can cause a ddl trigger to fire: Alter, create and drop
 DDL triggers only fire when certain database objects, such as functions, indexes, packages,
procedures, roles, sequences, synonyms, or triggers are affected by DDL statements.
 These triggers are also fired when ddl statements affect tables, tablespaces, types, views, users.
 You can use this syntax to create a ddl trigger. It is similar to the syntax for system event triggers.
However, in this case, you specify that the trigger should be fired by a ddl event.
Create or replace trigger trigger_name
Timing
[ddl_event1 [or ddl_event2 or…..]]
On {database | schema }
Trigger_body
 Create or replace trigger new_object After create on schema
Begin
Dbms_output.put_line(‘A new object has been created.’);
End;
 After alter on database
 After drop on schema
Triggers and CALL statements:
 You can use CALL statements to call external stored procedures from within triggers instead of
inserting the pl/sql code within the trigger itself. This simplifies the process of developing and
updating triggers.
 Procedures called by CALL statements can be implemented in PL/SQL, C, or Java.
 You use this syntax to create a trigger that uses a CALL statement to call an external procedure.
CALL procedure_name
 Triggers have a number of restrictions placed on them when they attempt to read and wirte data
from database tables and columns. These are referred to as mutating table restrictions.
 Mutating table restrictions apply to row triggers and statement triggers fired by on delete cascade
 Mutating tables are database tables that are affected by
o Sql statements: Tables that are currently being modified by the sql statements update,
delete or insert are mutating tables.
o Delete cascade referential integrity action: Tables that may be updated by the effects of a
declarative delete cascade referential integrity action are mutating tables.
o Triggered tables: Triggered tables and tables that use the Foreign key constraint to
reference triggered tables are considered to be mutating. Tables that are affected by
statement triggers are not mutating.
 Mutating table restrictions are intended to prevent triggers from seeing an inconsistent set of data
in a table.
 When a mutating table error is preventing you from updating a table. You can solve this problem by
storing the data affected by the trigger – the minimum and maximum salary information in this case
– in one of these objects:
o A separate temporary table
o A pl/sql package
 Mutating tables can cause more complex problems, which are more difficult to solve.
 To avoid these issues, you should consider implementing database rules in the application or middle
tier levels, not at the pl/sql level.
 You should also avoid using database triggers to implement complex business rules.

Oracle Supplied Packages:


There are a number of packages supplied with the Oracle server. These packages enable
 Access to SQL features that are usually restricted for PL/SQL
 Extended database functionality
 The most commonly used package is DBMS_OUTPUT, which was originally created to debug PL/SQL
programs.
Most significantly used oracle supplied packages are
1) DBMS_OUTPUT: This package passes textual messages between pl/sql objects – such as stored
procedures, packages and triggers – and memory buffers to enable code debugging and buffering.
The procedure comprising of dbms_output package are
a) PUT: You use the PUT procedure to pass text from pl/sql to the memory buffer. The text is
placed in the current life of the buffer.
b) NEW_LINE: It place an end of line marker in the buffer. You can use it to terminate a line you
placed in the buffer using the PUT procedure.
c) PUT_LINE: It place an entire line of information into the buffer. This combines the actions of the
PUT and NEW_LINE procedures.
d) GET_LINE: It take the current line of information from the buffer and assign it to a variable in a
pl/sql procedure. This procedure can only return character data.
e) GET_LINES: It take a number of lines of information – also called an array – from the buffer and
assign them to an array variable in a pl/sql procedure.
f) ENABLE/DISABLE: It enable and disable calls to the dbms_output procedures. If you do not
execute the ENABLE procedure, the other procedures – Get_LINE and PUT_LINE for example are
ignored. You do not need to use this procedure if you use the SET SERVEROUTPUT ON
command.
2) UTL_FILE: This package enables the reading and writing of operating system text files. It includes the
FOPEN command that you use to open a file in a specified directory for input/output(I/O). The
command returns a file handle that you can use for subsequent I/O operation on the file.
a) Before you can read or write to an OS file, you need to enable access to the file using
a. The CREATE DIRECTORY statement
b. The utl_file_dir database initialization parameter
b) You use the CREATE DIRECTORY statement from UTL_FILE package to associate an alias for an
OS directory. In the below case, the alias is called my_dir, and it is associated with the
/temp/my_files directory.
CREATE DIRECTORY my_dir AS ‘/temp/my_files’;
c) Then you use the GRANT command for the alias, which enable READ and WRITE to enable public
access to read and write functions for the OS files.
GRANT READ, WRITE ON DIRECTORY my_dir TO public;
d) In addition to the CREATE DIRECTORY statement, you can enable read and write access to OS
files by specifying the relevant path in the utl_file_dir database initialization parameter.
For example, here is the line of code that you add to the initialization file for the current
instance if you want to make the /usr/jsmith/my_app OS directory path accessible to the
UTL_FILE procedures.
UTL_FILE_DIR = /usr/jsmith/my_app
e) When you have enabled the read and write operations for the OS files, you can modify them
using the procedures and functions in the UTL_FILE package.
1) FOPEN/FCLOSE/FCLOSE_ALL: You use FOPEN to open an OS file in a specified directory for
I/O. This subprogram returns a file handle for use in subsequent I/O operations. You use
FCLOSE to close an open file.
The FCLOSE_ALL procedure closes all file handles that are open in the session.
2) IS_OPEN: You use the IS_OPEN function to check if a file is open before you modify it. The
function returns the Boolean value of TRUE if the file handle refers to an open file.
Otherwise, it returns a value of FALSE.
3) GET_LINE/NEW_LINE: You use the GET_LINE procedure to read a line of text from the OS file
to a parameter in the output buffer. The maximum size of an input record for this procedure
is 1023 bytes – unless you specify a larger size in the overloaded version of FOPEM.
The NEW_LINE procedure terminates a file in the buffer.
4) PUT/PUT_LINE/PUTF: You use the PUT and PUT_LINE procedures to write text from the
buffer to an opened OS file. The PUT procedure writes the current string.
You use the PUTF procedure to format the text. The %s format specifier substitutes a value
into the output string and \n specifies a new line character.
5) FFLUSH: You use the FFLUSH procedure to write all of the data currently in the buffer to a
file. The data must be terminated with a new line character.
The FFLUSH procedure is useful when the file must be read while still open. For example,
you can flush debug messages to the file so that they can be read immediately.
f) The package include seven exception that indicate error conditions in processing an OS file:
a. INVALID_PATH
b. INVALID_MODE
c. INVALID_FILEHANDLE
d. INVALID_OPERATION
e. READ_ERROR/WRITE_ERROR
f. INTERNAL_ERROR
3) HTP: This package enables you to write HTML tags into database buffers. Procedures in this package
allow you to generate HTML documents dynamically from a pl/sql programming environment.
Using HTP package from sql*plus.
SET SERVEROUTPUT ON
ACCEPT procname PROMT “Procedure: “
EXECUTE &procname
EXECUTE owa_util.showpage
UNDEFINE procname
Create or replace procedure html_create IS
BEGIN
Htp.htmlOpen;
Htp.headopen;
Htp.title(‘Oracle Databae’);
Htp.headclose;
Htp.bodyopen;
Htp.print(‘My oracle Database’);
Htp.bodyclose;
Htp.htmlclose;
End;
4) UTL_MAIL: This package is used to compose and send email messages using pl/sql. It provides a
utility for managing email that includes functions such as attaching data files, sending email to
multiple recipients, and configuring return receipts.
A) Utl_mail is not installed by default in your oracle db because the installation requires you to
configure a host and a port using the SMTP_OUT_SERVER parameter in the init.ora file.
Alter system set smtp_out_server = ‘smtpserver.mydomain.com’
B) If smtp_out_server is not defined, utl_mail invokes a default setting derived from the
db_domain parameter. This is a database initialization parameter that specifies the logical
location of the database within the network structure.
C) You need to execute utlmail.sql script in the database to install the utl_mail package.
D) To complete the installation of utl_mail, you need to execute prvtmail.plb script.
E) Performing the above installs the utl_mail package and you can use it to send e-mail.
F) Here is the code that creates an email message with a sender address, recipient address, a
message, a subject, CC and BCC fields, and a priority field.
Begin
Utl_mail.send(‘ahunold@easynomadtravel.com’,’wgietz@easynomadtravel.com’,
Message => ‘Vist www.easaynomadtravel.com’,
Subject => ‘Easy Nomad Travel Newsletter’,
Cc => ‘vpatabal@easynomadtravel.com’,
Bcc => ‘jchen@easynomadtravel.com’,
Priority => ‘High’
);
End;
G) To send a text or HTML message with a binary attachment, you use the
UTL_MAIL.SEND_ATTACH_RAW procedure.
5) DBMS_SCHEDULER: This package contains a number of subprograms that provide functions for
scheduling database tasks. You can use this package to control where and when database tasks are
run.
a) You use the Dbms_scheduler.create_job procedure to create a job. A job is the scheduler
component that causes something to be executed at a specified time. All jobs comprise a
program and a schedule. To create a job, the create_job system privilege is required. The name
you give the job must be in the form [schema.]name. and, once created, you need to explicitly
enable the job for it to become active and scheduled.
b) You can create jobs specifying the job details, such as the program to be executed(what) and its
schedule(when), in the arguments of the create_job procedure.
c) Begin
Dbms_scheduler.create_job(
Job_name => ‘sys.week_to_weekend’,
Job_type => ‘stored_procedure’,
Job_action => ‘sys.change_settings’,
Start_date => systimestamp,
Repeat_interval => ‘freq = weekly; byday = fri; byhour = 18’,
Enabled => true);
End;
d) Although you can specify a schedule for a job within its definition, it can be more useful to
create a discrete schedule component because it allows you to manage the scheduled execution
of multiple jobs without having to constantly update multiple job definitions. And when you
modify a schedule, each job that uses the schedule is update automatically.
e) When creating a schedule, you use the repeat_interval attribute to specify how frequently any
jobs that are assigned to the schedule should run. You set the repeat_interval attribute with an
oracle calendaring expression. The calendaring expression comprises an easytouse, intuitive
syntax that provides predictive scheduling using keywords. A calendaring expression has three
main parts: Frequency, Repeat Interval and Specifiers.
f) If you want to create a job that runs every then weeks, every nine minutes, or every four
seconds, you use a combination of the frequency and interval:
Every ten weeks – FREQ =WEEKLY; INTERVAL 10
Every ten weeks – FREQ =MINUTELY; INTERVAL 9
Every ten weeks – FREQ =SECONDLY; INTERVAL 4
g) Begin
Dbms_scheduler.create_schedule(‘weekend_schedule’,
Start_date => systimestamp,
Repeat_interval => ‘freq=weekly; byday = fri; byhour = 18’,
End date => systimestamp +90);
End;
6) DBMS_ALERT: This package supports the asynchronous notification of database events. It includes
the commit command that enables the sending of database message and alerts.
7) DBMS_SESSION: This package enables you to program using the alter session sql statement and
other session level commands.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy