P. 1
PLSQL Tutorial

PLSQL Tutorial

|Views: 112|Likes:
Published by sumanth_0678

More info:

Published by: sumanth_0678 on Jan 09, 2012
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

05/25/2012

pdf

text

original

sBasic Structure of PL/SQL

PL/SQL stands for Procedural Language/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. All PL/SQL programs

are made up of blocks, which can be nested within each other.

Typically, each block performs a logical action in he program. A

block has the following structure:

DECLARE

/* Declarative section: variables, types, and local

subprograms. */

BEGIN

/* Executable section: procedural and SQL statements go

here. */

/* This is the only section of the block that is required. */

EXCEPTION

/* Exception handling section: error handling statements go

here. */

END;

Only the executable section is required. The other sections are

optional. The only SQL statements allowed in a PL/SQL

program are SELECT, INSERT, UPDATE, DELETE and several

other data manipulation statements plus some transaction

control. However, the SELECT statement has a special form in

which a single tuple is placed in variables; more on this later.

Data definition statements like CREATE, DROP, or ALTER are not

allowed. The executable section also contains constructs such

as assignments, branches, loops, procedure calls, and triggers,

which are all described below (except triggers). PL/SQL is not

case sensitive. C style comments (/* ... */) may be used.

To execute a PL/SQL program, we must follow the program

text itself by

* A line with a single dot ("."), and then * A line with run;

As with Oracle SQL programs, we can invoke a PL/SQL program

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. The most commonly used character string type is VARCHAR(n). . 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.either by typing in sqlplus. Variables of type NUMBER can hold either an integer or a real number.

In many cases. and there is no default. This length is required. myBeer VARCHAR(20). even though Oracle does not support BOOLEAN as a type for database columns. a PL/SQL variable will be used to manipulate data stored in a existing . For example. Note that PL/SQL allows BOOLEAN variables.where n is the maximum length of the string in bytes. Types in PL/SQL can be tricky. we might declare: DECLARE price NUMBER.

For example: DECLARE myBeer Beers. In this case. To be safe. A variable may also have a type that is a record with several fields. instead of hard coding the type of a variable. If there is any type mismatch. The simplest way to declare such a variable is to use . gives PL/SQL variable myBeer whatever type was declared for the name column in relation Beers.relation.name%TYPE. you should use the %TYPE operator. variable assignments and comparisons may not work the way you expect. it is essential that the variable have the same type as the relation column.

The assignment can occur either immediately after the type of the . makes variable beerTuple be a record with fields name and manufacture. regardless of its type. The result is a record type in which the fields have the same names and types as the attributes of the relation. We can assign values to variables. using the ":=" operator. assuming that the relation has the schema Beers(name.%ROWTYPE on a relation name. The initial value of any variable. is NULL. manufacture). For instance: DECLARE beerTuple Beers%ROWTYPE.

run. Simple Programs in PL/SQL The simplest form of program has some declarations followed . END. because there are no changes to the database. An example: DECLARE a NUMBER := 3. BEGIN a := a + 1. This program has no effect when run.variable is declared. or anywhere in the executable portion of the program.

The major nuance is that the form of the SELECT statement is different from its SQL form. into which the components of the retrieved tuple must be placed. since the SELECT statement in PL/SQL only works if the result of the query contains a single tuple. The situation is essentially the same as that of the "single-row select" discussed in Section 7. we must have an INTO clause listing variables.by an executable section consisting of one or more of the SQL statements with which we are familiar. Notice we said "tuple" rather than "tuples".5 of the . After the SELECT clause. one for each attribute in the SELECT clause.1.

DELETE FROM T1. INSERT INTO T1 VALUES(2. 4). */ . f INTEGER ). If the query returns more than one tuple.text. /* Above is plain SQL. 3). in connection with embedded SQL. you need to use a cursor. Here is an example: CREATE TABLE T1( e INTEGER. INSERT INTO T1 VALUES(1. below is the PL/SQL program.

f INTO a.a). Fortuitously. . BEGIN SELECT e. namely (2.2) into T1. run.4).DECLARE a NUMBER. END. The INSERT statement thus inserts (4. INSERT INTO T1 VALUES(b. b NUMBER.b FROM T1 WHERE e>1. there is only one tuple of T1 that has first component greater than 1.

.Control Flow in PL/SQL PL/SQL allows you to branch and create loops in a fairly familiar way.. ELSIF <condition_2> THEN . ELSE . . . use: IF <condition_1> THEN .. The ELSE part is optional.. ... An IF statement looks like: IF <condition> THEN <statement_list> ELSE <statement_list> END IF. ELSIF <condition_n> THEN .... If you want a multiway branch....

f INTO a. The following is an example. IF b=1 THEN . we first add 10 to each component and then insert: DECLARE a NUMBER.b FROM T1 WHERE e>1. slightly modified from the previous one. If not. BEGIN SELECT e. b NUMBER. where now we only do the insertion if the second component is 1.END IF.

run. ELSE INSERT INTO T1 VALUES(b+10.a+10).a).INSERT INTO T1 VALUES(b. At least one of the statements in <loop_body> should be an EXIT statement of the form . Loops are created with the following: LOOP <loop_body> /* A list of statements. */ END LOOP. END IF. END.

here is a way to insert each of the pairs (1. EXIT WHEN i>100. . 1) through (100.EXIT WHEN <condition>.i). 100) into T1 of the above two examples: DECLARE i NUMBER := 1. i := i+1. The loop breaks if <condition> is true. BEGIN LOOP INSERT INTO T1 VALUES(i. For example.

* A WHILE loop can be formed with · WHILE <condition> LOOP · <loop_body> END LOOP.run. . END. * A simple FOR loop can be formed with: · FOR <var> IN <start>..<finish> LOOP . Some other useful loop-forming statements are: * EXIT by itself is an unconditional loop break.END LOOP. Use it inside a conditional if you like.

<var> can be any variable. it is local to the for-loop and need not be declared.· <loop_body> · END LOOP. <start> and <finish> are constants. Cursors A cursor is a variable that runs through the tuples of some relation. we can write a program to read and process the value of each such tuple. we can also . This relation can be a stored table. Also. or it can be the answer to some query. Here. By fetching into the cursor each tuple of the relation. If the relation is stored.

The program will delete every tuple whose first component is less than the second. It uses our example relation T1(e. and insert the reverse tuple into T1.e%TYPE.f%TYPE. 3) b T1.update or delete the tuple at the current cursor position. /* Cursor declaration: */ 4) CURSOR T1Cursor IS .f) whose tuples are pairs of integers. The example below illustrates a cursor loop. 1) DECLARE /* Output variables to hold the result of the query: */ 2) a T1.

f 6) FROM T1 7) WHERE e < f 8) FOR UPDATE. 11) LOOP /* Retrieve each row of the result of the above query into PL/SQL variables: */ 12) FETCH T1Cursor INTO a. .5) SELECT e. b. /* If there are no more rows to fetch. 9) BEGIN 10) OPEN T1Cursor. exit the loop: */ 13) EXIT WHEN T1Cursor%NOTFOUND.

16) END LOOP. Here are explanations for the various lines of this program: . */ 17) CLOSE T1Cursor. 20) run. 18) END. /* Free cursor used by the query. a). /* Insert the reverse tuple: */ 15) INSERT INTO T1 VALUES(b./* Delete the current tuple: */ 14) DELETE FROM T1 WHERE CURRENT OF T1Cursor. 19) .

