Sie sind auf Seite 1von 9

Notes : Oracle PL/SQL - Introduction

Content

1.1.Basic Structure of PL/SQL 1.2. Variables and Types 1.3. Simple PL/SQL Programs 1.4. Control Flow in PL/SQL 1.5. Exception Handling 1.6. Cursor in COMPANY schema

1.1. Basic Structure of PL/SQL


PL/SQL extends SQL by adding constructs found in procedural languages, resulting in a structural language that is more powerful than SQL. The basic unit in PL/SQL is a block. The block containing executable SQL instructions is also called a script. An example of a script is script for creating tables, inserting values and adding constraints to existing tables. All these examples you can find in the part "creating sample database". Now we shall discuss PL/SQL blocks in more details. The block consists of the following parts (not all of them are compulsory) declare {variable declarations} begin {SQL and PL/SQL commands} exception {series of exception handlers} end; / We illustrate first two parts on a simple example of computing area of a circle with given radius. First we create two tables. Table AREAS contains two columns with specification NUMBER(10,3) and names radius, areas. Table RADIUS_VALS contains just one column radius of the type NUMBER(10,3). In the first example we insert into table AREAS one tuple corresponding to radius 3.

EXAMPLE:

declare pi constant number(9,7) := 3.1415926; /* constant value pi is declared with predefined value */ radius number (10,3); area number (10,3); /* variables radius and area are declared, without predefined values */

begin radius :=3; area:= pi*power(radius,2); /* area of a circuit with radius 3 is computed */ insert into AREAS values (radius,area); /* a tuple is inserted into a table

/* exception section in this block is missing */ end; This block has no name and it is possible to run it from SQL*plus prompt. It is enough to have a valid account and create tables mentioned above. After execution this script you can see following message: PL/SQL procedure successfully completed.

When you write : SELECT * FROM AREAS, The echo is following. RADIUS AREA ---------- ---------3 28.274 1 row selected.

1.2 Variables and Types


Information is transmitted between a PL/SQL program and the database through variables. Every variable has a specific type associated with it. That type can be

One of the types used by SQL for database columns A generic type used in PL/SQL such as NUMBER Declared to be the same as the type of some database column

The most commonly used generic type is NUMBER. Variables of type NUMBER can hold either an integer or a real number. The most commonly used character string type is VARCHAR(n), where n is the maximum length of the string in bytes. This length is required, and there is no default. For example, we might declare:
DECLARE FNAME VARCHAR(15); DNO NUMBER;

Types in PL/SQL are tricky. Certain SQL types cannot be parameterized in PL/SQL. For example, CHAR(50) does not work, but either CHAR or VARCHAR(50) works fine! Also note that PL/SQL allows BOOLEAN variables, even though Oracle does not support BOOLEAN as a type for database columns. In many cases, a PL/SQL variable will be used to manipulate data stored in a existing relation. In this case, it is essential that the variable have the same type as the relation column. If there is any type mismatch, variable assignments and comparisons may not work the way you expect. To be safe, instead of hard coding the type of a variable, you should use the %TYPE operator. For example:
DECLARE area AREAS.area %TYPE;

gives PL/SQL variable area the same type as was declared for the area column in the table AREA.. A variable may also have a type that is a record with several fields. The simplest way to declare such a variable is to use %ROWTYPE on a relation name. The result is a record type in which the fields have the same names and types as the attributes of the relation. For instance:
DECLARE AreaTuple AREAS %ROWTYPE; makes variable AreaTuple be a record with fields: radius, area.

