As an extension of native sql, PL/SQL has Procedural Language features of programming languages. like block structures what it consists of blocks of code, can be nested within each other, can be stored in database and be reused, another advantage of PL/SQL is performance, PL SQL engine processes multiple SQL statements simultaneously as a single block, thereby reducing network traffic. In this section i will list a lot of demo code to demonstrate referenced theroy. For PL/SQL has Procedural language feature, so this section will list as: Variables, Constants, Records, Conditional Statements, Iterative Statements...
In order to convenient Demo code, we create employee table and add some data to employee table as following:
create table employee( emp_id number(10) primary key not null, first_name varchar2(25), last_name varchar2(25), dept varchar2(10), salary number(6) ); insert into employee values(1111, 'Kylin', 'Soong', 'BPM', 8000); insert into employee values(1112, 'Kylin', 'Soong', 'BPM', 8000); insert into employee values(1113, 'Kylin', 'Soong', 'BPM', 8000); insert into employee values(1114, 'Kylin', 'Soong', 'BPM', 9000); insert into employee values(1115, 'Kylin', 'Soong', 'BPM', 9000); insert into employee values(1116, 'Kylin', 'Soong', 'BPM', 9000);
1. Variables
Variables are kinds of Placeholders, which are temporary storage area. which are used to manipulate data during the execution of a PL SQL block. According to the scope of variables, variables can be classify into 2 kinds: Local variables which are declared in a inner block and cannot be referenced by outside Blocks; Global variables which are declared in a outer block and can be referenced by its itself and by its inner blocks. As following code block:
DECLARE var_num1 number; var_num2 number; BEGIN var_num1 := 100; var_num2 := 200; DECLARE var_mult number; BEGIN var_mult := var_num1 * var_num2; dbms_output.put_line('var_mult '|| var_mult); END; dbms_output.put_line('var_num1 '|| var_num1); dbms_output.put_line('var_num2 '|| var_num2); END; /
In the above code block, the variable 'var_mult' is declared in the inner block, so cannot be accessed in the outer block . The variables 'var_num1' and 'var_num2' can be accessed anywhere in the block.
2. Constants
As the name implies a constant is a value used in a PL/SQL Block that remains unchanged throughout the program. You must assign a value to a constant at the time you declare it. If you do not assign a value to a constant while declaring it and try to assign a value in the execution section, you will get a error. The following code is a Constants usege demo:
DECLARE salary_increase CONSTANT number(3) := 100; BEGIN dbms_output.put_line (salary_increase); END; /
3. Records
1> What are records?
Records are another type of datatypes which oracle allows to be defined as a placeholder. Records are composite datatypes, which means it is a combination of different scalar datatypes like char, varchar, number etc. Each scalar data types in the record holds a value. A record can be visualized as a row of data. It can contain all the contents of a row.
2> Declaring a record:
To declare a record, you must first define a composite datatype; then declare a record for that type. If all the fields of a record are based on the columns of a table, we can declare the record as follows:
record_name table_name%ROWTYPE
3> Passing Values To and From a Record
When you assign values to a record, you actually assign values to the fields within it. The General Syntax to assign a value to a column within a record direclty is: record_name.col_name := value;
DECLARE TYPE employee_type IS RECORD ( employee_id number(5), employee_first_name varchar2(25), employee_last_name employee.last_name%type, employee_dept employee.dept%type ); employee_salary employee.salary%type; employee_rec employee_type; employee_rec_all employee%ROWTYPE; var_emp_id number(6) := 1116; var_test_1 varchar2(25); var_test_2 varchar2(25); BEGIN SELECT first_name, last_name, dept INTO employee_rec.employee_first_name, employee_rec.employee_last_name, employee_rec.employee_dept from employee where emp_id = var_emp_id; SELECT * INTO employee_rec_all from employee where emp_id = var_emp_id; var_test_1 := employee_rec.employee_first_name; dbms_output.put_line(var_test_1); var_test_2 := employee_rec_all.first_name; dbms_output.put_line(var_test_2); commit; END; /
The above code block define 2 Records: employee_rec and employee_rec_all, the red, bold sentence explain how to pass value to Record employee_rec one by one; the blue bold sentence demonstrate how to pass values to Record employee_rec_all as a whole, and the black bold sentence show pass valurs from a Record.
4. Conditional Statements & Iterative Statements
As a professional coding programmer, I do not write more about condition Statements and Iterative statements in this section, I will use condition Statements and Iterative statements in the following section directly.
5. Cursors
1> What are cursors?
A cursor is a temporary work area created in the system memory when a SQL statement is executed. A cursor contains information on a select statement and the rows of data accessed by it. This temporary work area is used to store the data retrieved from the database, and manipulate this data. A cursor can hold more than one row, but can process only one row at a time. The set of rows the cursor holds is called the active set.
2> Two types of Cursor:
Implicit cursors: These are created by default when DML statements like, INSERT, UPDATE, and DELETE statements are 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 is called as current row. When you fetch a row the current row position moves to next row.
3> Implicit Cursors:
DECLARE var_rows number(5); BEGIN UPDATE employee SET salary = salary + 1000; IF SQL%NOTFOUND THEN dbms_output.put_line('None of the salaries where updated'); ELSIF SQL%FOUND THEN var_rows := SQL%ROWCOUNT; dbms_output.put_line('Salaries for ' || var_rows || ' employees are updated'); END IF; commit; END; /
In the above PL/SQL Block, the salaries of all the employees in the ‘employee’ table are updated. If none of the employee’s salary are updated we get a message 'None of the salaries where updated'. Else we get a message like for example, 'Salaries for 1000 employees are updated' if there are 1000 rows in ‘employee’ table.
4> Explicit Cursors
1) 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.
2) How to access an Explicit Cursor?
These are the three steps in accessing the cursor:
Open the cursor.
Fetch the records in the cursor one at a time.
Close the cursor.
5> Explicit Cursor Demo
DECLARE emp_rec employee%ROWTYPE; CURSOR emp_cur IS SELECT * FROM employee WHERE salary > 5000; BEGIN IF NOT emp_cur%ISOPEN THEN OPEN emp_cur; END IF; LOOP FETCH emp_cur INTO emp_rec; EXIT WHEN emp_cur%NOTFOUND; dbms_output.put_line (emp_rec.first_name || ' ' || emp_rec.last_name || ' ' || emp_rec.dept || ' ' || emp_rec.salary); END LOOP; IF emp_cur%ISOPEN THEN CLOSE emp_cur; END IF; END; /
The above use simple loop with cursor, the Red Bold sentence are using the cursor attribute %ISOPEN to check if the cursor is open, the second Red Bold sentence are checking whether the fetch returned any row.
DECLARE emp_rec employee%ROWTYPE; CURSOR emp_cur IS SELECT * FROM employee WHERE salary > 5000; BEGIN IF NOT emp_cur%ISOPEN THEN OPEN emp_cur; END IF; FETCH emp_cur INTO emp_rec; WHILE emp_cur%FOUND LOOP dbms_output.put_line (emp_rec.first_name || ' ' || emp_rec.last_name || ' ' || emp_rec.dept || ' ' || emp_rec.salary); FETCH emp_cur INTO emp_rec; END LOOP; IF emp_cur%ISOPEN THEN CLOSE emp_cur; END IF; END; /
The above use while loop instead of simple loop.
DECLARE emp_rec employee%ROWTYPE; CURSOR emp_cur IS SELECT * FROM employee WHERE salary > 5000; BEGIN FOR emp_rec IN emp_cur LOOP dbms_output.put_line (emp_rec.first_name || ' ' || emp_rec.last_name || ' ' || emp_rec.dept || ' ' || emp_rec.salary); END LOOP; IF emp_cur%ISOPEN THEN CLOSE emp_cur; END IF; END; /
The above use for loop insteaded the simple loop.