PL/SQL Block Structure ExmapleDECLAREage NUMBER;name VARCHAR2(128) := Surinder;salary NUMBER;BEGINage := 20;SELECT income into salary from employee_income where name is%Surinder%;DBMS_OUTPUT.PUT_LINE(name: || name || age : ||TO_CHAR(age));END;
SET SERVEROUTPUT ON● The SERVEROUTPUT can be used to control the output from SERVER.● Syntax: SET SERVEROUTPUT ON● On all the scripts, you will find SET SERVEROUTPUT ON at the top to display output from Oracle Database Server.● NOTE: If you do not see an expected output from DBMS_OUTPUT packages, check whether SERVEROUTPUT is on.
Anonymous Block● An anonymous block doesnt have a name. It has executable statements between BEGIN and END.● If you would like to execute a function from another package, you must put the call in an anonymous block.● Example : BEGIN call to a function from another package. END; /
Anonymous Block● NOTE: The anonymous block is widely used for simple things. We will use this several times in future programs.
PUT_LINE : print character strings● The DBMS_OUTPUT.PUT_LINE () function is used to display string output. SET SERVEROUTPUT ON BEGIN DBMS_OUTPUT.PUT_LINE(INDIA); END; /
Concatenation using || operator● The || operator is used for string concatenation.● It is widely used in PUT_LINE() function when two different strings needs to be displayed.
TO_CHAR : Convert to CHAR● The TO_CHAR() function is used mostly to convert an integer to character.● This is widely used in PUT_LINE() function that displays only character strings.● Example: SET SERVEROUTPUT ON BEGIN DBMS_OUTPUT.PUT_LINE(SURINDER IS || TO_CHAR(31) || years old); END; /
Identifiers● The identifiers are used to name PL/SQL items like variables, cursors, subprograms (procedures, functions) and packages.● The size of the identifier cannot exceed 30 characters.● The reserved words like BEGIN, END cannot be used as an identifier name.● They can contain any sequence of printable characters.● The characters such as hyphens, slashes, and spaces are not allowed in normal identifier.
Identifiers● Examples : X t2 phone# credit_limit LastName oracle$number● NOTE: PL/SQL also allows quoted identifiers (identifiers can be enclosed in double quotes). The quoted identifiers is a poor programming practice. So "A+B" is a valid identifier but we should avoid such things.
Literals● Boolean Literal: The boolean literals are pre-defined values TRUE, FALSE, NULL.● Character Literal : A character literal is just one character enclosed within a single quote.● String Literal : A string literal is a sequence of zero or more characters enclosed by single quote (please note the single quote).● Numeric Literal: The E is used to represent numeric literal. The E stands for times ten to the power of.● Example : 5E3 = 5 x 10**3 = 5 x 1000 = 5000 5E-3 = 5 x 10**-3 = 5 x .001 = .005
Comments● The single line comments are specified using -- (double hyphen).● The multi-line comments are specified using /* and */● Example : -- This is a comment /* This is another comment the comment continues */
Declarations - Variables● The variables are declared in DECLARE section of PL/SQL block. DECLARE birthday DATE; part_no NUMBER(6); part_name VARCHAR2(20); in_stock BOOLEAN; part_price NUMBER(6,2);
Declarations – Variables Example● SET SERVEROUTPUT ON DECLARE firstname VARCHAR2(14); birthday DATE; BEGIN firstname := Swathi; birthday := 01-MAY-1990; DBMS_OUTPUT.PUT_LINE(Name = || firstname); -- default date format is dd-mon-yy DBMS_OUTPUT.PUT_LINE(BDAY = || TO_CHAR(birthday, DD-MON- YYYY)); END;
Assigning Values to a Variable● The value can be assigned to PL/SQL variables using :=.● Example : SET SERVEROUTPUT ON DECLARE country VARCHAR2(128); BEGIN -- assign value using := country := India; DBMS_OUTPUT.put_line(country = || country); END;● Output : country = India
SELECT INTO: PL/SQL Variables● The data from the table column can be read into a PL/SQL variable by using SELECT INTO.● It will work only if the SELECT returns a single row.● Example : SET SERVEROUTPUT ON DECLARE bonus NUMBER(8,2); emp_id NUMBER(6) := 100; BEGIN SELECT salary * 0.10 INTO bonus FROM employees WHERE employee_id = emp_id; DBMS_OUTPUT.PUT_LINE(Bonus = || bonus); END; /
Constant Variable● To declare a constant, put the keyword CONSTANT before the type specifier.● A constant must be initialized in its declaration.● No further assignments to the constant are allowed.
Default Values● You can use the keyword DEFAULT instead of the assignment operator to initialize variables. -- set blood type to O blood_type CHAR DEFAULT O;
Declaring Table Column Variables - %TYPE● The %TYPE attribute provides the datatype of a variable or database column.● This is particularly useful when declaring variables that will hold database values.● Example : - The table employees has a column called last_name. - To declare a variable named v_last_name that has the same datatype as column last_name, use dot notation and the %TYPE attribute, as follows: v_last_name employees.last_name%TYPE; - Declaring v_last_name with %TYPE has two advantages: * You need not know the exact datatype of last_name. * If you change the database definition of last_name, the datatype of v_last_name changes accordingly at run time.
Declaring Table Row Variables - %ROWTYPE● Records are used to group data in PL/SQL● A record consists of a number of related fields in which data values can be stored.● The %ROWTYPE attribute provides a record type that represents a row in a table.● The record can store an entire row of data selected from the table or fetched from a cursor or cursor variable.● Columns in a row and corresponding fields in a record have the same names and datatypes.● In the following example, you declare a record named dept_rec. Its fields have the same names and datatypes as the columns in the departments table.
Declaring Table Row Variables - %ROWTYPE Example SET SERVEROUTPUT ON DECLARE CURSOR c1 IS SELECT last_name, salary, hire_date, job_id FROM employees WHERE employee_id = 120; employee_rec c1%ROWTYPE; BEGIN OPEN c1; FETCH c1 INTO employee_rec; DBMS_OUTPUT.PUT_LINE(Employee name: || employee_rec.last_name); END;● Output : Employee name: Weiss
Declaring PL/SQL Subprograms● Subprograms are named PL/SQL blocks that can be called with a set of parameters.● PL/SQL has two types of subprograms: procedures and functions.
Declaring PL/SQL Subprograms - Example SET SERVEROUTPUT ON DECLARE in_string VARCHAR2(100) := This is my test string.; out_string VARCHAR2(200); PROCEDURE double ( original IN VARCHAR2, new_string OUT VARCHAR2 ) AS BEGIN new_string := original || original; END; BEGIN double(in_string, out_string); DBMS_OUTPUT.PUT_LINE(out_string = || out_string); END;● Output : out_string = This is my test string.This is my test string.
ACCEPT & PROMPT● The ORACLE PL/SQL allows the data to be entered externally through keyboard using ACCEPT & PROMPT.● Anything after PROMPT will be displayed and the data entered will be stored in a variable after ACCEPT● Example : -- display a prompt and accept value into a variable. -- The value will be stored in ENUMBER ACCEPT ENUMBER NUMBER PROMPT Employee ID : SELECT EMAIL FROM EMPLOYEES WHERE EMPLOYEE_ID=&ENUMBER; Output : Employee ID : 100 EMAIL ------------------------- SKING
NUMBER Datatype● Syntax : NUMBER[(precision,scale)] - Precision is the total number of digits. - Scale is the number of digits to the right of the decimal point. For integers which have no decimal point, use NUMBER(precision).
NUMBER Datatype Example SET SERVEROUTPUT ON DECLARE x NUMBER(3); BEGIN x := 123.89; DBMS_OUTPUT.PUT_LINE(The value of x is || TO_CHAR(x)); END;● Output : The value of x is 124
PLS_INTEGER Datatype● THE PLS_INTEGER datatype is used to store signed integers that fits in 32 bits.● The PLS_INTEGER values require less storage than NUMBER values and NUMBER subtypes.● The PLS_INTEGER operations are faster than NUMBER operations as it uses hardware arithmetic instead of library arithmetic.
CHAR Data Type● The syntax follows: CHAR[(maximum_size [CHAR | BYTE] )] - Specify the size in terms of bytes or characters, where each character contains one or more bytes, depending on the character set encoding.
CHAR Data Type Exmaple SET SERVEROUTPUT ON DECLARE firstname CHAR(10 CHAR); lastname CHAR(10 BYTE); BEGIN firstname := Swathi; lastname := Matsya; DBMS_OUTPUT.PUT_LINE(First Name = || firstname); DBMS_OUTPUT.PUT_LINE(Last Name = || lastname); END;● Output : First Name = Swathi Last Name = Matsya
VARCHAR2 Datatype● VARCHAR2 datatype is used to store variable-length character data.● Syntax : VARCHAR2(maximum_size [CHAR | BYTE]) - The variable-length column will occupy only the amount of data that we store in them and not the size that we have specified in the column. - Small VARCHAR2 variables are optimized for performance, and larger ones are optimized for efficient memory use. - The cutoff point is 2000 bytes. - For a VARCHAR2 that is declared to be 2000 bytes or longer, PL/SQL dynamically allocates only enough memory to hold the actual value.
VARCHAR2 Datatype - For a VARCHAR2 variable that is declared to be shorter than 2000 bytes, PL/SQL preallocates the full declared length of the variable. It is considered similar to CHAR.● Example : first_name VARCHAR2(2010); -- >= 2000 use only memory that is really required last_name VARCHAR2(500); -- < 2000, use full size, normal CHAR.● If we store "hi" and "bye" as first_name and last_name.● The first_name will occupy only 2 bytes (only 2 bytes are required) and last_name will occupy 500 bytes as its data type has size less than 2000 so we should treat is CHAR.
TIMESTAMP Datatype● The datatype TIMESTAMP, which extends the datatype DATE, stores the year, month, day, hour, minute, and second.● Syntax : TIMESTAMP[(precision)] - The optional parameter precision specifies the number of digits in the fractional part of the seconds field. - The precision must be in the range 0 .. 9. The default is 6.
TIMESTAMP Datatype Example SET SERVEROUTPUT ON DECLARE checkout TIMESTAMP(3); BEGIN checkout := 10-JUL-1980 07:48:53.275; DBMS_OUTPUT.PUT_LINE( TO_CHAR(checkout)); END;● Output : 10-JUL-80 07.48.53.275 AM
PL/SQL Subtypes● You can create new data types using SUBTYPE.● The SUBTYPE is defined in declarative part.● Syntax : SUBTYPE subtype_name IS base_type[(constraint)] [NOT NULL];● The PL/SQL predefines the subtypes CHARACTER as follows: SUBTYPE CHARACTER IS CHAR;● Examples : DECLARE SUBTYPE pinteger IS PLS_INTEGER RANGE -9 .. 9; -- based on range SUBTYPE ID_Num IS employees.employee_id%TYPE; -- based on column type
CURRENT_TIMESTAMP● The current_timestamp shows the value of current timestamp.● sqlplus> select current_timestamp from dual; CURRENT_TIMESTAMP ----------------- 11-DEC-11 01.18.38.256784000 PM +05:30 1 rows selected● sqlplus>
Control Structures● Procedural computer programs use the basic control structures * Selection * Iteration * Sequence
Selection Structures● It tests a condition, then executes one sequence of statements instead of another, depending on whether the condition is true or false. A condition is any variable or expression that returns a BOOLEAN value (TRUE or FALSE).● For Selection we use IF Statements and CASE Statements
Iteration structure● Its executes a sequence of statements repeatedly as long as a condition holds true.● For iteratation we use Loop Statements and Exit Statements
Sequence structure● It simply executes a sequence of statements in the order in which they occur.● For sequence we use Goto Statements and Null Statements
IF - THEN - ELSE● Syntax : IF (condition1) THEN stmt1; ELSIF (condition2) THEN stmt2; ELSE stmt3; ENDIF● Description : - The sequence of statements is executed only if the condition is TRUE. - If the condition is FALSE or NULL, the IF statement does nothing. - In either case, control passes to the next statement.
IF - THEN – ELSE Example -- This is source file SET SERVEROUTPUT ON; ACCEPT v_emp_id NUMBER PROMPT Employee ID : DECLARE BEGIN IF ( &v_emp_id < 50 ) THEN DBMS_OUTPUT.PUT_LINE(employee id < 50); ELSE DBMS_OUTPUT.PUT_LINE(employee id >= 50); END IF ; END;● Output : Employee ID : 40 employee id < 50
CASE : Simple Expression● The CASE statement selects one sequence of statements to execute similar to IF.● The expression is evaluated once and its value is matched with several blocks whichever matches first, we execute that block.● It starts with CASE with a series of WHEN-THEN statments and ends with END CASE.
CASE : Simple Expression● Syntax : CASE expr WHEN v1 THEN stmt1; WHEN v2 THEN stmt2; WHEN v3 THEN stmt3; END CASE
CASE : Simple Expression Example SET SERVEROUTPUT ON DECLARE grade CHAR(1); BEGIN grade := B; CASE grade WHEN A THEN DBMS_OUTPUT.PUT_LINE(Excellent); WHEN B THEN DBMS_OUTPUT.PUT_LINE(Very Good); WHEN C THEN DBMS_OUTPUT.PUT_LINE(Good); WHEN D THEN DBMS_OUTPUT.PUT_LINE(Fair); WHEN F THEN DBMS_OUTPUT.PUT_LINE(Poor); ELSE DBMS_OUTPUT.PUT_LINE(No such grade); END CASE; END;● Output : Very Good.
CASE : Searched Expression● PL/SQL also provides a searched CASE statement, similar to the simple CASE statement.● A searched CASE expression lets you test different conditions instead of comparing a single expression to various values.
CASE : Searched Expression Example-- This is source fileSET serveroutput ON;ACCEPT MARKS NUMBER PROMPT Enter marks scored (0 to 100) : DECLAREBEGIN CASE WHEN &marks >= 75 THEN BEGIN DBMS_OUTPUT.PUT_LINE(PASS : Distinction); END; WHEN &marks >= 60 THEN BEGIN DBMS_OUTPUT.PUT_LINE(PASS : First Division); END;
CASE : Searched Expression ExampleWHEN &marks >= 50 THEN BEGIN DBMS_OUTPUT.PUT_LINE(PASS : Second Division); END;WHEN &marks >= 40 THEN BEGIN DBMS_OUTPUT.PUT_LINE(PASS : Third Division); END;WHEN &marks < 40 THEN BEGIN DBMS_OUTPUT.PUT_LINE(FAILED); END;END CASE;END;
CASE : Searched Expression Example● Output : Enter marks scored (0 - 100) : 50 PASS : Second Division Enter marks scored (0 - 100) : 30 FAILED
Looping Statements● The looping tatements execute a sequence of statements multiple times.● There are three forms of LOOP statements: * LOOP * WHILE-LOOP * FOR-LOOP
LOOP Statement● Simplest form of loop is a sequence of statments between LOOP and END LOOP.● Syntax : LOOP sequence_of_statements END LOOP;● With each iteration of the loop, the sequence of statements is executed, then control resumes at the top of the loop.
Exit statement● When an EXIT statement is encountered, the loop completes immediately and control passes to the next statement after END LOOP; LOOP IF (expr) THEN EXIT; END IF; other statements; END LOOP;
EXIT WHEN Statement● The EXIT-WHEN statement lets a loop complete conditionally. When the EXIT statement is encountered, the condition in the WHEN clause is evaluated. LOOP EXIT WHEN condition; other statements; END LOOP;
LOOP Statement ExampleSET SERVEROUTPUT ON ● Output :DECLARE i=1 i NUMBER := 0; i=2BEGIN i=3 LOOP i=4 i := i + 1 ; i=5 DBMS_OUTPUT.PUT_LINE(i = ||i); EXIT WHEN i = 5; END LOOP;END;
WHILE LOOP● The WHILE-LOOP statement executes the statements in the loop body as long as a condition is true: WHILE condition LOOP sequence_of_statements END LOOP;● Before each iteration of the loop, the condition is evaluated.● If it is TRUE, the sequence of statements is executed, then control resumes at the top of the loop.● If it is FALSE or NULL, the loop is skipped and control passes to the next statement.
WHILE LOOP● The equivalent in PL/SQL would be:● NOTE: The WHILE LOOP can be rewrriten as LOOP sequence_of_statements EXIT WHEN condition; END LOOP;
SET SERVEROUTPUT ON ● Output :DECLARE i=1i NUMBER := 0; i=2BEGIN i=3WHILE (i != 5) i=4LOOP i=5 i := i + 1 ;DBMS_OUTPUT.PUT_LINE(i= || i);END LOOP;END;
FOR LOOP● Simple FOR loops iterate over a specified range of integers. The number of iterations is known before the loop is entered.● A double dot (..) serves as the range operator.● The range is evaluated when the FOR loop is first entered and is never re-evaluated.● After each iteration, the loop counter is incremented.
FOR LOOP ExampleSET SERVEROUTPUT ON ● Output :DECLARE i=1i NUMBER := 0; i=2BEGIN i=3FOR i IN 1..5 i=4LOOP i=5DBMS_OUTPUT.PUT_LINE(i= || TO_CHAR(i));END LOOP;END;
LOOP Example using HR Schema :SET serveroutput ON;DECLARE min_id employees.employee_id%TYPE; max_id employees.employee_id%TYPE; mail employees.email%TYPE;BEGIN SELECT MIN(employee_id) INTO min_id FROM employees; SELECT MAX(employee_id) INTO max_id FROM employees; FOR id IN min_id..max_id LOOP SELECT EMAIL INTO MAIL FROM EMPLOYEES WHERE employee_id=id; DBMS_OUTPUT.PUT_LINE( EMPLOYEE_ID : || TO_CHAR(id) || EMAIL : || MAIL); END LOOP;END;
GOTO Statement● The GOTO statement branches to a label unconditionally.● The label must be unique within its scope and must precede an executable statement.● When executed, 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.● The labels are enclosed between angular brackets. << and >>.● You dont need : after labels (used by c lang.).
GOTO Statement ExampleSET serveroutput ON;ACCEPT country_p CHAR PROMPT Enter country (india or australia) : DECLARE country CHAR(20);BEGIN country := &country_p; IF country = australia THEN GOTO australia; ELSIF country = india THEN GOTO india; ELSE GOTO none; END IF;
GOTO Statement Example <<india>> DBMS_OUTPUT.put_line(sachin); GOTO none; <<australia>> DBMS_OUTPUT.put_line(ricky); <<none>> NULL; END;● Output : Enter country (india or australia) : india sachin
NULL Statement● The goto label must precede an executable statement.● In case there is none, you must use a NULL Statement.● A NULL statement is an executable statement that doesnt do anything.● Syntax: NULL;
Collections● An ordered group of elements, all of the same type.● It is a general concept that encompasses lists, arrays, and other datatypes used in classic programming algorithms.● Each element is addressed by a unique subscript.● PL/SQL offers these collection types:● Associative arrays (index-by tables), let it allow look up elements using arbitrary numbers and strings for subscript values. These are similar to hash tables in other programming languages.● Nested tables hold an arbitrary number of elements. They use sequential numbers as subscripts.● Varrays (short for variable-size arrays) hold a fixed number of elements . They use sequential numbers as subscripts.
Associative Array● Associative arrays are also called Hashes.● It is a collection of key-value pairs.● Syntax: TYPE <NEWTYPE> is TABLE of <TYPE1> INDEX BY <TYPE2>; TYPE swa_type is TABLE of NUMBER INDEX BY VARCHAR2(30);
Associative Array ExampleSET serveroutput ONDECLARE -- declare hash TYPE word_num_t IS TABLE OF NUMBER INDEX BY VARCHAR2(30); wn word_num_t; KEY VARCHAR2(30);BEGIN wn(one) := 1; wn(two) := 2; wn(three) := 3; wn(four) := 4; KEY := wn.FIRST; WHILE (KEY IS NOT NULL) LOOP DBMS_OUTPUT.put_line(KEY || = || TO_CHAR(wn(KEY))); KEY := wn.next(KEY); END LOOP;END;
Associative Array Example● Output : four = 4 one = 1 three = 3 two = 2
Nested Tables● Nested tables represent sets of values.● It is like a one-dimensional arrays with no declared number of elements.● It is indexed with numbered subscript.● Syntax: TYPE nested_type IS TABLE OF VARCHAR2(30);
Nested Tables Example SET SERVEROUTPUT ON DECLARE TYPE color_t IS TABLE OF VARCHAR2(30); colors color_t; idx NUMBER; BEGIN colors := color_t(Red, Blue, Green); idx := colors.FIRST; WHILE (idx IS NOT NULL) LOOP DBMS_OUTPUT.put_line(TO_CHAR(idx) || || colors(idx)); idx := colors.next(idx); END LOOP; END;● Output : 1 Red 2 Blue 3 Green
Varrays● VARRAY (also known as varrays) has a maximum size that is specified during type definition.● Syntax: TYPE varray_type IS VARRAY(5) OF %TYPE%;
Varrays Example SET SERVEROUTPUT ON DECLARE TYPE month_t IS VARRAY(12) OF VARCHAR2(20); months month_t; idx NUMBER; BEGIN months := month_t(Jan, Feb, Mar); idx := months.FIRST; WHILE (idx IS NOT NULL) LOOP DBMS_OUTPUT.put_line(TO_CHAR(idx) || || months(idx)); idx := months.next(idx); END LOOP; END;● Output : 1 Jan 2 Feb 3 Mar
Introduction● A user-define pl/sql block is fired when a DML statements like Insert, Delete, Update is executed on a database table.● A trigger is fired when the triggering DML statement is executed.● Syntax : CREATE [OR REPLACE] TRIGGER trigger_name BEFORE (or AFTER) INSERT OR UPDATE [OF COLUMNS] OR DELETE ON tablename [FOR EACH ROW [WHEN (condition)]] BEGIN ...sql statements END;
Introduction● CREATE [OR REPLACE] TRIGGER trigger_name : Creates a trigger with the given trigger_name or replace(overwrites) an existing trigger with the same trigger_name.● BEFORE (or AFTER) : Indicate when you want to fire the trigger, either before or after the database modification (update, delete, insert) .● INSERT OR UPDATE [OF COLUMNS] OR DELETE : This are the triggering events. You can use More than one triggering events together separated by OR keyword. Whenever the triggering event occurs trigger gets fired. [OF col_name] is used with update triggers. Used only when you want to trigger an event when a particular column is updated.
Introduction● [FOR EACH ROW [WHEN (condition)]] : Used to determine whether a trigger must fire when each row gets affected ( i.e. a Row Level Trigger) or just once when the entire sql statement is executed(i.e.statement level Trigger). WHEN (condition) is used only for row level triggers. The trigger is fired for each rows that satisfy the condition specified.● The PL/SQL block (between BEGIN and END) is a block where you can place the PL/SQL commands.
Trigger ExampleCREATE OR REPLACE TRIGGER JOBS_HISTORY_TRIGGERBEFOREUPDATE OF MIN_SALARY ON JOBS FOR EACH ROW BEGININSERTINTO jobs_history VALUES ( :old.job_id, :old.job_title, :old.min_salary, :old.max_salary );END;
Viewing Triggers● To see all your user defined triggers by doing a select statement on USER_TRIGGERS.● Syntax : SELECT TRIGGER_NAME FROM USER_TRIGGERS;● It will display the names of all triggers.● You can also select columns for detailed trigger information.● You can also select TRIGGER_TYPE, TRIGGER_EVENT, TRIGGER_BODY etc.
Viewing Triggers Example● SELECT TRIGGER_BODY FROM USER_TRIGGERS WHERE TRIGGER_NAME=JOBS_HISTORY_TRIGGER;● Output : TRIGGER_BODY -------------------------------------------- BEGIN INSERT INTO JOBS_HISTORY VALUES ( :OLD.JOB_ID, :OLD.JOB_TITLE, :OLD.MIN_SALARY, :OLD.MAX_SALARY ); END;
Dropping Triggers● By using DROP TRIGGER statement you can drop the database trigger from the database.● Syntax : DROP TRIGGER trigger_name;● Example : DROP TRIGGER JOB_HISTORY_TRIGGER● This will drop the trigger name job_history_trigger.
Altering Triggers● By using ALTER TRIGGER statement you can alter the database trigger.● Syntax : ALTER TRIGGER trigger_name [ENABLE|DISABLE];● Without dropping the trigger you can DISABLE the present trigger using the above syntax.● Whenevr you want to fire the trigger you can ENABLE it.
Restrictions on triggers● The size of the trigger is 32k.● A trigger can contain all DML statements, SELECT INTO statement and SELECT statement in cursor definition.● LONG and LONG RAW datatypes cannot be used in variale declaration.● :NEW and :PARENT cannot be used with LONG and LONG RAW columns.● You cant use the ROLLBACK, COMMIT, SAVEPOINT statement in triggger.