Object 1 Object 2 Object 3 Object 4 Object 5
Object 1 Object 2 Object 3 Object 4 Object 5
PL/SQL is a combination of SQL along with the procedural features of programming languages. It wasdeveloped by Oracle Corporation in the early 90s to enhance the capabilities of SQL. The PL/SQL Engine: Oracle uses a PL/SQL engine to processes the PL/SQL statements. A PL/SQL code can be stored in theclient system (client-side) or in the database (server-side). About This PL SQL Programming tutorial This Oracle PL SQL tutorial teaches you the basics of programming in PL/SQL with appropriateexamples. You can use this tutorial as your guide or reference while programming with PL SQL. I willbe making this Oracle PL SQL programming tutorial as often as possible to share my knowledge in PLSQL and help you in learning PL SQL better.Even though the programming concepts discussed in this tutorial is specific to Oracle PL SQL. Theconcepts like cursors, functions and stored procedures can be used in other database systems likeSybase , Microsoft SQL server etc, with some change in syntax. This tutorial will be growing regularly;let us know if any topic related to PL SQL needs to be added or you can also share your knowledge onPL SQL with us. Lets share our knowledge about PL SQL with others. A Simple PL/SQL Block: Each PL/SQL program consists of SQL and PL/SQL statements which from a PL/SQL block.A PL/SQL Block consists of three sections: The Declaration section (optional). The Execution section (mandatory). The Exception (or Error) Handling section (optional). Declaration Section: The Declaration section of a PL/SQL Block starts with the reserved keyword DECLARE. This sectionis optional and is used to declare any placeholders like variables, constants, records and cursors, whichare used to manipulate data in the execution section. Placeholders may be any of Variables, Constantsand Records, which stores data temporarily. Cursors are also declared in this section. Object 1 Object 2 Object 3 Object 4 Object 5
Execution Section: The Execution section of a PL/SQL Block starts with the reserved keyword BEGIN and ends withEND. This is a mandatory section and is the section where the program logic is written to perform anytask. The programmatic constructs like loops, conditional statement and SQL statements form the partof execution section. Exception Section: The Exception section of a PL/SQL Block starts with the reserved keyword EXCEPTION. This sectionis optional. Any errors in the program can be handled in this section, so that the PL/SQL Blocksterminates gracefully. If the PL/SQL Block contains exceptions that cannot be handled, the Block terminates abruptly with errors.Every statement in the above three sections must end with a semicolon ; . PL/SQL blocks can be nestedwithin other PL/SQL blocks. Comments can be used to document code.This is how a sample PL/SQL Block looks.DECLAREVariable declarationBEGINProgram ExecutionEXCEPTIONException handlingEND; Advantages of PL/SQL These are the advantages of PL/SQL. Block Structures : PL SQL consists of blocks of code, which can be nested within each other.Each block forms a unit of a task or a logical module. PL/SQL Blocks can be stored in thedatabase and reused. Procedural Language Capability :
PL SQL consists of procedural language constructs such asconditional statements (if else statements) and loops like (FOR loops). Better Performance : PL SQL engine processes multiple SQL statements simultaneously as asingle block, thereby reducing network traffic. Error Handling : PL/SQL handles errors or exceptions effectively during the execution of aPL/SQL program. Once an exception is caught, specific actions can be taken depending uponthe type of the exception or it can be displayed to the user with a message.
PL/SQL Placeholders Placeholders are temporary storage area. Placeholders can be any of Variables, Constants and Records.Oracle defines placeholders to store data temporarily, which are used to manipulate data during theexecution of a PL SQL block.Depending on the kind of data you want to store, you can define placeholders with a name and adatatype. Few of the datatypes used to define placeholders are as given below.Number (n,m) , Char (n) , Varchar2 (n) , Date , Long , Long raw, Raw, Blob, Clob, Nclob, Bfile PL/SQL Variables These are placeholders that store the values that can change through the PL/SQL Block.The General Syntax to declare a variable is: variable_name datatype [NOT NULL := value ]; variable_name is the name of the variable. datatype is a valid PL/SQL datatype. NOT NULL is an optional specification on the variable. value or DEFAULT value
is also an optional specification, where you can initialize a variable. Each variable declaration is a separate statement and must be terminated by a semicolon.For example, if you want to store the current salary of an employee, you can use a variable. DECLAREsalary number (6); * salary is a variable of datatype number and of length 6.When a variable is specified as NOT NULL, you must initialize the variable when it is declared.For example: The below example declares two variables, one of which is a not null. DECLAREsalary number(4);dept varchar2(10) NOT NULL := HR Dept; The value of a variable can change in the execution or exception section of the PL/SQL Block. We canassign values to variables in the two ways given below.1) We can directly assign values to variables.The General Syntax is: variable_name:= value
What are Cursors? A cursor is a temporary work area created in the system memory when a SQL statement is executed. Acursor contains information on a select statement and the rows of data accessed by it. This temporarywork area is used to store the data retrieved from the database, and manipulate this data. A cursor canhold more than one row, but can process only one row at a time. The set of rows the cursor holds iscalled the active set.There are two types of cursors in PL/SQL: Implicit cursors: These are created by default when DML statements like, INSERT, UPDATE, and DELETE statementsare executed. They are also created when a SELECT statement that returns just one row is executed. Explicit cursors: They must be created when you are executing a SELECT statement that returns more than one row.Even though the cursor stores multiple records, only one record can be processed at a time, which iscalled as current row. When you fetch a row the current row position moves to next row.Both implicit and explicit cursors have the same functionality, but they differ in the way they areaccessed. Implicit Cursors: When you execute DML statements like DELETE, INSERT, UPDATE and SELECT statements,implicit statements are created to process these statements.Oracle provides few attributes called as implicit cursor attributes to check the status of DMLoperations. The cursor attributes available are %FOUND, %NOTFOUND, %ROWCOUNT, and %ISOPEN.For example, When you execute INSERT, UPDATE, or DELETE statements the cursor attributes tellus whether any rows are affected and how many have been affected.When a SELECT... INTO statement is executed in a PL/SQL Block, implicit cursor attributes can beused to find out whether any row has been returned by
the SELECT statement. PL/SQL returns an error when no data is selected.The status of the cursor for each of these attributes are defined in the below table. AttributesReturn Value Example % F O U N D T h e r e t u r n v a l u e i s T R U E , i f t h e D M L statements like INSERT, DELETE andUPDATE affect at least one row and if SELECT .INTO statement return at least onerow.SQL%FOUNDThe return value is FALSE, if DML statementslike INSERT, DELETE and UPDATE do not
affect row and if SELECT.INTO statementdo not return a row.%NOTFOUND The return value is FALSE, if DML statementslike INSERT, DELETE and UPDATE at leastone row and if SELECT .INTO statementreturn at least one row.SQL%NOTFOUNDThe return value is TRUE, if a DML statementlike INSERT, DELETE and UPDATE do notaffect even one row and if SELECT .INTOstatement does not return a row. %ROWCOUNT Return the number of rows affected by theDML operations INSERT, DELETE, UPDATE,SELECTSQL%ROWCOUNTFor Example: Consider the PL/SQL Block that uses implicit cursor attributes as shown below: DECLARE var_rows number(5);BEGINUPDATE employeeSET salary = salary + 1000;IF SQL %NOTFOUND THENdbms_output.put_line('None of the salaries where updated');ELSIF SQL %FOUND THENvar_rows := SQL%ROWCOUNT;dbms_output.put_line('Salaries for ' || var_rows || 'employees are updated');END IF;END; In the above PL/SQL Block, the salaries of all the employees in the employee table are updated. If none of the employees salary are updated we get a message 'None of the salaries where updated'. Elsewe get a message like for example, 'Salaries for 1000 employees are updated' if there are 1000 rows inemployee table.
Explicit Cursors An explicit cursor is defined in the declaration section of the PL/SQL Block. It is created on a SELECTStatement which returns more than one row. We can provide a suitable name for the cursor. The General Syntax for creating a cursor is as given below: CURSOR cursor_name IS select_statement; cursor_name A suitable name for the cursor. select_statement A select query which returns multiple rows. How to use Explicit Cursor? There are four steps in using an Explicit Cursor. DECLARE the cursor in the declaration section. OPEN the cursor in the Execution Section. FETCH the data from cursor into PL/SQL variables or records in the Execution Section. CLOSE the cursor in the Execution Section before you end the PL/SQL Block.1) Declaring a Cursor in the Declaration Section: DECLARECURSOR emp_cur ISSELECT *FROM emp_tblWHERE salary > 5000;
In the above example we are creating a cursor emp_cur on a query which returns the records of alltheemployees with salary greater than 5000. Here emp_tbl in the table which contains records of alltheemployees.2) Accessing the records in the cursor:Once the cursor is created in the declaration section we can access the cursor in the executionsection of the PL/SQL program. How to access an Explicit Cursor? These are the three steps in accessing the cursor.1) Open the cursor.2) Fetch the records in the cursor one at a time.3) Close the cursor
CREATE [OR REPLACE] FUNCTION function_name [parameters]RETURN return_datatype;ISDeclaration_sectionBEGINExecution_sectionReturn return_variable;EXCEPTIONexception sectionReturn return_variable;END; 1) Return Type: The header section defines the return type of the function. The return datatype can beany of the oracle datatype like varchar, number etc.2) The execution and exception section both should return a value which is of the datatype defined inthe header section.For example, lets create a frunction called ''employer_details_func' similar to the one created in storedproc 1> CREATE OR REPLACE FUNCTION employer_details_func2> RETURN VARCHAR(20);3> IS5> emp_name VARCHAR(20);6> BEGIN7> SELECT first_name INTO emp_name8> FROM emp_tbl WHERE empID = '100';9> R ETURN emp_name;10> END;11> / In the example we are retrieving the first_name of employee with empID 100 to variableemp_name.The return type of the function is VARCHAR which is declared in line no 2. The function returns the 'emp_name' which is of type VARCHAR as the return value in line no 9. How to execute a PL/SQL Function? A function can be executed in the following ways.1) Since a function returns a value we can assign it to a variable. employee_name := employer_details_func; If employee_name is of datatype varchar we can store the name of the employee by assigning thereturn type of the function to it.2) As a part of a SELECT statement SELECT employer_details_func FROM dual; 3) In a PL/SQL Statements like, dbms_output.put_line(employer_details_func); This line displays the value returned by the function. Parameters in Procedure and Functions How to pass parameters to Procedures and Functions in PL/SQL ? 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 storedprocedures. NOTE: If a parameter is not explicitly defined a parameter type, then by default it is an IN typeparameter. 1) IN parameter: This is similar to passing parameters in programming languages. We can pass values to the storedprocedure through these parameters or variables. This type of parameter is a read only parameter. Wecan assign the value of IN type parameter to a variable or use it in a query, but we cannot change itsvalue inside the procedure.The General syntax to pass a IN parameter is CREATE [OR REPLACE] PROCEDURE procedure_name (param_name1 IN datatype, param_name12 IN datatype ... )
param_name1, param_name2... are unique parameter names. datatype - defines the datatype of the variable. IN - is optional, by default it is a IN type parameter. 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, butwe can assign values to OUT parameter inside the stored procedure and the calling program can recievethis 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 theprocedure. This parameter is used if the value of the IN parameter can be changed in the callingprogram.By using IN OUT parameter we can pass values into a parameter and return a value to the callingprogram using the same parameter. But this is possible only if the value passed to the procedure andoutput value have a same datatype. This parameter is used if the value of the parameter will be changedin the procedure.The General syntax to create an IN OUT parameter is CREATE [OR REPLACE] PROCEDURE proc3 (param_name IN OUT datatype) The below examples show how to create stored procedures using the above three types of parameters.Example1: Using IN and OUT parameter:
Lets create a procedure which gets the name of the employee when the employee id is passed. 1> CREATE OR REPLACE PROCEDURE emp_name (id IN NUMBER, emp_name OUT NUMBER)2> IS3> BEGIN4> SELECT first_name INTO emp_name5> FROM emp_tbl WHERE empID = id;6> END;7> /
INSERT INTO product_checkValues('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_productBEFOREUPDATE ON productFOR EACH ROWBEGININSERT INTO product_checkValues('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_productAFTERUPDATE ON productBEGININSERT INTO product_checkValues('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 AFTERinsert On productFOR EACH ROWBEGININSERT INTO product_checkValues('After update, Row level',sysdate);END;/ Now lets execute a update statement on table product. UPDATE PRODUCT SET unit_price = 800WHERE product_id in (100,101); Lets check the data in 'product_check' table to see the order in which the trigger is fired. SELECT * FROM product_check; Output: Mesage Current_Date-----------------------------------------------------------Before update, statement level 26-Nov-2008Before update, row level 26-Nov-2008After update, Row level 26-Nov-2008Before update, row level 26-Nov-2008After update, Row level 26-Nov-2008After update, statement level 26-Nov-2008The above result shows 'before update' and 'after update' row level events have occured twice, sincetwo records were updated. But 'before update' and 'after update' statement level events are fired onlyonce 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 LONGThis 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 atrigger 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 database.