where we were less careful and declared the corresponding variables to be of type NUMBER).* Line (1) introduces the declaration section. Although we know these types are INTEGER. * Lines (4) through (8) define the cursor T1Cursor. It ranges over a relation defined by the SELECT-FROM-WHERE query. * Lines (2) and (3) declare variables a and b to have types equal to the types of attributes e and f of the relation T1. That query selects those tuples of T1 whose first component is less than the second component. we wisely make sure that whatever types they may have are copied to the PL/SQL variables (compare with the previous example. Line (8) declares the cursor FOR UPDATE since we will modify T1 using this cursor later on .

Notice that such a loop is bracketed by LOOP and END LOOP. a test for the loop-breaking condition. o On Line (13). In general.Line (14). Within the loop we find: o On Line (12). Its . FOR UPDATE is unnecessary if the cursor will not be used for modification. a fetch through the cursor into the local variables. an essential step. * Line (10) opens the cursor. Since the query of Lines (5) through (7) produces pairs. * Lines (11) through (16) are a PL/SQL loop. we have correctly provided two variables. the FETCH statement must provide variables for each component of the tuple retrieved. * Line (9) begins the executable section of the program. and we know they are of the correct type. In general.

a SQL INSERT statement that inserts the reverse tuple into T1. Procedures PL/SQL procedures behave very much like procedures in other programming language. * Line (18) ends the PL/SQL program. o On Line (15). * Lines (19) and (20) cause the program to execute. * Line (17) closes the cursor. Here is an example of a PL/SQL . a SQL DELETE statement that deletes the current tuple using the special WHERE condition CURRENT OF T1Cursor. o On Line (14).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.

CREATE PROCEDURE addtuple1(i IN NUMBER) AS BEGIN INSERT INTO T2 VALUES(i. b CHAR(10) ). given an integer i. 'xxx') into the following example relation: CREATE TABLE T2 ( a INTEGER. inserts the tuple (i. 'xxx'). .procedure addtuple1 that. END addtuple1.

OUT (write-only). The possible modes are IN (read-only). and the old procedure will be lost. and INOUT (read and write). each followed by a mode and a type. On the other hand. A procedure is introduced by the keywords CREATE PROCEDURE followed by the procedure name and its parameters. you will not be warned. the type specifier in .run. An option is to follow CREATE by OR REPLACE. There can be any number of parameters. you will not get an error. Note: Unlike the type specifier in a PL/SQL variable declaration. The advantage of doing so is that should you have already made the definition. should the previous definition be a different procedure of the same name.

a parameter declaration must be unconstrained. Rather.. We have repeated the name of the procedure after the END. following AS we have: . However. CHAR(10) and VARCHAR(20) are illegal. Then comes the body. For example. The actual length of a parameter depends on the corresponding argument that is passed in when the procedure is invoked. but this is optional. which is essentially a PL/SQL block. Following the arguments is the keyword AS (IS is a synonym). AS . the DECLARE section should not start with the keyword DECLARE. CHAR or VARCHAR should be used instead..

in which the procedure is invoked as an executable statement. it does not execute the procedure. The run at the end runs the statement that creates the procedure. . To execute the procedure. For example: BEGIN addtuple1(99).<local_var_declarations> BEGIN <procedure_body> END. run. use another PL/SQL statement. . END.

. b) VALUES(x. . run.b%TYPE) AS BEGIN INSERT INTO T2(a.a%TYPE. The following procedure also inserts a tuple into T2. but it takes both components as arguments: CREATE PROCEDURE addtuple2( x T2. y). y T2.

The following illustrates the use of an OUT parameter: CREATE TABLE T3 ( a INTEGER. run.END addtuple2. 'abc'). . . Now. END. 'abc') to T2: BEGIN addtuple2(10. run. to add a tuple (10. .

b INTEGER ). . run. b). END. CREATE PROCEDURE addtuple3(a NUMBER. . b OUT NUMBER) AS BEGIN b := 4. INSERT INTO T3 VALUES(a.

v). Because of this. A constant or a literal argument should not be passed in for an OUT/INOUT .DECLARE v NUMBER. BEGIN addtuple3(10. END. such as a variable like v in the example above. the input argument for an OUT or INOUT parameter should be something with an "lvalue". Note that assigning values to parameters declared as OUT or INOUT causes the corresponding input arguments to be written. run.

"RETURN <expression>.. object_name .. we follow the parameter list by RETURN and the type of the return value: CREATE FUNCTION <func_name>(<param_list>) RETURN <return_type> AS . use the following SQL query: select object_type. In the body of the function definition. In a function declaration." exits from the function and returns the value of <expression>. To find out what procedures and functions you have created. We can also write functions instead of procedures.parameter.

Instead. . drop function <function_name>. try issuing the command show errors procedure <procedure_name>. it gives you a cryptic message such as "procedure created with compilation errors". If you don't see what is wrong immediately. Discovering Errors PL/SQL does not always tell you about compilation errors.from user_objects where object_type = 'PROCEDURE' or object_type = 'FUNCTION'. To drop a stored procedure/function: drop procedure <procedure_name>.

A more couth way is to define a bind variable. you can type. A ``quick-and-dirty'' way is to store it as the sole tuple of some relation and after the PL/SQL statement print the relation with a SELECT statement. The steps are as follows: . which is the only kind that may be printed with a print command. Bind variables are the kind that must be prefixed with a colon in PL/SQL statements.Alternatively. SHO ERR (short for SHOW ERRORS) to see the most recent compilation error. Printing Variables Sometimes we might want to print the value of a PL/SQL local variable.

3. We may then assign to the variable in a following PL/SQL statement. VARIABLE x NUMBER BEGIN . but we must prefix it with a colon. Finally. which prints the value 1. We declare a bind variable as follows: VARIABLE <name> <type> where the type can be only one of three things: NUMBER. we can execute a statement PRINT :<name>.1. 2. CHAR. or CHAR(n). outside the PL/SQL statement Here is a trivial example.

PLSQL Tutorial 2. run. PL/SQL Tutorial What is SQL? The Structured Query Language is used in manipulating data stored in Relational Database Management Systems (RDBMS).:x := 1. But the . SQL Data Manipulation Language (DM): SQL (Structured Query Language) is a syntax for executing queries. Sybase. however. Oracle. . All the important and common sql statements are supported by these RDBMS. updated. PRINT :x. which has laid down certain rules for the language. SQL has the full support of ANSI (American National Standards Institute). Microsoft SQL Server. PostgresSQL. deleted and inserted. each has its own set of proprietary statements and extensions. mSQL. Ingres etc. Looking for more information of PL SQL tutorials: 1. sorted. Access. SQL can be used with any RDBMS such as MySQL. SQL provides commands through which data can be extracted. END.

Kari Referring to Two Tables We can select data from two tables by referring to two tables.Name FROM Employees. Stephen Example Who ordered a printer? SELECT Employees.SQL Data Manipulation Language (DM): SQL (Structured Query Language) is a syntax for executing queries. Stephen Svendson. Orders. and what did they order? SELECT Employees. The purpose is to bind data together. without repeating all of the data in every table. When you look at the example tables below. Joins and Keys Sometimes we have to select data from two tables to make our result complete.Product='Printer' Result Name Product Printer Table Chair . The Employee_ID distinguishes two persons even if they have the same name. meaning that no two rows can have the same Employee_ID. and delete records. notice that: • • • The "Employee_ID" column is the primary key of the "Employees" table The "Prod_ID" column is the primary key of the "Orders" table The "Employee_ID" column in the "Orders" table is used to refer to the persons in the "Employees" table without using their names Employees: Employee_ID 01 02 03 04 Orders: Prod_ID 234 657 865 Product Printer Table Chair Employee_ID 01 03 03 Name Hansen. insert. Ola Svendson. Ola Svendson. In the "Employees" table below.Product FROM Employees. Stephen Pettersen. A primary key is a column with a unique value for each row. Orders WHERE Employees. the "Employee_ID" column is the primary key.Employee_ID=Orders. Tove Svendson. Tables in a database can be related to each other with keys. But the SQL language also includes a syntax to update.Employee_ID AND Orders.Employee_ID=Orders. Orders WHERE Employees.Employee_ID Result Name Hansen. like this: Example Who has ordered a product.Name. We have to perform a join. across tables.

Product FROM Employees LEFT JOIN Orders ON Employees. Ola Using Joins OR we can select data from two tables with the JOIN keyword. field2. Orders.foreign_keyfield List all employees. Result Name Hansen.Employee_ID=Orders. even if there are no matches in the second table (Orders). Kari Table Chair Product Printer Product Printer Table Chair .foreign_keyfield Who has ordered a product.keyfield = second_table.Employee_ID The INNER JOIN returns all rows from both tables where there is a match. and what did they order? SELECT Employees. Tove Svendson. SELECT Employees. Orders. field2.Hansen. Stephen Example LEFT JOIN Syntax SELECT field1.Product FROM Employees INNER JOIN Orders ON Employees. Ola Svendson. Result Name Hansen.keyfield = second_table.Employee_ID=Orders. and their orders . field3 FROM first_table LEFT JOIN second_table ON first_table. those rows also will be listed. field3 FROM first_table INNER JOIN second_table ON first_table. those rows will not be listed. Stephen Svendson.Employee_ID The LEFT JOIN returns all the rows from the first table (Employees). If there are rows in Employees that do not have matches in Orders. Stephen Pettersen. Ola Svendson. If there are rows in Employees that do not have matches in Orders. Stephen Svendson.if any.Name.Name. like this: Example INNER JOIN Syntax SELECT field1.

Product Printer Table Chair . Result Name Hansen.foreign_keyfield List all orders. Stephen Example Who ordered a printer? SELECT Employees.Employee_ID=Orders. those rows also would have been listed. Ola Create a Database CREATE DATABASE database_name Create a Table CREATE TABLE Person ( LastName varchar. field3 FROM first_table RIGHT JOIN second_table ON first_table. Address varchar. SELECT Employees.keyfield = second_table.Product FROM Employees RIGHT JOIN Orders ON Employees. field2.Product = 'Printer' Result Name Hansen.Employee_ID=Orders. and who has ordered .if any.Name FROM Employees INNER JOIN Orders ON Employees.Example RIGHT JOIN Syntax SELECT field1. Stephen Svendson. even if there are no matches in the first table (Employees). Orders. FirstName varchar.Employee_ID The RIGHT JOIN returns all the rows from the second table (Orders). If there had been any rows in Orders that did not have matches in Employees.Name. Ola Svendson.Employee_ID WHERE Orders.

The maximum number of digits are specified in "size". Holds a fixed length string (can contain letters. A unique index means that two rows cannot have the same index value. and special characters). you can add the reserved word DESC after the column name: CREATE INDEX PersonIndex ON Person (LastName DESC) If you want to index more than one column you can list the column names within the parentheses. Hold numbers with fractions.index_name Delete a Database or Table To delete a database: . CREATE UNIQUE INDEX index_name ON table_name (column_name) The "column_name" specifies the column you want indexed. The maximum number of digits are specified in parenthesis. this is because the indexes also need an update. Holds a date Create Index Indices are created in an existing table to locate rows more quickly and efficiently. duplicate values are allowed. It is possible to create an index on one or more columns of a table. numbers.Age int ) The data type specifies what type of data the column can hold. When the UNIQUE keyword is omitted. The maximum size is specified in parenthesis. A Unique Index Creates a unique index on a table. it is a good idea to create indexes only on columns that are often used for a search. DROP INDEX table_name. The table below contains the most common data types in SQL: Data Type integer(size) int(size) smallint(size) tinyint(size) decimal(size. The users cannot see the indexes. and special characters). The fixed size is specified in parenthesis.d) char(size) varchar(size) date(yyyymmdd) Description Hold integers only. CREATE INDEX index_name ON table_name (column_name) The "column_name" specifies the column you want indexed. named "PersonIndex". Holds a variable length string (can contain letters. numbers. on the LastName field of the Person table: CREATE INDEX PersonIndex ON Person (LastName) If you want to index the values in a column in descending order. they are just used to speed up queries. separated by commas: CREATE INDEX PersonIndex ON Person (LastName. So. Example This example creates a simple index.d) numeric(size. A Simple Index Creates a simple index on a table. FirstName) Drop Index You can delete an existing index in a table with the DROP statement. Note: Updating a table containing indexes takes more time than updating a table without. The maximum number of digits to the right of the decimal is specified in "d". and each index is given a name.

DROP DATABASE database_name To delete a table (the table structure, attributes, and indexes will also be deleted): DROP TABLE table_name Alter Table The ALTER TABLE statement is used to add or drop columns in an existing table. ALTER TABLE table_name ADD column_name datatype ALTER TABLE table_name DROP COLUMN column_name Note: Some database systems don't allow the dropping of a column in a database table (DROP COLUMN column_name). Person: LastName Pettersen FirstName Kari Address Storgt 20

Example To add a column named "City" in the "Person" table: ALTER TABLE Person ADD City varchar(30) Result: LastName Pettersen FirstName Kari Address Storgt 20 City

Example To drop the "Address" column in the "Person" table: ALTER TABLE Person DROP COLUMN Address Result: LastName Pettersen FirstName Kari City

Function Syntax The syntax for built-in SQL functions is: SELECT function(column) FROM table Types of Functions There are several basic types and categories of functions in SQL. The basic types of functions are:

• •

Aggregate Functions Scalar functions

Aggregate functions Aggregate functions operate against a collection of values, but return a single value. Note: If used among many other expressions in the item list of a SELECT statement, the SELECT must have a GROUP BY clause!! "Persons" table (used in most examples) Name Hansen, Ola Svendson, Tove Pettersen, Kari Aggregate functions in MS Access Function Description Returns the average value of a column Returns the number of rows (without a NULL value) of a column Age 34 45 19

AVG(column) COUNT(column)

COUNT(*) FIRST(column) LAST(column) MAX(column) MIN(column)
STDEV(column) STDEVP(column)

Returns the number of selected rows Returns the value of the first record in the specified field Returns the value of the last record in the specified field Returns the highest value of a column Returns the lowest value of a column

SUM(column)
VAR(column) VARP(column) Aggregate functions in SQL Server Function

Returns the total sum of a column

Description Returns the average value of a column

AVG(column)
BINARY_CHECKSUM CHECKSUM CHECKSUM_AGG

COUNT(column) COUNT(*) COUNT(DISTINCT column) FIRST(column) LAST(column) MAX(column) MIN(column)
STDEV(column) STDEVP(column)

Returns the number of rows (without a NULL value) of a column Returns the number of selected rows Returns the number of distinct results Returns the value of the first record in the specified field Returns the value of the last record in the specified field Returns the highest value of a column Returns the lowest value of a column

SUM(column)
VAR(column) VARP(column)

Returns the total sum of a column

Scalar functions Scalar functions operate against a single value, and return a single value based on the input value. Useful Scalar Functions in MS Access Function UCASE(c) LCASE(c) MID(c,start[,end]) LEN(c) INSTR(c) LEFT(c,number_of_char) RIGHT(c,number_of_char) ROUND(c,decimals) MOD(x,y) NOW() Description Converts a field to upper case Converts a field to lower case Extract characters from a text field Returns the length of a text field Returns the numeric position of a named character within a text field Return the left part of a text field requested Return the right part of a text field requested Rounds a numeric field to the number of decimals specified Returns the remainder of a division operation Returns the current system date

FORMAT(c,format) DATEDIFF(d,date1,date2) SELECT AVG(column) FROM table

Changes the way a field is displayed Used to perform date calculations

SELECT AVG(Age) FROM Persons WHERE Age>20 SELECT COUNT(Age) FROM Persons SELECT FIRST(Age) AS lowest_age FROM Persons ORDER BY Age GROUP BY GROUP BY... was added to SQL because aggregate functions (like SUM) return the aggregate of all column values every time they are called, and without the GROUP BY function it was impossible to find the sum for each individual group of column values. The syntax for the GROUP BY function is: SELECT column,SUM(column) FROM table GROUP BY column GROUP BY Example This "Sales" Table: Company W3Schools IBM W3Schools And This SQL: SELECT Company, SUM(Amount) FROM Sales Returns this result: Company W3Schools IBM W3Schools SUM(Amount) 17100 17100 17100 Amount 5500 4500 7100

The above code is invalid because the column returned is not part of an aggregate. A GROUP BY clause will solve this problem: SELECT Company,SUM(Amount) FROM Sales GROUP BY Company Returns this result: Company W3Schools IBM SUM(Amount) 12600 4500

HAVING CLAUSE HAVING... was added to SQL because the WHERE keyword could not be used against aggregate functions (like SUM), and without HAVING... it would be impossible to test for result conditions. The syntax for the HAVING function is: SELECT column,SUM(column) FROM table GROUP BY column HAVING SUM(column) condition value This "Sales" Table: Company Amount

Name. you can do so by listing them after the SELECT statement: SELECT LastName. Firstname INTO Persons_sandnes FROM Persons WHERE City='Sandnes' Selecting data from more than one table is also possible.SUM(Amount) FROM Sales GROUP BY Company HAVING SUM(Amount)>10000 Returns this result Company W3Schools 5500 4500 7100 SUM(Amount) 12600 The SELECT INTO Statement The SELECT INTO statement is most often used to create backup copies of tables or for archiving records.Product INTO Empl_Ord_backup FROM Employees INNER JOIN Orders ON Employees.Employee_ID=Orders.W3Schools IBM W3Schools This SQL: SELECT Company. The following example creates a new table "Empl_Ord_backup" that contains data from the two tables Employees and Orders: SELECT Employees. Syntax SELECT column_name(s) INTO newtable [IN externaldatabase] FROM source Make a Backup Copy The following example makes a backup copy of the "Persons" table: SELECT * INTO Persons_backup FROM Persons The IN clause can be used to copy tables into another database: SELECT Persons.mdb' FROM Persons If you only want to copy a few fields.Employee_ID Basic Structure of PL/SQL . The following example creates a "Persons_backup" table with two columns (FirstName and LastName) by extracting the persons who lives in "Sandnes" from the "Persons" table: SELECT LastName.Orders. FirstName INTO Persons_backup FROM Persons You can also add a where clause.* INTO Persons IN 'Backup.

C style comments (/* . we must follow the program text itself by * A line with a single dot (". and local subprograms. and there is no default. loops. Data definition statements like CREATE. The executable section also contains constructs such as assignments. the SELECT statement has a special form in which a single tuple is placed in variables. The basic unit in PL/SQL is a block. INSERT. more on this later. DELETE and several other data manipulation statements plus some transaction control.. */ BEGIN /* Executable section: procedural and SQL statements go here. we can invoke a PL/SQL program either by typing in sqlplus. */) may be used. or ALTER are not allowed. UPDATE."). and then * A line with run. Variables and Types Information is transmitted between a PL/SQL program and the database through variables. The only SQL statements allowed in a PL/SQL program are SELECT. 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. The other sections are optional. procedure calls. Variables of type NUMBER can hold either an integer or a real number.PL/SQL stands for Procedural Language/SQL. types. As with Oracle SQL programs. each block performs a logical action in he program. resulting in a structural language that is more powerful than SQL. For example. PL/SQL extends SQL by adding constructs found in procedural languages. This length is required. To execute a PL/SQL program. PL/SQL is not case sensitive. branches. which can be nested within each other. where n is the maximum length of the string in bytes. Every variable has a specific type associated with it. All PL/SQL programs are made up of blocks. Only the executable section is required. DROP. . */ EXCEPTION /* Exception handling section: error handling statements go here.. we might declare: DECLARE price NUMBER. The most commonly used character string type is VARCHAR(n). */ END. and triggers. which are all described below (except triggers). However. Typically. */ /* This is the only section of the block that is required. A block has the following structure: DECLARE /* Declarative section: variables.

For instance: DECLARE beerTuple Beers%ROWTYPE. Simple Programs in PL/SQL The simplest form of program has some declarations followed by an executable section consisting of one or more of the SQL statements with which we are familiar. regardless of its type. If there is any type mismatch. we must have an INTO clause listing variables. The assignment can occur either immediately after the type of the variable is declared. assuming that the relation has the schema Beers(name. This program has no effect when run. using the ":=" operator. Note that PL/SQL allows BOOLEAN variables. or anywhere in the executable portion of the program. An example: DECLARE a NUMBER := 3. one for each attribute in the SELECT clause. gives PL/SQL variable myBeer whatever type was declared for the name column in relation Beers. The major nuance is that the form of the SELECT statement is different from its SQL form. run. In this case. manufacture). END. The result is a record type in which the fields have the same names and types as the attributes of the relation. . makes variable beerTuple be a record with fields name and manufacture. The simplest way to declare such a variable is to use %ROWTYPE on a relation name. Types in PL/SQL can be tricky. you should use the %TYPE operator. After the SELECT clause. because there are no changes to the database. The initial value of any variable. In many cases. A variable may also have a type that is a record with several fields. variable assignments and comparisons may not work the way you expect.name%TYPE. even though Oracle does not support BOOLEAN as a type for database columns. instead of hard coding the type of a variable. For example: DECLARE myBeer Beers.myBeer VARCHAR(20). is NULL. To be safe. into which the components of the retrieved tuple must be placed. We can assign values to variables. a PL/SQL variable will be used to manipulate data stored in a existing relation. BEGIN a := a + 1. it is essential that the variable have the same type as the relation column.

namely (2. */ DECLARE a NUMBER.. run. since the SELECT statement in PL/SQL only works if the result of the query contains a single tuple.. An IF statement looks like: IF <condition> THEN <statement_list> ELSE <statement_list> END IF. INSERT INTO T1 VALUES(2. below is the PL/SQL program.f INTO a. in connection with embedded SQL. If you want a multiway branch.. Control Flow in PL/SQL PL/SQL allows you to branch and create loops in a fairly familiar way. /* Above is plain SQL. b NUMBER. . The INSERT statement thus inserts (4. there is only one tuple of T1 that has first component greater than 1. DELETE FROM T1. END. If the query returns more than one tuple. INSERT INTO T1 VALUES(b. f INTEGER ).Notice we said "tuple" rather than "tuples". The ELSE part is optional. use: IF <condition_1> THEN .4). 4).2) into T1.a). INSERT INTO T1 VALUES(1.. The situation is essentially the same as that of the "single-row select" discussed in Section 7. you need to use a cursor. Here is an example: CREATE TABLE T1( e INTEGER.5 of the text. BEGIN SELECT e.b FROM T1 WHERE e>1. ELSIF <condition_2> THEN .1. 3). Fortuitously.

... Loops are created with the following: LOOP <loop_body> /* A list of statements. END IF. we first add 10 to each component and then insert: DECLARE a NUMBER. slightly modified from the previous one. where now we only do the insertion if the second component is 1. here is a way to insert each of the pairs (1.a+10)... END IF.. For example..f INTO a.b FROM T1 WHERE e>1. The loop breaks if <condition> is true. */ END LOOP. If not. b NUMBER.a). ELSIF <condition_n> THEN . ELSE . The following is an example. 1) through (100. run.. 100) into T1 of the above two examples: DECLARE i NUMBER := 1. At least one of the statements in <loop_body> should be an EXIT statement of the form EXIT WHEN <condition>. . BEGIN . END.. BEGIN SELECT e. ELSE INSERT INTO T1 VALUES(b+10. IF b=1 THEN INSERT INTO T1 VALUES(b.

run. 1) DECLARE /* Output variables to hold the result of the query: */ 2) a T1.f) whose tuples are pairs of integers. or it can be the answer to some query. END LOOP. we can write a program to read and process the value of each such tuple. If the relation is stored. it is local to the for-loop and need not be declared. Here.. <var> can be any variable. * A WHILE loop can be formed with · WHILE <condition> LOOP · <loop_body> END LOOP. It uses our example relation T1(e. i := i+1.e%TYPE. and insert the reverse tuple into T1. <start> and <finish> are constants. Some other useful loop-forming statements are: * EXIT by itself is an unconditional loop break. This relation can be a stored table.i). By fetching into the cursor each tuple of the relation. * A simple FOR loop can be formed with: · FOR <var> IN <start>. Use it inside a conditional if you like. The example below illustrates a cursor loop. The program will delete every tuple whose first component is less than the second. .<finish> LOOP · <loop_body> · END LOOP. . we can also update or delete the tuple at the current cursor position. Cursors A cursor is a variable that runs through the tuples of some relation. EXIT WHEN i>100. Also.LOOP INSERT INTO T1 VALUES(i. END.

Although we know these types are INTEGER. /* Insert the reverse tuple: */ 15) INSERT INTO T1 VALUES(b.f%TYPE. 16) END LOOP. /* Cursor declaration: */ 4) CURSOR T1Cursor IS 5) SELECT e. b. we wisely make sure that . * Lines (2) and (3) declare variables a and b to have types equal to the types of attributes e and f of the relation T1. 9) BEGIN 10) OPEN T1Cursor. 20) run. 11) LOOP /* Retrieve each row of the result of the above query into PL/SQL variables: */ 12) FETCH T1Cursor INTO a. exit the loop: */ 13) EXIT WHEN T1Cursor%NOTFOUND. /* Free cursor used by the query. 18) END. a).3) b T1. /* If there are no more rows to fetch. Here are explanations for the various lines of this program: * Line (1) introduces the declaration section. 19) . f 6) FROM T1 7) WHERE e < f 8) FOR UPDATE. /* Delete the current tuple: */ 14) DELETE FROM T1 WHERE CURRENT OF T1Cursor. */ 17) CLOSE T1Cursor.

