Professional Documents
Culture Documents
1
PL/SQL Trigger ......................................................................................................................................... 28
Advantages of Triggers .................................................................................................................... 29
PL/SQL Introduction
Creating a trigger: .............................................................................................................................. 29 PL/SQL is a block structured language that enables developers to combine
PL/SQL Trigger Example.................................................................................................................. 30
2 3
PL/SQL is a block of codes that used to Typically, each block performs a logical action in the program. A block has the following
structure:
SQL is a single query that is used to write the entire program blocks/ DECLARE
declaration statements;
perform DML and DDL operations. procedure/ function, etc.
BEGIN
executable statements
It is declarative, that defines what needs
EXCEPTIONS
to be done, rather than how things need PL/SQL is procedural that defines how the exception handling statements
4 5
brightness_4 var3 varchar2(20) := 'I Love GeeksForGeeks' ;
BEGIN Explanation:
null; Assignment operator (:=) : It is used to assign a value to a
END; variable.
/
Output: 2. Displaying Output:
The outputs are displayed by using DBMS_OUTPUT which is a built-in
package that enables the user to display output, debugging
PL/SQL procedure successfully completed. information, and send messages from PL/SQL blocks, subprograms,
Explanation: packages, and triggers.
SET SERVEROUTPUT ON: It is used to display the buffer used by Let us see an example to see how to display a message using PL/SQL
the dbms_output. :
var1 INTEGER : It is the declaration of variable,
named var1 which is of integer type. There are many other data
filter_none
types that can be used like float, int, real, smallint, long etc. It also brightness_4
supports variables used in SQL as well like NUMBER(prec, scale), SQL> SET SERVEROUTPUT ON;
varchar, varchar2 etc. SQL> DECLARE
PL/SQL procedure successfully completed.: It is displayed
var varchar2(40) := 'I love
when the code is compiled and executed successfully. GeeksForGeeks' ;
Slash (/) after END;: The slash (/) tells the SQL*Plus to execute
the block. BEGIN
dbms_output.put_line(var);
1.1) INITIALISING VARIABLES:
The variables can also be initialised just like in other programming END;
languages. Let us see an example for the same: /
filter_none Output:
brightness_4 I love GeeksForGeeks
6 7
Using Comments:
Like in many other programming languages, in PL/SQL also, comments
can be put within the code which has no effect in the code. There are two
syntaxes to create comments in PL/SQL :
Single Line Comment: To create a single line comment , the
symbol – – is used.
Multi Line Comment: To create comments that span over several
lines, the symbol /* and */ is used.
Example to show how to create comments in PL/SQL :
filter_none
edit
play_arrow The selection structure tests a condition, then executes one sequence of
brightness_4 statements instead of another, depending on whether the condition is true or false.
SQL> SET SERVEROUTPUT ON; A condition is any variable or expression that returns a BOOLEAN value (TRUE or
SQL> DECLARE FALSE).
The iteration structure executes a sequence of statements repeatedly as long as a
-- I am a comment, so i will be ignored. condition holds true.
var varchar2(40) := 'I love The sequence-structure simply executes a sequence of statements in the order in
GeeksForGeeks' ;
which they occur.
BEGIN
Want to know more about SQL? Read this extensive SQL Tutorial and
dbms_output.put_line(var);
enhance your knowledge!
END; Testing Conditions: IF and CASE Statements
/
The IF statement executes a sequence of statements depending on the
Control Structures in PL/SQL value of a condition. There are three forms of IF statements: IF-THEN, IF-
THEN-ELSE, and IF-THEN-ELSIF.
Procedural computer programs use the basic control structures.
The CASE statement is a compact way to evaluate a single condition and
choose between many alternative actions. It makes sense to use CASE
when there are three or more alternatives to choose from.
10 11
Using the EXIT Statement loop body is executed once.
Example: Using a Simple FOR LOOP Statement
The EXIT statement forces a loop to complete unconditionally. When an
DECLARE
EXIT statement is encountered, the loop completes immediately and control
p NUMBER := 0;
passes to the next statement.
BEGIN
Using the EXIT-WHEN Statement FOR k IN 1..500 LOOP -- calculate pi with 500 terms
p := p + ( ( (-1) ** (k + 1) ) / ((2 * k) - 1) );
The EXIT-WHEN statement lets a loop complete conditionally. When the END LOOP;
EXIT statement is encountered, the condition in the WHEN clause is
p := 4 * p;
evaluated. If the condition is true, the loop completes and control passes to
DBMS_OUTPUT.PUT_LINE( 'pi is approximately : ' || p ); -- print result
the next statement after the loop.
END;
Labeling a PL/SQL Loop /
Like PL/SQL blocks, loops can be labeled. The optional label, an Sequential Control: GOTO and NULL Statements
undeclared identifier enclosed by double angle brackets, must The GOTO statement is seldom needed. Occasionally, it can simplify logic enough to
appear at the beginning of the LOOP statement. The label name warrant its use. The NULL statement can improve readability by making the meaning and
can also appear at the end of the LOOP statement. When you nest action of conditional statements clear.
labeled loops, use ending label names to improve readability. Overuse of GOTO statements can result in code that is hard to understand and maintain.
Use GOTO statements sparingly. For example, to branch from a deeply nested structure
Using the WHILE-LOOP Statement to an error-handling routine, raise an exception rather than use a GOTO statement.
The WHILE-LOOP statement executes the statements in the loop body as Using the GOTO Statement
long as a condition is true:
WHILE condition LOOP The GOTO statement branches to a label unconditionally. The label must be unique within
sequence_of_statements its scope and must precede an executable statement or a PL/SQL block. When executed,
END LOOP; the GOTO statement transfers control to the labeled statement or block. The labeled
statement or block can be down or up in the sequence of statements.
Come to Intellipaat’s Community if you have queries! Example: Using a Simple GOTO Statement
DECLARE
Using the FOR-LOOP Statement
Simple FOR loops iterate over a specified range of integers. The number of p VARCHAR2(30);
iterations is known before the loop is entered. A double dot (..) serves as the n PLS_INTEGER := 37; -- test any integer > 2 for prime
range operator. The range is evaluated when the FOR loop is first entered BEGIN
and is never re-evaluated. If the lower bound equals the higher bound, the FOR j in 2..ROUND(SQRT(n)) LOOP
12 13
IF n MOD j = 0 THEN -- test for prime
p := ' is not a prime number'; -- not a prime number
GOTO print_now; Oracle / PLSQL: Sequences (Autonumber)
END IF; In Oracle, you can create an autonumber field by using sequences. A sequence is an
END LOOP; object in Oracle that is used to generate a number sequence. This can be useful when
you need to create a unique number to act as a primary key.
p := ' is a prime number';
<<print_now>>
DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p); Create Sequence
END; You may wish to create a sequence in Oracle to handle an autonumber field.
/
Syntax
Check out the top PL/SQL Interview Questions to learn what is expected from PL/SQL
The syntax to create a sequence in Oracle is:
professionals!
CREATE SEQUENCE sequence_name
Using the NULL Statement
MINVALUE value
The NULL statement does nothing and passes control to the next statement. Some MAXVALUE value
languages refer to such instruction as a no-op (no operation). START WITH value
Example: Using the NULL Statement to Show No Action
INCREMENT BY value
DECLARE
CACHE value;
v_job_id VARCHAR2(10);
v_emp_id NUMBER(6) := 110; sequence_name
BEGIN The name of the sequence that you wish to create.
SELECT job_id INTO v_job_id FROM employees WHERE employee_id = v_emp_i
d; Example
IF v_job_id = 'SA_REP' THEN
Let's look at an example of how to create a sequence in Oracle.
UPDATE employees SET commission_pct = commission_pct * 1.2;
For example:
ELSE
NULL; -- do nothing if not a sales representative CREATE SEQUENCE supplier_seq
END IF; MINVALUE 1
END;
MAXVALUE 999999999999999999999999999
/
START WITH 1
14 15
INCREMENT BY 1 This insert statement would insert a new record into the suppliers table.
The supplier_id field would be assigned the next number from
CACHE 20; the supplier_seq sequence. The supplier_name field would be set to Kraft Foods.
START WITH 1
INCREMENT BY 1
Example
Let's look at an example of how to drop a sequence in Oracle.
CACHE 20;
For example:
Now that you've created a sequence object to simulate an autonumber field, we'll
cover how to retrieve a value from this sequence object. To retrieve the next DROP SEQUENCE supplier_seq;
value in the sequence order, you need to use nextval.
This example would drop the sequence called supplier_seq.
For example:
supplier_seq.NEXTVAL;
PL/SQL - Functions
This would retrieve the next value from supplier_seq. The nextval statement
needs to be used in a SQL statement. For example: .
18 19
Example To illustrate the concept, let us calculate the factorial of a number.
Factorial of a number n is defined as −
The following example demonstrates Declaring, Defining, and
n! = n*(n-1)!
Invoking a Simple PL/SQL Function that computes and returns the = n*(n-1)*(n-2)!
maximum of two values. ...
DECLARE = n*(n-1)*(n-2)*(n-3)... 1
a number; The following program calculates the factorial of a given number
b number; by calling itself recursively −
c number;
FUNCTION findMax(x IN number, y IN number) DECLARE
RETURN number
IS
num number;
factorial number;
z number;
BEGIN
FUNCTION fact(x number)
IF x > y THEN
RETURN number
z:= x;
IS
ELSE
f number;
Z:= y;
BEGIN
END IF;
IF x=0 THEN
RETURN z;
f := 1;
END;
ELSE
BEGIN
a:= 23; f := x * fact(x-1);
b:= 45; END IF;
c := findMax(a, b); RETURN f;
dbms_output.put_line(' Maximum of (23,45): ' || c); END;
END;
/
BEGIN
When the above code is executed at the SQL prompt, it produces num:= 6;
the following result − factorial := fact(num);
dbms_output.put_line(' Factorial '|| num || ' is '
Maximum of (23,45): 45 || factorial);
END;
PL/SQL procedure successfully completed. /
PL/SQL Recursive Functions
When the above code is executed at the SQL prompt, it produces
We have seen that a program or subprogram may call another the following result −
subprogram. When a subprogram calls itself, it is referred to as a Factorial 6 is 720
recursive call and the process is known as recursion.
20 21
PL/SQL procedure successfully completed. Execution section
EXCEPTION
Exception section
Stored Procedures END;
22 23
EXECUTE [or EXEC] procedure_name; the FORALL statement. The following table provides the description of the most used
attributes −
2) Within another procedure – simply use the procedure name. S.No Attribute & Description
procedure_name;
%FOUND
NOTE: In the examples given above, we are using backward slash ‘/’ at 1
Returns TRUE if an INSERT, UPDATE, or DELETE statement affected one or more rows
the end of the program. This indicates the oracle engine that the PL/SQL or a SELECT INTO statement returned one or more rows. Otherwise, it returns FALSE.
program has ended and it can begin processing the statements.
%NOTFOUND
2 The logical opposite of %FOUND. It returns TRUE if an INSERT, UPDATE, or DELETE
PL/SQL - Cursors statement affected no rows, or a SELECT INTO statement returned no rows. Otherwise, it
returns FALSE.
In this chapter, we will discuss the cursors in PL/SQL. Oracle creates a memory area, %ISOPEN
known as the context area, for processing an SQL statement, which contains all the 3
Always returns FALSE for implicit cursors, because Oracle closes the SQL cursor
information needed for processing the statement; for example, the number of rows automatically after executing its associated SQL statement.
processed, etc.
A cursor is a pointer to this context area. PL/SQL controls the context area through a %ROWCOUNT
cursor. A cursor holds the rows (one or more) returned by a SQL statement. The set of 4
rows the cursor holds is referred to as the active set. Returns the number of rows affected by an INSERT, UPDATE, or DELETE statement, or
returned by a SELECT INTO statement.
You can name a cursor so that it could be referred to in a program to fetch and process
the rows returned by the SQL statement, one at a time. There are two types of cursors
− Any SQL cursor attribute will be accessed as sql%attribute_name as
shown below in the example.
Implicit cursors
Explicit cursors Example
Implicit Cursors We will be using the CUSTOMERS table we had created and used in the
Implicit cursors are automatically created by Oracle whenever an SQL statement is previous chapters.
executed, when there is no explicit cursor for the statement. Programmers cannot control
Select * from customers;
the implicit cursors and the information in it.
Whenever a DML statement (INSERT, UPDATE and DELETE) is issued, an implicit +----+----------+-----+-----------+----------+
cursor is associated with this statement. For INSERT operations, the cursor holds the | ID | NAME | AGE | ADDRESS | SALARY |
data that needs to be inserted. For UPDATE and DELETE operations, the cursor +----+----------+-----+-----------+----------+
identifies the rows that would be affected. | 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
In PL/SQL, you can refer to the most recent implicit cursor as the SQL cursor, which | 2 | Khilan | 25 | Delhi | 1500.00 |
always has attributes such as %FOUND, %ISOPEN, %NOTFOUND, | 3 | kaushik | 23 | Kota | 2000.00 |
and %ROWCOUNT. The SQL cursor has additional | 4 | Chaitali | 25 | Mumbai | 6500.00 |
attributes, %BULK_ROWCOUNT and %BULK_EXCEPTIONS, designed for use with | 5 | Hardik | 27 | Bhopal | 8500.00 |
24 25
| 6 | Komal | 22 | MP | 4500.00 | +----+----------+-----+-----------+----------+
+----+----------+-----+-----------+----------+
Explicit Cursors
The following program will update the table and increase the salary of each
Explicit cursors are programmer-defined cursors for gaining more control
customer by 500 and use the SQL%ROWCOUNT attribute to determine the
over the context area. An explicit cursor should be defined in the
number of rows affected −
declaration section of the PL/SQL Block. It is created on a SELECT
DECLARE Statement which returns more than one row.
total_rows number(2);
The syntax for creating an explicit cursor is −
BEGIN
UPDATE customers CURSOR cursor_name IS select_statement;
SET salary = salary + 500; Working with an explicit cursor includes the following steps −
IF sql%notfound THEN
dbms_output.put_line('no customers selected'); Declaring the cursor for initializing the memory
ELSIF sql%found THEN Opening the cursor for allocating the memory
total_rows := sql%rowcount; Fetching the cursor for retrieving the data
dbms_output.put_line( total_rows || ' customers Closing the cursor to release the allocated memory
selected ');
END IF; Declaring the Cursor
END; Declaring the cursor defines the cursor with a name and the
/
associated SELECT statement. For example −
When the above code is executed at the SQL prompt, it produces the
CURSOR c_customers IS
following result −
SELECT id, name, address FROM customers;
6 customers selected
Opening the Cursor
PL/SQL procedure successfully completed. Opening the cursor allocates the memory for the cursor and makes it ready
If you check the records in customers table, you will find that the for fetching the rows returned by the SQL statement into it. For example, we
will open the above defined cursor as follows −
rows have been updated −
OPEN c_customers;
Select * from customers;
Fetching the Cursor
+----+----------+-----+-----------+----------+
Fetching the cursor involves accessing one row at a time. For example, we will fetch
| ID | NAME | AGE | ADDRESS | SALARY |
rows from the above-opened cursor as follows −
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2500.00 | FETCH c_customers INTO c_id, c_name, c_addr;
| 2 | Khilan | 25 | Delhi | 2000.00 |
| 3 | kaushik | 23 | Kota | 2500.00 |
Closing the Cursor
| 4 | Chaitali | 25 | Mumbai | 7000.00 | Closing the cursor means releasing the allocated memory. For example, we
| 5 | Hardik | 27 | Bhopal | 9000.00 | will close the above-opened cursor as follows −
| 6 | Komal | 22 | MP | 5000.00 |
CLOSE c_customers;
26 27
Example Triggers are stored programs, which are automatically executed or fired
when some event occurs.
Following is a complete example to illustrate the concepts of Triggers are written to be executed in response to any of the following
explicit cursors &minua; events.
DECLARE
o A database manipulation (DML) statement (DELETE, INSERT, or
c_id customers.id%type;
UPDATE).
c_name customerS.No.ame%type;
c_addr customers.address%type; o A database definition (DDL) statement (CREATE, ALTER, or DROP).
CURSOR c_customers is o A database operation (SERVERERROR, LOGON, LOGOFF, STARTUP, or
SELECT id, name, address FROM customers; SHUTDOWN).
BEGIN
OPEN c_customers; Triggers could be defined on the table, view, schema, or database with
LOOP which the event is associated.
FETCH c_customers into c_id, c_name, c_addr;
EXIT WHEN c_customers%notfound; Advantages of Triggers
dbms_output.put_line(c_id || ' ' || c_name || ' '
|| c_addr); These are the following advantages of Triggers:
END LOOP;
o Trigger generates some derived column values automatically
CLOSE c_customers;
END; o Enforces referential integrity
/ o Event logging and storing information on table access
o Auditing
When the above code is executed at the SQL prompt, it produces o Synchronous replication of tables
the following result − o Imposing security authorizations
1 Ramesh Ahmedabad o Preventing invalid transactions
2 Khilan Delhi
3 kaushik Kota
4 Chaitali Mumbai
Creating a trigger:
5 Hardik Bhopal
Syntax for creating trigger:
6 Komal MP
1. CREATE [OR REPLACE ] TRIGGER trigger_name
PL/SQL procedure successfully completed
2. {BEFORE | AFTER | INSTEAD OF }
3. {INSERT [OR] | UPDATE [OR] | DELETE}
4. [OF col_name]
PL/SQL Trigger 5. ON table_name
6. [REFERENCING OLD AS o NEW AS n]
Trigger is invoked by Oracle engine automatically whenever a specified event occurs.Trigger
7. [FOR EACH ROW]
is stored into database and invoked repeatedly, when specific condition match.
8. WHEN (condition)
9. DECLARE
28 29
10. Declaration-statements
11. BEGIN
12. Executable-statements
13. EXCEPTION 1 Ramesh 23 Allahabad 20000
14. Exception-handling-statements
15. END;
2 Suresh 22 Kanpur 22000
Here,
3 Mahesh 24 Ghaziabad 24000
o CREATE [OR REPLACE] TRIGGER trigger_name: It creates or replaces
an existing trigger with the trigger_name.
4 Chandan 25 Noida 26000
o {BEFORE | AFTER | INSTEAD OF} : This specifies when the trigger
would be executed. The INSTEAD OF clause is used for creating trigger
on a view. 5 Alex 21 Paris 28000
o {INSERT [OR] | UPDATE [OR] | DELETE}: This specifies the DML
operation. 6 Sunita 20 Delhi 30000
o [OF col_name]: This specifies the column name that would be
updated.
o [ON table_name]: This specifies the name of the table associated with Create trigger:
the trigger.
Let's take a program to create a row level trigger for the CUSTOMERS table
o [REFERENCING OLD AS o NEW AS n]: This allows you to refer new and that would fire for INSERT or UPDATE or DELETE operations performed on
old values for various DML statements, like INSERT, UPDATE, and the CUSTOMERS table. This trigger will display the salary difference between
DELETE. the old values and new values:
o [FOR EACH ROW]: This specifies a row level trigger, i.e., the trigger
would be executed for each row being affected. Otherwise the trigger 1. CREATE OR REPLACE TRIGGER display_salary_changes
will execute just once when the SQL statement is executed, which is 2. BEFORE DELETE OR INSERT OR UPDATE ON customers
called a table level trigger. 3. FOR EACH ROW
4. WHEN (NEW.ID > 0)
o WHEN (condition): This provides a condition for rows for which the
5. DECLARE
trigger would fire. This clause is valid only for row level triggers.
6. sal_diff number;
7. BEGIN
PL/SQL Trigger Example 8. sal_diff := :NEW.salary - :OLD.salary;
9. dbms_output.put_line('Old salary: ' || :OLD.salary);
Let's take a simple example to demonstrate the trigger. In this example, we 10. dbms_output.put_line('New salary: ' || :NEW.salary);
are using the following CUSTOMERS table:
11. dbms_output.put_line('Salary difference: ' || sal_diff);
Create table and have records: 12. END;
13. /
ID NAME AGE ADDRESS SALARY After the execution of the above code at SQL Prompt, it produces the
following result.
30 31
Trigger created. New salary: 35000
Salary difference: 5000
Check the salary difference by procedure:
6 customers updated
Use the following code to get the old salary, new salary and salary difference
after the trigger created. Note: As many times you executed this code, the old and new both salary is
incremented by 5000 and hence the salary difference is always 5000.
1. DECLARE
2. total_rows number(2); After the execution of above code again, you will get the
3. BEGIN following result.
4. UPDATE customers
5. SET salary = salary + 5000; Old salary: 25000
6. IF sql%notfound THEN New salary: 30000
7. dbms_output.put_line('no customers updated');
Salary difference: 5000
8. ELSIF sql%found THEN
9. total_rows := sql%rowcount;
Old salary: 27000
10. dbms_output.put_line( total_rows || ' customers updated '); New salary: 32000
11. END IF; Salary difference: 5000
12. END; Old salary: 29000
13. / New salary: 34000
Salary difference: 5000
Output: Old salary: 31000
Old salary: 20000 New salary: 36000
New salary: 25000 Salary difference: 5000
Salary difference: 5000 Old salary: 33000
Old salary: 22000 New salary: 38000
New salary: 27000 Salary difference: 5000
Salary difference: 5000 Old salary: 35000
Old salary: 24000 New salary: 40000
New salary: 29000 Salary difference: 5000
Salary difference: 5000 6 customers updated
Old salary: 26000
New salary: 31000
Salary difference: 5000
Old salary: 28000
New salary: 33000
Salary difference: 5000
Old salary: 30000
32 33