The initial value of any variable, regardless of its type, is NULL. We can assign values to variables, using the ":=" operator. The assignment can occur either immediately after the type of the variable is declared, or anywhere in the executable portion of the program. For reading values from existing tables we can use cursors. A cursor is declared in the declare section. In the following example we declare and use a cursor for reading values of radius. declare pi constant number(9,7) := 3.1415926; cursor rad_cursor is select * from RADIUS_VALS; /* definition of a cursor with name rad_cursor */ rad_val rad_cursor %ROWTYPE; /* declaration of a variable rad_val with the same type as a record of table

RADIUS_VALS area AREAS.area %TYPE; begin open rad_cursor; /* cursor rad_cursor is opened */ fetch rad_cursor into rad_val; /* one record (value) is fetched to record variable rad_val */ area:= pi*power(rad_val.radius,2); /* value rad_val.radius is used for computing the area */ insert into AREAS values(rad_val.radius,area); close rad_cursor; end; In this example all records from the table RADIUS_VALS are read, but only one is used for computing the area.

1.3 Simple Programs in PL/SQL


In the PL/SQL programs we want repeat many times some group of operations. In other words, we need loops. In the following example we present loop construction for inserting values into table RADIUS_VALS. declare radius RADIUS_VALS.radius %TYPE; begin radius :=2; /* starting value of the radius */ loop /* beginning of a loop */ insert into RADIUS_VALS values(radius); radius:= radius+1; exit when radius >10; /* condition for exiting the loop end loop; end; In this example values from 2 to 10 are inserted to the table RADIUS_VALS. Another example of the loop is a loop with cursor, where values of RADIUS_VALS are read for producing tuples in the table AREAS. declare pi constant number(9,7) := 3.1415926; cursor rad_cursor is select * from RADIUS_VALS; rad_val rad_cursor %ROWTYPE; area AREAS.area %TYPE; begin

open rad_cursor; loop fetch rad_cursor into rad_val; exit when rad_cursor %NOTFOUND; area:= pi*power(rad_val.radius,2); insert into AREAS values(rad_val.radius,area); end loop; close rad_cursor; end; When run this script we obtain in the table AREAS values of areas of circles with radii r = 2 ...10. Condition for exiting the loop is %NOTFOUND, it means no more records can be fetched from the cursor. Another useful conditions related to cursor can be used: %FOUND A record can be fetched from the cursor %ISOPENThe cursor have been opened %ROWCOUNT- the number of rows fetched from the cursor so far

1.4. Control Flow in PL/SQL


PL/SQL allows you to branch and create loops in a fairly familiar way. An IF statement looks like:
if <condition> then <statement_list> else <statement_list> end if;

The ELSE part is optional. If you want a multiway branch, use:


if <condition_1> then ... elsif <condition_2> then ... ... ... elsif <condition_n> then ... else... end if;

The following is an example, slightly modified from the previous one, where now we only do the insertion if the area of the circuit is less then 100.

Example:
declare pi constant number(9,7) := 3.1415926; cursor rad_cursor is select * from RADIUS_VALS; rad_val rad_cursor %ROWTYPE;

area AREAS.area %TYPE; begin open rad_cursor; loop fetch rad_cursor into rad_val; exit when rad_cursor %NOTFOUND; area:= pi*power(rad_val.radius,2); if area < 100 then insert into AREAS values (rad_val.radius,area); end if; end loop; close rad_cursor; end;

Loops are created with the following:


loop <loop_body> /* A list of statements. */ end loop;

At least one of the statements in <loop_body> should be an EXIT statement of the form
exit when <condition>; The loop breaks if <condition> is true.

Some other useful loop-forming statements are:


exit by itself is an unconditional loop break. Use it inside a conditional if you like. A simple for loop can be formed with:
for <var> in <start>..<finish> loop <loop_body> end loop;

Here, <var> can be any variable; it is local to the for-loop and need not be declared. Also, <start> and <finish> are constants.

Example: declare pi constant number(9,7) := 3.1415926; area AREAS.area %TYPE; begin

for radius in 1..7 loop area:= pi*power(radius,2); if area < 100 then insert into AREAS values (radius,area); end if; end loop; end; We can use for-loops together with cursors. In this case the cursor is opened and closed automatically (without open, fetch and close instructions also %NOTFOUND condition is not tested). Example: declare pi constant number(9,7) := 3.1415926; cursor rad_cursor is select * from RADIUS_VALS; rad_val rad_cursor %ROWTYPE; area AREAS.area %TYPE; begin for rad_val in rad_cursor loop area:= pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius,area); end loop; end;