* Lines (4) through (8) define the cursor T1Cursor. Procedures PL/SQL procedures behave very much like procedures in other programming language. END addtuple1. * Lines (11) through (16) are a PL/SQL loop. a fetch through the cursor into the local variables. Notice that such a loop is bracketed by LOOP and END LOOP. Here is an example of a PL/SQL procedure addtuple1 that. given an integer i. you will not get an error. * Line (18) ends the PL/SQL program. * Line (10) opens the cursor. o On Line (14). Line (8) declares the cursor FOR UPDATE since we will modify T1 using this cursor later on Line (14). On the . o On Line (13). * Lines (19) and (20) cause the program to execute. In general. CREATE PROCEDURE addtuple1(i IN NUMBER) AS BEGIN INSERT INTO T2 VALUES(i. * Line (17) closes the cursor.whatever types they may have are copied to the PL/SQL variables (compare with the previous example. and we know they are of the correct type. Within the loop we find: o On Line (12). FOR UPDATE is unnecessary if the cursor will not be used for modification. Since the query of Lines (5) through (7) produces pairs. 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. In general. a test for the loop-breaking condition. where we were less careful and declared the corresponding variables to be of type NUMBER). That query selects those tuples of T1 whose first component is less than the second component. It ranges over a relation defined by the SELECT-FROM-WHERE query. 'xxx'). A procedure is introduced by the keywords CREATE PROCEDURE followed by the procedure name and its parameters. The advantage of doing so is that should you have already made the definition. a SQL INSERT statement that inserts the reverse tuple into T1. the FETCH statement must provide variables for each component of the tuple retrieved. An option is to follow CREATE by OR REPLACE. we have correctly provided two variables. an essential step. run. * Line (9) begins the executable section of the program. b CHAR(10) ). a SQL DELETE statement that deletes the current tuple using the special WHERE condition CURRENT OF T1Cursor. o On Line (15). inserts the tuple (i. 'xxx') into the following example relation: CREATE TABLE T2 ( a INTEGER.

CHAR or VARCHAR should be used instead.a%TYPE. For example: BEGIN addtuple1(99).b%TYPE) AS BEGIN INSERT INTO T2(a. . which is essentially a PL/SQL block.. AS <local_var_declarations> BEGIN <procedure_body> END. OUT (write-only). you will not be warned. Following the arguments is the keyword AS (IS is a synonym). but this is optional. The actual length of a parameter depends on the corresponding argument that is passed in when the procedure is invoked. For example. but it takes both components as arguments: CREATE PROCEDURE addtuple2( x T2. and INOUT (read and write). . the type specifier in a parameter declaration must be unconstrained. run. Then comes the body. The following procedure also inserts a tuple into T2.. the DECLARE section should not start with the keyword DECLARE. use another PL/SQL statement. Note: Unlike the type specifier in a PL/SQL variable declaration. b) VALUES(x. We have repeated the name of the procedure after the END. The run at the end runs the statement that creates the procedure. END. should the previous definition be a different procedure of the same name. . However. following AS we have: . y T2. Rather. The possible modes are IN (read-only).other hand. run. in which the procedure is invoked as an executable statement. To execute the procedure. and the old procedure will be lost. y). each followed by a mode and a type. END addtuple2. it does not execute the procedure. There can be any number of parameters. CHAR(10) and VARCHAR(20) are illegal.

. b OUT NUMBER) AS BEGIN b := 4. run. END. 'abc'). run. END. Now. BEGIN addtuple3(10. b INTEGER ). . to add a tuple (10. END. v). 'abc') to T2: BEGIN addtuple2(10. INSERT INTO T3 VALUES(a.. CREATE PROCEDURE addtuple3(a NUMBER. b). The following illustrates the use of an OUT parameter: CREATE TABLE T3 ( a INTEGER. DECLARE v NUMBER. run. . run.

We declare a bind variable as follows: . object_name from user_objects where object_type = 'PROCEDURE' or object_type = 'FUNCTION'. A constant or a literal argument should not be passed in for an OUT/INOUT parameter. it gives you a cryptic message such as "procedure created with compilation errors".Note that assigning values to parameters declared as OUT or INOUT causes the corresponding input arguments to be written. Printing Variables Sometimes we might want to print the value of a PL/SQL local variable. To drop a stored procedure/function: drop procedure <procedure_name>.. A more couth way is to define a bind variable. such as a variable like v in the example above. SHO ERR (short for SHOW ERRORS) to see the most recent compilation error. try issuing the command show errors procedure <procedure_name>. A ``quick-anddirty'' way is to store it as the sole tuple of some relation and after the PL/SQL statement print the relation with a SELECT statement. We can also write functions instead of procedures. In a function declaration." exits from the function and returns the value of <expression>. The steps are as follows: 1. If you don't see what is wrong immediately. we follow the parameter list by RETURN and the type of the return value: CREATE FUNCTION <func_name>(<param_list>) RETURN <return_type> AS . To find out what procedures and functions you have created. In the body of the function definition. you can type. Bind variables are the kind that must be prefixed with a colon in PL/SQL statements. "RETURN <expression>. use the following SQL query: select object_type. the input argument for an OUT or INOUT parameter should be something with an "lvalue". Instead. drop function <function_name>.. which is the only kind that may be printed with a print command. Alternatively. Because of this. Discovering Errors PL/SQL does not always tell you about compilation errors.

cursors etc. The declare section contains declaration of memory variables. END. 3. constants. PRINT :x. Finally. or CHAR(n). CHAR. The begin section contains sql executable statements and pl/sql executable statements. -----The Master BEGIN and END section that contains the EXCEPTION section. A bit about it's working. run. but we must prefix it with a colon. and sql statements are sent to the sql executor in the oracle engine. The exception section contains code to handle errors that may arise during the execution of the code block. the codes executes smoothly and efficiently. where procedural statements are executed. we can execute a statement PRINT :<name>. VARIABLE x NUMBER BEGIN :x := 1.VARIABLE <name> <type> where the type can be only one of three things: NUMBER. Since pl/sql engine resides in the oracle engine. which prints the value 1. outside the PL/SQL statement Here is a trivial example. PL/SQL DATA-TYPE . 2. . It is sent to the pl/sql engine. The end declares the end of pl/sql block. We may then assign to the variable in a following PL/SQL statement. When you typed out the pl/sql block for execution. PL/SQL BLOCK The pl/sql block contains the following section:------The DECLARE section.

Put_line expects a single parameter of character data type. NULL etc since they r quite easy to understand. varchar. -. HOW TO DISPLAY MESSAGES ON SCREEN --DBMS_OUTPUT : is a package that includes a number of procedure and functions that accumulate information in a buffer so that it can be retrieved later.put_line(x). AND. > . >=. SERVEROUTPUT is a sql*plus environment parameter that displays the information pased as a parameter to the PUT_LINE function. char etc etc. I won't discuss about logical comparisons operators such as <.The C style comment such as /* i am a comment */ CONDITIONAL CONTROL AND ITERATIVE CONTROL AND SEQUENTIAL CONTROL IF and else. Variables must be separated from each other by at least one space or by a punctuation mark. IF --Condition THEN --Action ELSEIF --Condition THEN . -. Some of the attributes such as %TYPE is also used. A comment can have 2 forms i. EG: dbms_output.. it is the message 'string'. PUT_LINE : Put a piece of information in the package buffer followed by an end-of-line marker. This attribute automatically takes in the default data type of the sql table from which u have passed the query.This is easy since it includes almost all the data types which u have used in sql such as date. Remember in pl/sql a variable name must begin with a character and can be followed by maximum of 29 other characters. OR. NOT. These functions can also be used to display messages to the user. Reserved words can't be used unless enclosed within double quotes. EG: SET SERVEROUTPUT ON A bit about comments... number.... If used to display a message. TRUE.The comment line begins with a double hyphen (--). REMEMBER: To display messages to the user the SERVEROUTPUT should be set to ON. You can assign values of operator using := operator. It can also be used to display message to the user.e. We will discuss this later. The entire line will be treated as a comment.

b:=&b.10 loop --sequence of statements end loop... . the loop ends when u use EXIT WHEN statement --condition WHILE LOOP While --condition loop --sequence of statements end loop.put_line('Sum of ' || a || ' and ' || b || ' is ' || c). end loop... b number. begin a:=&a. Here & is used to take user input at runtime. GOTO (sequential control) GOTO X. << X >> EXAMPLES --ADDITION declare a number. SIMPLE LOOP loop -..--Action ELSE --Action END IF. c number.Sequence of statements. dbms_output. FOR LOOP FOR i in 1. c:=a+b.

n:=1. loop s1:=s1+a.put_line('Sum between 1 to 100 is '||s1).for loop declare n number. endvalue number. begin endvalue:=&endvalue.2)=1 then sum1:=sum1+n. endvalue number. --SUM OF odd NUMBERS USING USER INPUT. exit when (a=100). a:=a+1.. begin endvalue:=&endvalue. sum1 number default 0. WHILE LOOP declare n number. End. sum1 number default 0. end if end loop. --SUM OF 100 ODD NUMBER . s1 number default 0. endvalue loop if mod(n. dbms_output. for n in 1. end.... while (n < endvalue) .--SUM OF 100 NUMBERS Declare a number. Begin a:=1. end loop. n:=1.put_line('sum = ' || sum1). dbms_output.

hra number. end if. da number. basic:=&basic.put_line('Net salary : ' || netsalary). dbms_output. end. n:=n+2. basic number. elsif (basic >= 5000 and basic <= 8000) then pf:=basic * (8/100).put_line('Employee name : ' || ename).put_line('Providend Fund : ' || pf). end loop. begin ename:=&ename. pf number. hra:=basic * (15/100). dbms_output. else pf:=basic * (10/100). --MAXIMUM OF 3 NUMBERS . elsif (basic >= 3000 and basic <= 5000) then pf:=basic * (7/100).put_line('Sum of odd numbers between 1 and ' || endvalue || ' is ' || sum1). netsalary number.loop sum1:=sum1+n. dbms_output. da:=basic * (41/100). --CALCULATION OF NET SALARY declare ename varchar2(15). if (basic < 3000) then pf:=basic * (5/100). netsalary:=basic + da + hra -pf. dbms_output. end.

end. c:=&b. end if. d number. elsif (b>a) and (b>c) then dbms_output. --QUERY EXAMPLE--IS SMITH EARNING ENOUGH declare s1 emp. End.put_line('Enter b:'). dbms_output. end if. dbms_output. if(no_data_found) then raise_application_error (20001. if(s1 > 10000) then raise_application_error (20002. c number. a:=&a. end if.putline('A is Maximum'). b:=&b. Begin dbms_output. update emp set sal=sal + 500 where ename='SMITH'.putline('C is Maximum').put_line('Enter a:').sal %type.putline('B is Maximum'). else dbms_output. begin select sal into s1 from emp where ename = 'SMITH'.put_line('Enter c:'). .'smith is not present').Declare a number. b number. if (a>b) and (a>c) then dbms_output.'smith is earning enough').

dbms_output.. <> IF a = 1 THEN DBMS_OUTPUT. end loop. BEGIN FOR i IN 2. j number:= 0. a NUMBER (4). begin while i <=100 loop j := j+1. --EXAMPLE OF WHILE LOOP Declare i number:=0.--PRIME NO OR NOT DECLARE no NUMBER (3) := &no. END. END LOOP. begin loop a := a+25. IF a = 0 THEN GOTO out. end. END IF.1 LOOP a := no MOD i. .PUT_LINE (no || ' is a prime number'). ELSE DBMS_OUTPUT. --SIMPLE EXAMPLE OF LOOP STATEMENT I.put_line (to_Char(a)).no .E. END IF. EXIT WHEN Declare a number:= 100.PUT_LINE (no || ' is not a prime number'). exit when a=250. b NUMBER (2).

While radius <=7 Loop area := pi* power(radius. << Upd >> Update price set minprice = 6999 where prodid=111.2) := 3. STORE THE RADIUS AND THE CORRESPONDING VALUES OF CALCULATED AREA IN A TABLE AREAS. end if. radius number(5). end. end. --EXAMPLE OF FOR LOOP Declare begin for i in 1.put_line(to_char(i)).10 loop dbms_output. --SEQUENTIAL CONTROL GOTO declare --takes the default datatype of the column of the table price cost price. if cost > 7000 then goto Upd. area number(14. end loop.2). begin select stdprice into cost from price where prodial in (Select prodid from product where prodese = "shampoo"). Declare pi constant number(4. dbms_output. Begin radius := 3.14. end. --CALCULATE THE AREA OF A CIRCLE FOR A VALUE OF RADIUS VARYING FROM 3 TO 7.i := i +2. .2). end loop..minprice%type.put_line(to_char(i)).

radius:= radius+1. 1). str_length number(2)..str_length loop inverted_number := inverted_number || substr(given_number. dbms_output. area). EXCEPTION HANDLING IN PLSQL Errors in pl/sql block can be handled..This is exactly the same as we do in C++ or java.error handling refers to the way we handle the errors in pl/sql block so that no crashing stuff of code takes place. end.. end loop.put_line('The inverted number is ' || inverted_number). Begin str_length := length(given_number).. end.. cntr. inverted_number varchar(5).Insert into areas values (radius. For cntr in reverse 1.put_line('The Given no is ' || given_number)..right!! There are two type: ===> predefined exceptions ===> user defined exceptions The above 2 terms are self explanatory predefined exceptions: No-data-found == when no rows are returned Cursor-already-open == when a cursor is opened in advance Dup-val-On-index == for duplicate entry of index.. Storage-error == if memory is damaged Program-error == internal problem in pl/sql Zero-divide == divide by zero invalid-cursor == if a cursor is not open and u r trying to close it Login-denied == invalid user name or password Invalid-number == if u r inserting a string datatype for a number . end loop. dbms_output. --REVERSING A NUMBER 5639 TO 9365 Declare given_number varchar(5) := '5639'.

sal%TYPE. exception when --exception name then sequence of statements. EXCEPTION WHEN no_data_found THEN RAISE_APPLICATION_ERROR (-20001. end. end.'). END IF.'). sal1 emp. EXAMPLES --When there is no data returned by row declare price item. . e1 EXCEPTION. WHEN e1 THEN RAISE_APPLICATION_ERROR (-20002.actualprice%type. BEGIN SELECT sal INTO sal1 FROM emp WHERE deptno = 30 AND ename = 'John'. --EXAMPLE OF USER DEFINED EXCEPTION DECLARE e_rec emp%ROWTYPE. when no-data-found then dbms_output. IF sal1 < 5000 THEN RAISE e1. UPDATE emp SET sal = sal1 WHERE deptno = 30 AND ename = 'John'. begin Select actual price into price from item where qty=888. 'Less Salary. sal1 := 8500. END.put_line('item missing'). 'John is not there.datatype which is already declared Too-many-rows == if more rows r returned by select statement SYNTAX begin sequence of statements.

.... end. --INTERESTING EG OF USER DEFINED EXCEPTIONS Declare zero-price exception. update emp set sal=sal+500 where ename='SOMDUTT'. begin select sal into s1 from emp where ename='SOMDUTT'..... 'somdutt is earing a lot').. 'somdutt is not there')..cursors are generally used in such a case when a query .now the cursor is transferred to the client where again cursor is created and hence the result is displayed.. price number(8). end if...put_line('raised xero-price exception').YOU RAISE YOUR OWN ERROR Declare s1 emp... Cursors are of 2 types: implicit and explicit... if(s1 > 10000) then raise_application_error(20002. You can independently manipulate cursor values. suppose you ask for a query stored in the server . at first a cursor consisting of query result is created in server.. THIS IS YOUR OWN ERROR STATEMENT. A bit about it's working.. Each column value is pointed using pointer. end if. if(no-data-found) then raise_application_error(20001. exception when zero-price then dbms_output...sal %type.. CURSORS Cursor is a work area in pl/sql which is used by sql server used to store the result of a query.implicit cursors are created by oracle engine itself while explicit cursors are created by the users.--EXAMPLE OF RAISE-APPLICATION-ERROR. if price=0 or price is null then raise zero-price... end.... end if. begin select actualprice into price from item where ordid =400..

close statement closes the cursor.put_line('employee no does not exist'). false otherwise %FOUND == returns true if recod was fetched successfully.put_line('employee record modified successfully'). Cursor attributes %ISOPEN == returns true if ursor is open.put_line('employee record modified successfully').. if sql%found then dbms_output...so cursors are used.open statement identifies the active set.. else dbms_output....15 where emp_code = &emp_code.. They are Open.. else dbms_output.... if sql%notfound then dbms_output.and fetch statement fetches rows into the variables. Very important: Cursor can be controlled using following 3 control statements.returns more than one rows. --EXAMPLE FOR SQL%NOTFOUND (IMPLICIT CURSORS) begin update employee set salary = salary*0..e... false otherwise %NOTFOUND == returns true if record was not fetched successfully.put_line('employee no . end.i. .Cursors can be made into use using cursor for loop and fetch statement. Fetch...normal pl/sql returning more than one rows givens error but using cursor this limitation can be avoided. false otherwise %ROWCOUNT == returns number of records processed from the cursor...... query returned by select statement. EXAMPLES --EXAMPLE OF SQL%FOUND (IMPLICIT CURSORS) begin update employee set salary=salary *0.. end if.. does not exist')..we will see the corresponding examples. Close.15 where emp_code = &emp_code.

begin update employee set salary = salary*0. end if.. close. end.. Syntax Syntax Syntax Syntax of of of of explicit cursor: Cursor cursorname is sql select statement.mgr%type.deptno%type. str_hiredate emp.ename%type. str_job emp.PUT_LINE (str_empno || ' ' || str_ename || ' ' || . --EXPLICIT CURSOR EG DECLARE CURSOR c1 is SELECT * FROM emp. close cursorname. else dbms_output. str_sal emp. str_comm emp..15 where job='programmers'. if sql%rowcount > 0 then dbms_output. BEGIN rno := &rno. variable2.put_line('There are no employees working as programmers'). open cursorname.comm%type.end if.hiredate%type.sal%type. open cursor.empno%type. FOR e_rec IN c1 LOOP IF c1%rowcount = rno THEN DBMS_OUTPUT. rno number. str_empno emp. str_deptno emp. str_mgr emp. end. fetch : fetch cursorname into variable1.job%type. --EXAMPLE FOR SQL%ROWCOUNT (IMPLICIT CURSORS) declare rows_affected char(4).put_line(rows_affected || 'employee records modified successfully'). rows_affected := to_char(sql%rowcount). str_ename emp.

PUT_LINE('Salary: ' || ' ' || e_rec. -.EXAMPLE OF CURSOR FOR LOOP declare cursor c1 is select * from somdutt. BEGIN FOR e_rec IN c1 LOOP DBMS_OUTPUT. EXIT WHEN c1%ROWCOUNT >= 10. --ANOTHER EG DISPLAYING VALUE OF A TABLE DECLARE CURSOR c1 IS SELECT * FROM emp. LOOP FETCH c1 INTO e_rec.PUT_LINE('Number: ' || ' ' || e_rec. DBMS_OUTPUT. DBMS_OUTPUT. DBMS_OUTPUT. END IF.sal).empno). e_rec emp%rowtype. EXIT WHEN c1%NOTFOUND.PUT_LINE('Name : ' || ' ' || e_rec. e_rec emp%rowtype. END LOOP. END. begin for outvariable in c1 loop . DBMS_OUTPUT. DBMS_OUTPUT. END. END.PUT_LINE('Number: ' || ' ' || e_rec. END LOOP. -.ename).Display details of Highest 10 salary paid employee DECLARE CURSOR c1 IS SELECT * FROM emp ORDER BY sal DESC.str_job || ' ' || str_mgr || ' ' || str_hiredate || ' ' || str_sal || ' ' || str_comm || ' ' || str_deptno).ename).PUT_LINE('Name : ' || ' ' || e_rec.PUT_LINE('Salary: ' || ' ' || e_rec. CLOSE c1.empno). BEGIN OPEN c1.sal). END LOOP.

').PUT_LINE ('Employee No : ' || e_rec.'). close tcur. if outvariable. --ref STRONG CURSORS DECLARE TYPE ecursor IS REF CURSOR RETURN emp%ROWTYPE. . end if.PUT_LINE ('Emp table opened. ecur ecursor. DBMS_OUTPUT. d1 dept%ROWTYPE. dn NUMBER. DBMS_OUTPUT. IF tname = 'emp' THEN OPEN tcur FOR SELECT * FORM emp.exit when c1%notfound.salary). tname VARCHAR2(20).empno). tcur tcursor. END LOOP. BEGIN dn := &deptno. OPEN ecur FOR SELECT * FROM emp WHERE deptno = dn.age < 21 then dbms_output. --REF WEAK CURSORS DECLARE TYPE tcursor IS REF CURSOR. e1 emp%ROWTYPE.PUT_LINE ('Dept table opened. end. DBMS_OUTPUT.put_line(outvariable. BEGIN tname := &tablename.PUT_LINE ('Emp table closed. DBMS_OUTPUT.PUT_LINE ('Employee Salary: ' || e_rec.'). end loop. DBMS_OUTPUT. e_rec emp%ROWTYPE. close tcur.'). END.age || ' ' || outvariable. ELSE IF tname = 'dept' THEN OPEN tcur FOR SELECT * FROM dept. FOR e_rec IN ecur LOOP DBMS_OUTPUT.PUT_LINE ('Emp table closed.name).

e. TRIGGERS Trigger is a stored procedure which is called implicitly by oracle engine whenever a insert. --CURSOR FOR LOOP WITH PARAMETERS Declare Cursor c1(Dno number) is select * from emp where deptno = dno.begin.put_line(empree.. 'Table name is wrong').[before/after] [insert/pdate/delete] on --tablename-. from 8 a. END.and for each row and for each statement trigger. before trigger is fired before insert/update/delete statement while after trigger is fired after insert/update/delete statement. end loop.. begin for empree in c1(10) loop. dbms_output.m.. Syntax: Create or replace trigger --triggername-..for each row and for each statements triggers are self explainatory..ename)... update or delete statement is fired.ELSE RAISE_APPLICATION_ERROR (-20004.m to 5.) from monday ..00 p.[for each satement/ for each row] [when --condition--] plus. end.and exception Triggers are of following type: before or after trigger .A database trigger that allows changes to employee table only during the business hours(i.. Advantages of database triggers: ---> Data is generated on it's own ---> Replicate table can be maintained ---> To enforce complex integrity contraints ---> To edit data modifications ---> To autoincrement a field etc. EXAMPLE -.. END IF.

empno then dbms_output. 'your no is greater than 5000'). A stored procedure or function is a named pl/sql code block that have been compiled and stored in one of the . --A TRIGGER WHICH WILL NOT ALLOW U TO ENTER DUPLICATE VALUES IN FIELD EMPNO IN EMP TABLE Create or replace trigger dubb before insert on emp for each row Declare cursor c1 is select * from emp.:old.empno is null then dbms_output.'YOU CAN ACCESS ONLY BETWEEN 10 AM TO 5 PM ON MONDAY TO FRIDAY ONLY. begin raise_application_error(-20000.'). begin open c1. close c1.which consists of a set of sql statement.job. end. end. end. IF U DELETE A RECORD FROM ONE TABLE . exit when c1%notfound. save the file.ename = upper(:New. --NO CHANGES CAN BE DONE ON A PARTICULAR TABLE ON SUNDAY AND SATURDAY Create or replace trigger change before on emp for each row when (to_char(sysdate.'hh24')) >= 17 OR TO_CHAR(SYSDATE. 'u cannot enter data in saturnday and sunday'). PROCEDURES AND FUNCTIONS procedure is a subprogram. END..:old. and then sql> @ triggername --To STICK IN SAL FIELD BY TRIGGER MEANS WHEN U ENTER GREATER THAN 5000. end. There is no restriction on viewing data from the table -CREATE OR REPLACE TRIGGER Time_Check BEFORE INSERT OR UPDATE OR DELETE ON EMP BEGIN IF TO_NUMBER(TO_CHAR(SYSDATE. IT WILL BE INSERTED IN 2ND TABLE ED TRIGGERNAME Create or replace trigger backup after delete on emp fro each row begin insert into emp/values (:old.'DAY') = 'SAT' OR TO_CHAR(SYSDATE.'DAY') = 'SAT' THEN RAISE_APPLICATION_ERROR (-20004. elseif :New. Procedures are not very different from functions. --IF U ENTER IN EMP TABLE ENAME FIELD'S DATA IN ANY CASE IT WILL BE INSERTED IN CAPITAL LETTERS'S ONLY Create or replace trigger cap before insert on emp for each row begin :New... THEN THIS TRIGGER IS EXECUTED Create or replace trigger check before insert on emp for each row when (New. end loop.'hh24')) < 10 OR TO_NUMBER(TO_CHAR(SYSDATE.'SUN')) begin raise_application_error(200001.put_line('you entered duplicated no').'dy') in ('SAT'.put_line('you empno is null'). A procedure or function is a logically grouped set of SQL and PL/SQL statements that perform a specific task.ename).. END IF. x emp%rowtype. statement.empno = x. end.. if :New. loop fetch c1 into x. --YOU HAVE 2 TABLES WITH THE SAME STRUCTURE.sal).sal > 5000). end if.ename. Remember trigger can be dropped using Drop Trigger triggername .to saturday.

The out variable being global by nature.. To make a procedure or function dynamic either of them can be passed parameters before execution. A procedure or function can then change the way it works depending upon the parameters passed prior to its execution. IN OUT} data type. constant declarations...e. Syntax for stored procedure: CREATE OR REPLACE PROCEDURE [schema] procedure name (argument { IN. Verifies procedure or function validity and executes the procedure or function. END.) {IS. integrity. A function can return only one value to the calling pl/sql block. . EXCEPTION exception pl/sql block. Most important the difference between procedures and functions: A function must return a value back to the caller. performance. memory allocation.Verifies user access.. an executable part and an optional exception-handling part A declaration part consists of declarations of variables.. A executable part consists of the logic i. Syntax for stored function: CREATE OR REPLACE FUNCTION [schema] functionname(argument IN data type. constant declarations. By defining multiple out parameters in a procedure. END. AS} variable declarations. sql statements. Procedures and function are made up of a declarative part. . productivity. . Some of the advantages of using procedures and functions are: security. BEGIN pl/sql subprogram body. its value is accessible by any pl/sql code block including the calling pl/sql block.oracle engines's system tables. OUT. EXCEPTION exception pl/sql block. AS} variable declarations. BEGIN pl/sql subprogram body.) RETURN data type {IS.and exception handling part handles any error during run-time The oracle engine performs the following steps to execute a procedure or function.... multiple values can be passed to the caller.

By default it takes IN. --return (x*x).... --FUNCTION using argument CREATE OR REPLACE FUNCTION RMT(X IN NUMBER) RETURN NUMBER IS BEGIN dbms_output. OUT : specifies that the procedure passes a value for this argument back to its calling environment after execution.ename). --PROCEDURE USING ARGUMENT CREATE OR REPLACE PROCEDURE ME( X IN NUMBER) IS BEGIN dbms_output.IN : specifies that a value for the argument must be specified when calling the procedure or function. parentheses can be omitted if no arguments are present. . end loop.put_line(erec. begin for erec in cur1 loop dbms_output..put_line(x*x)...put_line(x*x). end. IN OUT : specifies that a value for the argument must be specified when calling the procedure and that the procedure passes a value for this argument back to its calling environment after execution.. EXAMPLES --PROCEDURE USING NO ARGUMENT. end.put_line(rmt(3)). end. argument : is the name of an argument to the procedure or function. (make a block like this to run it.. sql> exec me(3).The above syntax i think is self explanatory..) begin dbms_output.AND USING CURSOR CREATE OR REPLACE PROCEDURE P2 IS cursor cur1 is select * from emp. Data type : is the data type of an argument.but i will give you some details.

enquiry c where c. --AND FIND OUT FEES PAID BY THAT STUDENT CREATE or REPLACE procedure me (namee in varchar) is cursor c1 is select a. --CREATE A PROCEDURE THAT DELETE ROWS FROM ENQUIRY --WHICH ARE 1 YRS BEFORE Create or replace procedure myprocedure is begin delete from enquiry where enquirydate <= sysdate .rollno and c. Begin a:=50.put_line(erec. b number.end. enrollment b. End. c number.enquiryno and a. dbms_output. --SUM OF 2 Numbers CREATE or replace procedure p1 is Declare a number.rollno = b. begin for erec in c1 loop dbms_output.put_line('Sum of '||a||' and '||b||' is '||c). end. --CREATE A PROCEDURE THAT TAKES ARGUMENT STUDENT NAME.feespaiddate from feespaid a. end loop.enquiryno = b.fname = namee.1.feespaiddate). c:=a+b. b:=89. end. --DELETION PROCEDURE create or replace procedure myproc is .

end . begin sample(3000. begin select ordid. b in out number) is identity number. b number. prodid into identity. begin select ordid into identity from item where itemid = a. end. end. . end if. --SIMILAR EXAMPLE AS BEFORE create or replace procedure getsal( sal1 in out number) is begin select sal into sal1 from emp where empno = sal1. b) dbms_output. if b<600 then b := b + 100. b from item where itemid=a. --IN and OUT procedure example Create or replace procedure lest ( a number. b out number) is identify number.begin delete from enquiry where fname='somdutt'. end if. now procedure is called by passing parameter declare a number. end l --in out parameter Create or replace procedure sample ( a in number.put_line(1th value of b is 11 b). if identity < 1000 then b := 100. end .

.. Objects commonly held within a package are procedures..also if u wanna drop a function then use drop function functionname and for procedure use drop procedure procedurename PACKAGES A package is an oracle object.. procedure rmt1(x in number)..now use the above in plsql block declare sal1 number := 7999..... begin getsal(sal1). Packages in plsql is very much similar to those packages which we use in JAVA. cursors and exceptions...right!!!. end . EXAMPLE --SIMPLEST EG --specification create or replace package pack2 is function rmt(x in number) return number. which holds other objects within it. package specification and package body A package specification part consists of all sort of declaration of functions and procedures while package body consists of codings and logic of declared functions and procedures. constants.. --body create or replace package body pack2 is function rmt(x in number) return number is . You can make a procedure and functions similarly.... variables. end. dbms_output.put_line('The employee salary is' || sal1).. functions.. A package has 2 parts..yeah!! java packages holds numerous classes.

procedure rmt1(x in number) is begin dbms_output. procedures and functions..Just try out packages which includes cursors. (how to run.) exec packagename.you can easily modify the above code to fit your requirement...put_line(x*x).Remeber pl/sql supports overloading. you can use the same function or procedure name in your application but with different no or type of arguments. exec pack2....i..procedurename i.e.etc.begin return (x*x). As shown above u can put in complicated procedures and functions inside the package.I have just shown a simple example.. end. end.... ....rmt1(3).e... end..

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->