pl sql
pl sql
Every PL/SQL statement ends with a semicolon (;). PL/SQL blocks can be nested within other PL/SQL
blocks using BEGIN and END. Here is the basic structure of a PL/SQL block:
DECLARE
The 'Hello World' Example:
<declarations section>
BEGIN DECLARE
<executable command(s)> message varchar2(20):= 'Hello, World!';
EXCEPTION BEGIN
<exception handling> dbms_output.put_line(message);
END; END;
/
The end; line signals the end of the PL/SQL block. To run the code from SQL command line, you may need to
type / at the beginning of the first blank line after the last line of the code. When the above code is executed at
SQL prompt, it produces following result: Hello World
PL/SQL - Data Types
PL/SQL variables, constants and parameters must have a valid data type which specifies a storage
format, constraints, and valid range of values. This tutorial will take you through SCALAR and LOB data types
available in PL/SQL and other two data types will be covered in other chapters.
Category Description
Single values with no internal components, such as a NUMBER, DATE, or
Scalar
BOOLEAN.
Pointers to large objects that are stored separately from other data items, such as
Large Object (LOB)
text, graphic images, video clips, and sound waveforms.
Data items that have internal components that can be accessed individually. For
Composite
example, collections and records.
Reference Pointers to other data items.
PL/SQL Scalar Data Types and Subtypes
PL/SQL Scalar Data Types and Subtypes come under the following categories:
Date Type Description
Numeric Numeric values on which arithmetic operations are performed.
Character Alphanumeric values that represent single characters or strings of characters.
Boolean Logical values on which logical operations are performed.
Datetime Dates and times.
PL/SQL provides subtypes of data types. For example, the data type NUMBER has a subtype called INTEGER.
Following is a valid declaration:
DECLARE
num1 INTEGER;
num2 REAL;
num3 DOUBLE PRECISION;
BEGIN
null;
END;
/
Built-in SQL functions (such as TO_CHAR)
PL/SQL functions invoked from SQL statements
PL/SQL Datetime and Interval Types
The DATE datatype to store fixed-length datetimes, which include the time of day in seconds since
midnight. Valid dates range from January 1, 4712 BC to December 31, 9999 AD.
The default date format is set by the Oracle initialization parameter NLS_DATE_FORMAT. For example, the
default might be 'DD-MON-YY', which includes a two-digit number for the day of the month, an abbreviation of
the month name, and the last two digits of the year, for example, 01-OCT-12.
Each DATE includes the century, year, month, day, hour, minute, and second.
PL/SQL Large Object (LOB) Data Types
Large object (LOB) data types refer large to data items such as text, graphic images, video clips, and
sound waveforms. LOB data types allow efficient, random, piecewise access to this data. Following are the
predefined PL/SQL LOB data types:
Data Type Description Size
Used to store large binary objects in operating system System-dependent. Cannot
BFILE
files outside the database. exceed 4 gigabytes (GB).
BLOB Used to store large binary objects in the database. 8 to 128 terabytes (TB)
Used to store large blocks of character data in the
CLOB 8 to 128 TB
database.
Used to store large blocks of NCHAR data in the
NCLOB 8 to 128 TB
database.
PL/SQL User-Defined Subtypes
A subtype is a subset of another data type, which is called its base type. A subtype has the same valid
operations as its base type, but only a subset of its valid values.
PL/SQL predefines several subtypes in package STANDARD. For example, PL/SQL predefines the subtypes
CHARACTER and INTEGER as follows:
SUBTYPE CHARACTER IS CHAR;
SUBTYPE INTEGER IS NUMBER(38,0);
You can define and use your own subtypes. The following program illustrates defining and using a user-
defined subtype:
DECLARE
SUBTYPE name IS char(20);
SUBTYPE message IS varchar2(100);
salutation name;
greetings message;
BEGIN
salutation := 'Reader ';
greetings := 'Welcome to the World of PL/SQL';
dbms_output.put_line('Hello ' || salutation || greetings);
END;
/
When the above code is executed at SQL prompt, it produces the following result:
Hello Reader Welcome to the World of PL/SQL
NULLs in PL/SQL
PL/SQL NULL values represent missing or unknown data and they are not an integer, a character, or
any other specific data type. Note that NULL is not the same as an empty data string or the null character value
'\0'. A null can be assigned but it cannot be equated with anything, including itself.
PL/SQL - Variables
The name of a PL/SQL variable consists of a letter optionally followed by more letters, numerals, dollar
signs, underscores, and number signs and should not exceed 30 characters. By default, variable names are not
case-sensitive. You cannot use a reserved PL/SQL keyword as a variable name.
Variable Declaration in PL/SQL
PL/SQL variables must be declared in the declaration section or in a package as a global variable. When you
declare a variable, PL/SQL allocates memory for the variable's value and the storage location is identified by the
variable name.
The syntax for declaring a variable is:
variable_name [CONSTANT] datatype [NOT NULL] [:= | DEFAULT initial_value]
Where, variable_name is a valid identifier in PL/SQL, datatype must be a valid PL/SQL data type or any user
defined data type which we already have discussed in last chapter. Some valid variable declarations along with
their definition are shown below:
sales number(10, 2);
pi CONSTANT double precision := 3.1415;
name varchar2(25);
address varchar2(100);
PL/SQL - Conditions
Decision-making structures require that the programmer specify one or more conditions to be evaluated
or tested by the program, along with a statement or statements to be executed if the condition is determined to be
true, and optionally, other statements to be executed if the condition is determined to be false.
IF-THEN Statement
It is the simplest form of IF control statement, frequently used in decision making and changing the
control flow of the program execution.
The IF statement associates a condition with a sequence of statements enclosed by the keywords THEN and END
IF. If the condition is TRUE, the statements get executed, and if the condition is FALSE or NULL, then the IF
statement does nothing.
Syntax for IF-THEN statement is:
IF condition THEN
S;
END IF;
Where condition is a Boolean or relational condition and S is a simple or compound statement. Example
of an IF-THEN statement is:
IF (a <= 20) THEN
c:= c+1;
END IF;
If the Boolean expression condition evaluates to true, then the block of code inside the if statement will be
executed. If Boolean expression evaluates to false, then the first set of code after the end of the if statement (after
the closing end if) will be executed.
IF-THEN-ELSE Statement
A sequence of IF-THEN statements can be followed by an optional sequence of ELSE statements, which
execute when the condition is FALSE.
Syntax for the IF-THEN-ELSE statement is:
IF condition THEN
S1;
ELSE
S2;
END IF;
Where, S1 and S2 are different sequence of statements. In the IF-THEN-ELSE statements, when the test
condition is TRUE, the statement S1 is executed and S2 is skipped; when the test condition is FALSE, then S1 is
bypassed and statement S2 is executed. For example,
IF color = red THEN
dbms_output.put_line('You have chosen a red car')
ELSE
dbms_output.put_line('Please choose a color for your car');
END IF;
If the Boolean expression condition evaluates to true, then the if-then block of code will be executed, otherwise
the else block of code will be executed.
IF-THEN-ELSIF Statement
The IF-THEN-ELSIF statement allows you to choose between several alternatives. An IF-THEN
statement can be followed by an optional ELSIF...ELSE statement. The ELSIF clause lets you add additional
conditions.
When using IF-THEN-ELSIF statements there are few points to keep in mind.
It's ELSIF, not ELSEIF
An IF-THEN statement can have zero or one ELSE's and it must come after any ELSIF's.
An IF-THEN statement can have zero to many ELSIF's and they must come before the ELSE.
Once an ELSIF succeeds, none of the remaining ELSIF's or ELSE's will be tested.
The syntax of an IF-THEN-ELSIF Statement in PL/SQL programming language is:
IF(boolean_expression 1)THEN
S1; -- Executes when the boolean expression 1 is true
ELSIF(boolean_expression 2) THEN
S2; -- Executes when the boolean expression 2 is true
ELSIF(boolean_expression 3) THEN
S3; -- Executes when the boolean expression 3 is true
ELSE
S4; -- executes when the none of the above condition is true
END IF;
Triggers
Triggers are stored programs, which are automatically executed or fired when some events occur.
Triggers are, in fact, written to be executed in response to any of the following events:
A database manipulation (DML) statement (DELETE, INSERT, or UPDATE).
A database definition (DDL) statement (CREATE, ALTER, or DROP).
A database operation (SERVERERROR, LOGON, LOGOFF, STARTUP, or SHUTDOWN).
Benefits of Triggers
Triggers can be written for the following purposes:
Generating some derived column values automatically
Enforcing referential integrity
Event logging and storing information on table access
Auditing
Synchronous replication of tables
Imposing security authorizations
Preventing invalid transactions
There are two types of triggers based on the which level it is triggered.
1) Row level trigger - An event is triggered for each row upated, inserted or deleted.
2) Statement level trigger - An event is triggered for each sql statement executed.
Let's create a BEFORE and AFTER statement and row level triggers for the product table.
1) BEFORE UPDATE, Statement Level: This trigger will insert a record into the table 'product_check' before a
sql update statement is executed, at the statement level.
CREATE or REPLACE TRIGGER Before_Update_Stat_product
BEFORE
UPDATE ON product
Begin
INSERT INTO product_check
Values('Before update, statement level',sysdate);
END;
/
2) BEFORE UPDATE, Row Level: This trigger will insert a record into the table 'product_check' before each
row is updated.
CREATE or REPLACE TRIGGER Before_Upddate_Row_product
BEFORE
UPDATE ON product
FOR EACH ROW
BEGIN
INSERT INTO product_check
Values('Before update row level',sysdate);
END;
/
3) AFTER UPDATE, Statement Level: This trigger will insert a record into the table 'product_check' after a sql
update statement is executed, at the statement level.
CREATE or REPLACE TRIGGER After_Update_Stat_product
AFTER
UPDATE ON product
BEGIN
INSERT INTO product_check
Values('After update, statement level', sysdate);
End;
/
4) AFTER UPDATE, Row Level: This trigger will insert a record into the table 'product_check' after each row is
updated.
CREATE or REPLACE TRIGGER After_Update_Row_product
AFTER
insert On product
FOR EACH ROW
BEGIN
INSERT INTO product_check
Values('After update, Row level',sysdate);
END;
/
Now lets execute a update statement on table product.
UPDATE PRODUCT SET unit_price = 800
WHERE product_id in (100,101);
Lets check the data in 'product_check' table to see the order in which the trigger is fired.
Output:
Mesage Current_Date
------------------------------------------------------------
Before update, statement level 26-Nov-2008
Before update, row level 26-Nov-2008
After update, Row level 26-Nov-2008
Before update, row level 26-Nov-2008
After update, Row level 26-Nov-2008
After update, statement level 26-Nov-2008
The above result shows 'before update' and 'after update' row level events have occured twice, since two records
were updated. But 'before update' and 'after update' statement level events are fired only once per sql statement.
The above rules apply similarly for INSERT and DELETE statements.
How To know Information about Triggers.
We can use the data dictionary view 'USER_TRIGGERS' to obtain information about any trigger.
The below statement shows the structure of the view 'USER_TRIGGERS'
DESC USER_TRIGGERS;
NAME Type
--------------------------------------------------------
TRIGGER_NAME VARCHAR2(30)
TRIGGER_TYPE VARCHAR2(16)
TRIGGER_EVENT VARCHAR2(75)
TABLE_OWNER VARCHAR2(30)
BASE_OBJECT_TYPE VARCHAR2(16)
TABLE_NAME VARCHAR2(30)
COLUMN_NAME VARCHAR2(4000)
REFERENCING_NAMES VARCHAR2(128)
WHEN_CLAUSE VARCHAR2(4000)
STATUS VARCHAR2(8)
DESCRIPTION VARCHAR2(4000)
ACTION_TYPE VARCHAR2(11)
TRIGGER_BODY LONG
This view stores information about header and body of the trigger.
SELECT * FROM user_triggers WHERE trigger_name = 'Before_Update_Stat_product';
The above sql query provides the header and body of the trigger 'Before_Update_Stat_product'.
You can drop a trigger using the following command.
DROP TRIGGER trigger_name;
CYCLIC CASCADING in a TRIGGER
This is an undesirable situation where more than one trigger enter into an infinite loop. while creating a
trigger we should ensure the such a situtation does not exist.
The below example shows how Trigger's can enter into cyclic cascading.
Let's consider we have two tables 'abc' and 'xyz'. Two triggers are created.
1) The INSERT Trigger, triggerA on table 'abc' issues an UPDATE on table 'xyz'.
2) The UPDATE Trigger, triggerB on table 'xyz' issues an INSERT on table 'abc'.
In such a situation, when there is a row inserted in table 'abc', triggerA fires and will update table 'xyz'.
When the table 'xyz' is updated, triggerB fires and will insert a row in table 'abc'.
This cyclic situation continues and will enter into a infinite loop, which will crash the databa
Stored Procedure
Overview
A stored procedure is nothing more than prepared SQL code that you save so you can reuse the
code over and over again. So if you think about a query that you write over and over again, instead of having to
write that query each time you would save it as a stored procedure and then just call the stored procedure to
execute the SQL code that you saved as part of the stored procedure.
In addition to running the same SQL code over and over again you also have the ability to pass parameters to the
stored procedure, so depending on what the need is the stored procedure can act accordingly based on the
parameter values that were passed.
A stored procedure or in simple a proc is a named PL/SQL block which performs one or more specific
task. This is similar to a procedure in other programming languages.
A procedure has a header and a body. The header consists of the name of the procedure and the parameters or
variables passed to the procedure. The body consists or declaration section, execution section and exception
section similar to a general PL/SQL Block.
A procedure is similar to an anonymous PL/SQL Block but it is named for repeated usage.
Parameters in Procedure and Functions
In PL/SQL, we can pass parameters to procedures and functions in three ways.
1) IN type parameter: These types of parameters are used to send values to stored procedures.
2) OUT type parameter: These types of parameters are used to get values from stored procedures. This is similar
to a return type in functions.
3) IN OUT parameter: These types of parameters are used to send values and get values from stored procedures.
NOTE: If a parameter is not explicitly defined a parameter type, then by default it is an IN type parameter.
1) IN parameter:
This is similar to passing parameters in programming languages. We can pass values to the stored procedure
through these parameters or variables. This type of parameter is a read only parameter. We can assign the value
of IN type parameter to a variable or use it in a query, but we cannot change its value inside the procedure.
General syntax to pass a IN parameter is
2) OUT Parameter:
The OUT parameters are used to send the OUTPUT from a procedure or a function. This is a write-only
parameter i.e, we cannot pass values to OUT paramters while executing the stored procedure, but we can assign
values to OUT parameter inside the stored procedure and the calling program can recieve this output value.
The General syntax to create an OUT parameter is
CREATE [OR REPLACE] PROCEDURE proc2 (param_name OUT datatype)
The parameter should be explicity declared as OUT parameter.
3) IN OUT Parameter:
The IN OUT parameter allows us to pass values into a procedure and get output values from the procedure. This
parameter is used if the value of the IN parameter can be changed in the calling program.
By using IN OUT parameter we can pass values into a parameter and return a value to the calling program
using the same parameter. But this is possible only if the value passed to the procedure and output value have a
same datatype. This parameter is used if the value of the parameter will be changed in the procedure.
The General syntax to create an IN OUT parameter is
CREATE [OR REPLACE] PROCEDURE proc3 (param_name IN OUT datatype)
There are two ways to execute a procedure.
1) From the SQL prompt.
EXECUTE [or EXEC] procedure_name;
2) Within another procedure – simply use the procedure name.
procedure_name;
Exception Handling
Exceptions are runtime errors or unexpected events that occur during the execution of a
PL/SQL code block. PL/SQL provides a feature to handle the Exceptions which occur in a PL/SQL
Block known as exception Handling.The oracle engine is the first one to identify such an exception
and it immediately tries to resolve it by default exception handler.The default exception handler is a
block of code predefined in the memory to take the appropriate action against exceptions.
Exception handling can be done in the EXCEPTION part of PL/SQL program code block.
Following is the syntax for it:
DECLARE -- Declaration statements; BEGIN -- SQL statements; -- Procedural statements;
EXCEPTION -- Exception handling statements; END;
Locks :
Locks are mechanism used to ensure data integrity. The oracle engine automatically locks table
data while executing SQL statements like Select/insert/UPDATE/DELETE. This type of locking is
called implicit locking
There are two types of Locks
1)Shared lock
2)Exclusive lock
Shared lock:
Shared locks are placed on resources whenever a read operation (select) is performed.
Multiple shared locks can be simultaneously set on a resource.
Exclusive lock:
Exclusive locks are placed on resources whenever a write operation (INSERT, UPDATE And DELETE) are performed.
Only one exclusive lock can be placed on a resource at a time.
i.e. the first user who acquires an exclusive lock will continue to have the sole ownership of the resource, and no
other user can acquire an exclusive lock on that resource
Levels of Locks:
Oracle does not provide a field level lock.
Oracle provides the following three levels of Locking.
a)Row level
b)Page level
c)Table level
Row Level locking
If the WHERE clause evaluates to only one row in the table, a row level lock is used.
Page Level locking
If the WHERE clause evaluates to a set of data, a page level lock is used.
Table Level locking
If there is no WHERE clause, the query accesses the entire table, a table level lock is used.
Can't update entire table data when update is done by other user.
Syntax:
LOCK TABLE <tablename> [<tablename>]….. IN { ROW SHARE / ROW EXCLUSIVE / SHARE UPDATE / SHARE / SHARE
ROW EXCLUSIVE / EXCLUSIVE}[NOWAIT]
Exclusive lock:
They allow query on the locked resource but prohibit any other activity
Example:
Run SQL Command Line
SQL> Lock table client_master IN Exclusive Mode NOWAIT;
Table(s) Locked.
Deadlock:
In a deadlock, two database operations wait for each other to release a lock.
A deadlock occurs when two users have a lock, each on a separate object, and, they want to acquire a lock on each
other's object.
When this happens, the first user has to wait for the second user to release the lock, but the second user will not
release it until the lock on the first user's object is freed. At this point, both the users are at an impasse and cannot
proceed with their business.
In such a case, Oracle detects the deadlock automatically and solves the problem by aborting one of the two
transactions.
example :
Transaction 1 BEGIN UPDATE client_master SET salary = 500 WHERE client_no=’c1’; UPDATE client_master SET
salary = 500 WHERE client_no=’c2’; END Transaction 2 BEGIN UPDATE client_master SET salary = 5000 WHERE
client_no=’c2’; UPDATE client_master SET salary = 500 WHERE client_no=’c1’; END
Assume that Transaction 1 and Transaction2 begin exactly at the same time.
By default Oracle automatically places exclusive lock on data that is being updated.
This causes Transaction 1 to wait for Transaction2 to complete but in turn Transaction2 has to wait for Transaction 1
to complete.