1.5. Exception Handling.


When user-defined or system-related errors are encountered, the control of PL/SQL shifts to the Exception Handling section. Within the Exception section when clause is used to evaluate which exception is to be handled. In our running example we define a new variable some_var to illustrate an error than can happen during the execution of our program. The error we expect is division by zero. In the case of division by zero the default action is " insert (0,0) into the AREAS table. declare pi constant number(9,7) := 3.1415926; radius number (10,3); area number (10,3); some_var number(10,3); begin radius :=2; loop some_var := 1/(radius-5); area:= pi*power(radius,2); insert into AREAS values(radius,area); radius:= radius+1; exit when area >100; end loop;

exception when ZERO_DIVIDE then insert into AREAS values (0,0); end; The action of the program is following. We compute values of some_var and area and insert values of radius and area to the AREAS table. If there was not computing 1/(radius -5 ) all values for area <= 100 would be inserted into database. In the case of radius=5 exception of dividing by zero is raised. Execution of the loop is ended and operation of insert into AREAS values (0,0); is executed. All other values of radius that are greater than 5 are ignored. Result is following: RADIUS AREA ---------- ---------2 12.566 3 28.274 4 50.265 0 0 4 rows selected.

1.6 Cursors (example in COMPANY schema)


A cursor is a variable whose value is a tuple of some relation; typically that relation is not a stored relation but is the answer to some query. By fetching into the cursor each tuple of the relation, we can write a program that acts on each such tuple. The example below illustrates a cursor fetch loop. It uses our sample relation Employee.. The program looks at each tuple and, if the number of department is less than 4 the tuple is inserted into auxiliary table Employee1. Now we illustrate defined notions in the exaple of program running against table employee from the database COMPANY.

Example:
At first we create an auxiliary table Employee1 with attributes chosen from table Employee.
CREATE TABLE Employee1( Name1 VARCHAR(15), SSN1 CHAR(9), DNO1 NUMBER);

now we create a program in PL/SQL:


SQL> 1 declare /*Output variables*/ 2 a EMPLOYEE.LNAME%TYPE;

3 b EMPLOYEE.SSN%TYPE; 4 c EMPLOYEE.DNO%TYPE; 5 cursor EMPCursor IS 6 select LNAME,SSN,DNO 7 from EMPLOYEE; 8 begin 9 open EMPCursor; 10 loop 11 fetch EMPCursor into a,b,c; 12 exit when EMPCursor%NOTFOUND; 13 if C>=4 THEN INSERT into EMPLOYEE1 values (a,b,c); 14 end if; 15 end loop; 16 close EMPCursor; 17* end; Here are explanations for the various lines of this program:

Line (1) introduces the declaration section. Lines (2),(3) and (4) declare variables a,b and c to have types equal to the types of attributes of the relation Employee1. Lines (5) through (7) define the cursor EMPCursor. It ranges over a relation defined by the SELECT-FROM-WHERE query. That query selects all tuples of Employee. Line (8) begins the executable section of the program. Line (9) opens the cursor, an essential step. Lines (10) through (15) are a PL/SQL loop. Notice that such a loop is bracketed by LOOP and END LOOP. Within the loop we find: o On Line (11), a fetch through the cursor into the local variables. In general, the FETCH statement must provide variables for each component of the tuple retrieved. Since the query of Lines (5) through (7) produces triples, we have correctly provided three variables, and we know they are of the correct type. o On Line (12), a test for the loop-breaking condition. Its meaning should be clear: %NOTFOUND after the name of a cursor is true exactly when a fetch through that cursor has failed to find any more tuples. o On Line (13), a SQL INSERT statement that inserts the tuple into Employee1. Line (16) closes the cursor. Line (17) ends the PL/SQL program.

It is possible of course to copy the above tuples into the table Employee1 by standalone SQL construction. We encourage the reader to try it and to compare the result.

Das könnte Ihnen auch gefallen