Sie sind auf Seite 1von 43

Foreign key

A foreign key is a way to enforce referential integrity within your Oracle database. The referenced table is
called the parent table while the table with the foreign key is called the child table. The foreign key in the
child table will generally reference a primary key in the parent table.

Set NULL on Delete


A foreign key with "set null on delete" means that if a record in the parent table is deleted, then the
corresponding records in the child table will have the foreign key fields set to null. The records in the child
table will not be deleted.
Create table emp
(empid number not null,
Ename varchar2(50) not null,
Deptno number not null,
Constraint deptno_pk PRIMARY KEY (deptno)
);
Create table dept
(
Deptno number,
Deptname varchar2(50),
Constraint fk_deptno
FOREIGN KEY(deptno)
REFERENCES EMP(DEPTNO)
ON DELETE SET NULL
);

Cascade DELETE

A foreign key with cascade delete means that if a record in the parent table is deleted, then the
corresponding records in the child table with automatically be deleted. This is called a cascade delete in
Oracle.
Create table emp
(empid number not null,
Ename varchar2(50) not null,
Deptno number not null,
Constraint deptno_pk PRIMARY KEY (deptno)
);
Create table dept
(
Deptno number,
Deptname varchar2(50),
Constraint fk_deptno
FOREIGN KEY(deptno)
REFERENCES EMP(DEPTNO)
ON DELETE CASCADE
);

SAVEPOINT
Use the SAVEPOINTstatement to identify a point in a transaction to which you can roll back
later.
UPDATEemployees
SETsalary=7000
WHERElast_name='Banda';
SAVEPOINTa;
UPDATEemployees
SETsalary=12000
WHERElast_name='Greene';
SAVEPOINTb;

ROLLBACKTOSAVEPOINTa;
COMMIT;

What is View :View is database object which is usually providing the authority of security levels. View doesnt store
data. View is virtual table. it is created by a query joining one or more tables.
Sytax
Create view ViewName as select columns from tables

Types of views
1) Simple view

What is PL/SQL?
PL/SQL stands for Procedural Language extension of SQL.
PL/SQL is a combination of SQL along with the procedural features of programming languages.
It was developed by Oracle Corporation in the early 90s to enhance the capabilities of SQL.
The PL/SQL Engine:
Oracle uses a PL/SQL engine to processes the PL/SQL statements. A PL/SQL code can be stored in the
client system (client-side) or in the database (server-side).
A Simple PL/SQL Block:
Each PL/SQL program consists of SQL and PL/SQL statements which from a PL/SQL block.
PL/SQL Block consists of three sections:

The Declaration section (optional).


The Execution section (mandatory).
The Exception (or Error) Handling section (optional).

Declaration Section:

The Declaration section of a PL/SQL Block starts with the reserved keyword DECLARE. This section is
optional and is used to declare any placeholders like variables, constants, records and cursors, which are
used to manipulate data in the execution section. Placeholders may be any of Variables, Constants and
Records, which stores data temporarily. Cursors are also declared in this section.
Execution Section:
The Execution section of a PL/SQL Block starts with the reserved keyword BEGIN and ends with END.
This is a mandatory section and is the section where the program logic is written to perform any task. The
programmatic constructs like loops, conditional statement and SQL statements form the part of execution
section.
Exception Section:
The Exception section of a PL/SQL Block starts with the reserved keyword EXCEPTION. This section is
optional. Any errors in the program can be handled in this section, so that the PL/SQL Blocks terminates
gracefully. If the PL/SQL Block contains exceptions that cannot be handled, the Block terminates
abruptly with errors.
Every statement in the above three sections must end with a semicolon ; . PL/SQL blocks can be nested
within other PL/SQL blocks. Comments can be used to document code.
How a Sample PL/SQL Block Looks
DECLARE
Variable declaration
BEGIN
Program Execution
EXCEPTION
Exception handling
END;

Advantages of PL/SQL

Block Structures: PL SQL consists of blocks of code, which can be nested within each other. Each
block forms a unit of a task or a logical module. PL/SQL Blocks can be stored in the database and
reused.

Procedural Language Capability: PL SQL consists of procedural language constructs such as


conditional statements (if else statements) and loops like (FOR loops).

Better Performance: PL SQL engine processes multiple SQL statements simultaneously as a single
block, thereby reducing network traffic.

Error Handling: PL/SQL handles errors or exceptions effectively during the execution of a PL/SQL
program. Once an exception is caught, specific actions can be taken depending upon the type of the
exception or it can be displayed to the user with a message.

DECLARE
var_salary number(6);
var_emp_id number(6) = 1116;
BEGIN
SELECT salary
INTO var_salary
FROM employee
WHERE emp_id = var_emp_id;
dbms_output.put_line(var_salary);
dbms_output.put_line('The employee '
|| var_emp_id || ' has salary ' || var_salary);
END;
/
Scope of PS/SQL Variables

Local variables - These are declared in a inner block and cannot be referenced by outside Blocks.

Global variables - These are declared in a outer block and can be referenced by its itself and by
its inner blocks.

PL/SQL Constants
Constant is a value used in a PL/SQL Block that remains unchanged throughout the program.
constant_name CONSTANT datatype := VALUE;
DECLARE
salary_increase CONSTANT number(3);
BEGIN
salary_increase := 100;
dbms_output.put_line (salary_increase);
END;
Iterative Statements in PL/SQL
Iterative control Statements are used when we want to repeat the execution of one or more statements for
specified number of times.

There are three types of loops in PL/SQL:


Simple Loop
While Loop
For Loop
1) Simple Loop
A Simple Loop is used when a set of statements is to be executed at least once before the loop terminates. An
EXIT condition must be specified in the loop, otherwise the loop will get into an infinite number of iterations.
LOOP
statements;
EXIT;
{or EXIT WHEN condition;}
END LOOP;
2) While Loop
A while loop repeats set of statements in the plsql block as long as a condition is
true. The iteration continues until the condition becomes false.
WHILE <condition>
LOOP statements;
END LOOP;
3) For Loop
A for loop is used to execute a set of statements in plsql block for predetermined number of times.
Iteration occurs between the start and end integer values given. The counter is always incremented by 1.
The loop exits when the counter reachs the value of the end integer.
FOR counter IN val1..val2
LOOP statements;
END LOOP;
Cursors
A cursor is a temporary work area created in the system memory when a SQL statement is executed. 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.
Syntax
Declare
CURSOR [cursor name] [parameter]
Retrun [return type]
Is

Select statement
Begin
Open [cursor name];
Fetch [cursor name] into [return value];
Close [cursor name];
End;
Eg :-Declare cursor c1 is select * from emp;
V_emp emp%rowtype;
Begin
Open c1;
Loop
Fetch c1 into v_emp;
Dbms_output.put_line(The emp name is ||v_emp.ename);
End loop;
Close c1;
End;

TYPES OF CURSORS
There are two types of cursors
(1) An IMPLICIT cursor is automatically declared by Oracle every time an SQL statement is
executed. The user will not be aware of this happening and will not be able to control or process
the information in an implicit cursor.
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;
END;
(2) An EXPLICIT cursor is defined by the program for any query that returns more than one row of
data. That means the programmer has declared the cursor within the PL/SQL code block. This
declaration allows for the application to sequentially process each row of data as it is returned by
the cursor.
DECLARE
CURSOR emp_cur IS
SELECT first_name, last_name, salary FROM emp_tbl;
emp_rec emp_cur%rowtype;

BEGIN
IF NOT sales_cur%ISOPEN THEN
OPEN sales_cur;
END IF;
LOOP
FETCH emp_cur INTO emp_rec;
EXIT WHEN emp_cur%NOTFOUND;
dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name
|| ' ' ||emp_cur.salary);
END LOOP;
END;
/
Explicit Cursor Attributes
%NOTFOUND cursor_name%NOTFOUND A Boolean attribute that re-turns TRUE if the previous
FETCH did not return a row, and FALSE if it did.
%FOUND cursor_name%FOUND A Boolean attribute that re-turns TRUE if the previous FETCH
returned a row, and FALSE if it did not.
%ROWCOUNT cursor_name%ROWCOUNT # of records fetched from a cursor at that point in time.
%ISOPEN cursor_name%ISOPEN A Boolean attribute that re-turns TRUE if cursor is open, FALSE if it
is not.
Cursor with a FOR Loop:
When using FOR LOOP you need not declare a record or variables to store the cursor values, need not
open, fetch and close the cursor. These functions are accomplished by the FOR LOOP automatically.
DECLARE
CURSOR emp_cur IS
SELECT first_name, last_name, salary FROM emp_tbl;
emp_rec emp_cur%rowtype;
BEGIN
FOR emp_rec in sales_cur
LOOP
dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name
|| ' ' ||emp_cur.salary);
END LOOP;
END;
/
Ref Cursor
A ref cursor is a data type that holds a cursor value in the same way that a varchar2
variable will hold a string value. A ref cursor can be opened on the server and
passed to the client as a unit rather than fetching one row at a time. One can use a

ref cursor as target of an assignment, and it is can be passed as parameter to other


program units. Ref cursors are opened with an OPEN FOR statement. In most other
ways they behave like normal cursors.
Eg :
declare
type x is ref cursor;
y x;
stmt varchar2(200) := 'select * from emp where deptno= :X1';
V_deptno varchar2(10) := 10;
emp_rec emp%rowtype;
begin
open y for stmt using v_deptno;
loop
fetch y into emp_rec;
exit when y%notfound
dbms_output.put_line(emp_rec.ename||' , '|| emp_rec.deptno);
end loop;
close y;
end;
Passing parameter and Cursor within cursor
Declare
Cursor curdept is select distinct deptno from dept;
Cursor curemp(vardeptno dept.deptno%type) is select * from emp where
deptno=vardeptno;
Begin
For x in curdept
Loop
For y in curemp(x.deptno)
Loop
Insert into empdept(empno,ename,doj,sal,deptno,deptname,username,pwd)
values(y.empno,y.ename,y.doj,y.sal,x.deptno,x.deptname,x.username,x.pwd);
End loop;
End loop;
End;
Inline Cursor
A inline cursor is a cursor that is not declared in the declare section but the cursor
definition is included in FOR loop.
Declare
Vusername emp.username%type;
Vpwd emp.pwd%type;
Begin
For I in(select empno,f_name,l_name,sal from emp)

Loop
Vusername :=substr(i.f_name,2,3);
V_pwd:=substr(i.l_name,-2,2);
Update emp set username =vusername,pwd=vpwd ;
End loop;
Commit;
End;

For update of clause


Used to block the fetched rows from accessing it by other users.
Declare
Vsal number;
Cursor curempsal is select sal from emp where deptno=10) for update of sal;
Begin
Open curempsal;
Loop
Fetch curempsal into vsal;
Exit when curempsal %notfound;
Update emp set sal=sal+vsal*1.10 where current of curempsal;
End loop;
Close curempsal;
End;

Examples
--ANOTHER EG DISPLAYING VALUE OF A TABLE
DECLARE
CURSOR c1 IS SELECT * FROM emp;
e_rec emp%rowtype;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO e_rec;
DBMS_OUTPUT.PUT_LINE('Number: ' || ' ' || e_rec.empno);
DBMS_OUTPUT.PUT_LINE('Name : ' || ' ' || e_rec.ename);
DBMS_OUTPUT.PUT_LINE('Salary: ' || ' ' || e_rec.sal);
EXIT WHEN c1%NOTFOUND;
END LOOP;
CLOSE c1;
END;

-- Display details of Highest 10 salary paid employee


DECLARE
CURSOR c1 IS SELECT * FROM emp ORDER BY sal DESC;
e_rec emp%rowtype;
BEGIN
FOR e_rec IN c1
LOOP
DBMS_OUTPUT.PUT_LINE('Number: ' || ' ' || e_rec.empno);
DBMS_OUTPUT.PUT_LINE('Name : ' || ' ' || e_rec.ename);
DBMS_OUTPUT.PUT_LINE('Salary: ' || ' ' || e_rec.sal);
EXIT WHEN c1%ROWCOUNT >= 10;
END LOOP;
END;
-- EXAMPLE OF CURSOR FOR LOOP
declare cursor c1 is select * from somdutt;
begin
for outvariable in c1
loop
exit when c1%notfound;
if outvariable.age < 21 then
dbms_output.put_line(outvariable.age || ' ' || outvariable.name);
end if;
end loop;
end;
--ref STRONG CURSORS
DECLARE
TYPE ecursor IS REF CURSOR RETURN emp%ROWTYPE;
ecur ecursor;
e_rec emp%ROWTYPE;
dn NUMBER;
BEGIN
dn := &deptno;
OPEN ecur FOR SELECT * FROM emp WHERE deptno = dn;
FOR e_rec IN ecur
LOOP
DBMS_OUTPUT.PUT_LINE ('Employee No : ' || e_rec.empno);
DBMS_OUTPUT.PUT_LINE ('Employee Salary: ' || e_rec.salary);
END LOOP;
END;

--REF WEAK CURSORS


DECLARE
TYPE tcursor IS REF CURSOR;
tcur tcursor;
e1 emp%ROWTYPE;
d1 dept%ROWTYPE;
tname VARCHAR2(20);
BEGIN
tname := &tablename;
IF tname = 'emp' THEN
OPEN tcur FOR SELECT * FORM emp;
DBMS_OUTPUT.PUT_LINE ('Emp table opened.');
close tcur;
DBMS_OUTPUT.PUT_LINE ('Emp table closed.');
ELSE IF tname = 'dept' THEN
OPEN tcur FOR SELECT * FROM dept;
DBMS_OUTPUT.PUT_LINE ('Dept table opened.');
close tcur;
DBMS_OUTPUT.PUT_LINE ('Emp table closed.');
ELSE
RAISE_APPLICATION_ERROR (-20004, 'Table name is wrong');
END IF;
END;
--CURSOR FOR LOOP WITH PARAMETERS
Declare
Cursor c1(Dno number) is select * from emp where deptno = dno;
begin
for empree in c1(10) loop;
dbms_output.put_line(empree.ename);
end loop;
end;

Procudere
Procedure is a named block which are logically grouped sql and plsql statements
that performs specific tasks.
Syntax:-

CREATE [OR REPLACE] PROCEDURE proc_name [<IN,OUT,INOUT> <DATATYPE>]


IS
Declaration section
BEGIN
Execution section
EXCEPTION
Exception section
END;
IN
An IN parameter whose values is passed into a procedure. The value of IN
parameter is constant.
OUT
An out parameter whose values is passed out of the stored procedure.
INOUT
An INOUT Parameter whose values is passed into stored procedure and new value
can be assigned to the parameter and passed out of the procedure. INOUT is not
constant.
Eg:Create or replace procedure Acc_credit(v_accno number,v_creditamnt number)
As
V_bal number;
V_updbal number;
Begin
Select curbal into v_bal from accounts where accno=v_accno for update of curbal;
V_updbal:=v_bal+v_creditamnt;
Update accounts set curbal=v_updbal where accno=v_accno;
Commit;
Exception
When no_Data_Found then
Insert into accounts (accno,curbal) values(v_accno,v_creditamnt);
When others then
Rollback;
End acc_credit;
/
Execution of procedure
Exec acc_credit(2,2000);
Exec acc_credit(15,15000);

Advantages of Procedure are

1) Extensionality
2) Modularity
3) Maintainability
4) Reusability
5) One time compilation

PL/SQL Functions
A function is a named PL/SQL Block which is similar to a procedure. The major difference between a
procedure and a function is, a function must always return a value, but a procedure may or may not return
a value.
CREATE [OR REPLACE] FUNCTION function_name [parameters]
RETURN return_datatype;
IS
Declaration_section
BEGIN
Execution_section
Return return_variable;
EXCEPTION
exception section
Return return_variable;
END;
CREATE OR REPLACE FUNCTION employer_details_func
RETURN VARCHAR(20);
IS
emp_name VARCHAR(20);
BEGIN
SELECT first_name INTO emp_name
FROM emp_tbl WHERE empID = '100';
RETURN emp_name;
END;
/

Difference between Procedure and Function


Procedure
A procedure may return one or more values
through parameters or may not return values at all.

Function
A function always returns a value using return
statement.

A procedure doesnt contain return clause in header


and exec part
Select statement query can call function.
DML statements can be used in procedure
Procedures are used for business logic purposes

A function contains return clause in header and


exec part.
Select sql query cant call procedure.
DML cant be used in function.
Functions are used for computations or calculation
purposes.

Packages:
Oracle allows grouping stored procedures, functions, variables, constants, cursors
and exceptions into packages.
A package consist of
1) Package specification: - The package specification contains information about the package. The package specification
lists the available procedures and functions. The package specification generally doesn't contain the
code.
2) Package body: -- The package body contains the actual code.
Advantages
1) We can reduce input/output operations
2) Multiple interactions with database.
3) Improve performance while accessing sub programs from remote client.
4) Over loading
Syntax for package specification
Create or replace package <package name>
{is/as}
<package specification>
End <package name>;
Syntax for package Body
create or replace package body <package name>
{is/as}
<package body>

End <package name>;


INVOKING PACKAGE
Exec <package name>.<sub program>(<list of parameters>);
Recompile Package
Alter package <package name> compile package
Drop Package
Drop package <package name>
PACKAGE OVER LOADING
The same procedure name is repeated with parameters with different datatypes.
PL/SQL Records
Records are composite datatypes, which means it is a combination of different scalar datatypes like char,
varchar, number etc. TYPE rec record is to be used whenever query returns columns of different
tables views and variables.
TYPE record_type_name IS RECORD
(first_col_name column_datatype,
second_col_name column_datatype, ...);
Dynamically define the datatype of a column based on a database column as given below
col_name table_name.column_name%type;
Eg:Declare
Type ABC is record (a number,
b date);
x abc;
begin
x.a:=5;
x.b:=11-jul-2014;
end;

PL/SQL Collections
Collections are composite data types. Collections allow treating several variables as a unit. A collection
combines variables of the same type.

The types of collections are


1) VARRAYS
2) NESTED TABLES
3) INDEX BY TABLES (ASSOCIATE ARRAYS)

VARRAY: -- A VARRAY is data type similar to an array. A VARRAY has a fixed limit on its size,
Specified as part of declaration. Elements are inserted into VARRAY starting at index 1, up to maximum
length declared in the varray type. The maximum size of the VARRAY is 2 GB.
Syntax: -- TYPE <type name> is VARRAY (<Limit>) of <element type>;
Eg:-Declare
Type ABC is varray(10) of number;
V1 ABC :=abc(1,2,3,4,5,6)
Begin
Dbms_output.put_line(v1(1));
End;
By using select query
Declare
Type abc is varray (10) of number;
V2 abc;
Cusrsor c1 is select empno from emp where rownum<10;
V_emp abc;
Counter number :=1;
Begin
V2:=abc();
For I in 1 .. 10
Loop
V2.extend();
V2(i):=i;
Dbms_output.put_line(v2(i));
End loop;
V_emp :=abc();
For rec in c1
Loop
V_emp.extend();
V_emp(Counter) :=rec.empno;
Counter:=counter+1;
Dbms_output.put_line(v_emp(Counter));
End loop;
End;

Different Types of METHODS for varray and nested table :--

1)
2)
3)
4)
5)
6)
7)
8)

COUNT :-- Returns the total number of elements that a collection currently contains.
LIMIT :-- Returns the Maximum number of elements for a Varray or NULL for Nested Tables.
EXISTS(N) :-- Returns TRUE if the Nth element in a collection exists; otherwise FALSE.
FIRST :-- Returns the First index numbers in a collection that uses integer subscripts.
LAST :-- Returns the Last index numbers in a collection that uses integer subscripts.
PRIOR :-- Returns the index number that precedes index N in a collection
NEXT :-- Returns the index number that succeeds index N.
EXTEND :-- Add a null element to a collection.
TRIM :-- Removes one element from the end of a collection

Eg :-TYPE ABC IS Varray(10) of number;


V abc:=abc(1,2,3,4,5,6);
1 2 3 4 5 6
Begin
Dbms_output.put_line(v1.count ||v1.count); 6
Dbms_output.put_line(v1.limit || v1.limit); 10
Dbms_output.put_line(v1.first|| v1.first); 1
Dbms_output.put_line(v1.last || v1.last); 6
V1.trim(2) 5 and 6 index are deleted
1 2 3 4
For I in v1.first .. v1.last
loop
Dbms_output.put_line(v1); 1,2,3,4
End loop
Dbms_output.put_line(v1.last || v1.last); 4
End;
/

NESTED TABLES
A Nested table is thought of a database table which has no limit on its size. Elements are inserted into
nested table starting at index 1. The maximum size of the varray is 2 GB.
SYNTAX :-Type <type name> is table of <table type>;
Eg:-Declare
Type abc is table of number;
V2 abc;

Cursor c1 is select empno from emp;


V_emp abc;
Counter number :=1;
Begin
V_emp :=abc();
For rec in c1
Loop
V_emp.extend();
V_emp(counter):=rec.empno;
Counter:=counter+1;
Dbms_output.put_line(V_emp(counter))
End loop;
end;
INDEX-BY TABLE (ASSOCIATE ARRAY) :-An Index-by table has no limit on its size. Elements are inserted into index-by table whose index may
start non sequentially including negative integers.
Syntax :-Type <type name> is table of <table type> index by binary integer;
Eg:
Declare
Type ABC is table of date index by pls_integer;
V abc;
Begin
For I in 1..10
Loop
V(i):=sysdate+I;
End loop;
If (v.exists(11)) then
Dbms_output.put_line(elements exists);
Else
Dbms_output.put_line(elements not exists);
End if;
Dbms_output.put_line(total no of elements||v.count); 10
v.delete(7);
Dbms_output.put_line(total no of elements||v.count); 9
v.delete(8,10); 8,9,10 deleted.
Dbms_output.put_line(total no of elements||v.count); 6
For I in v.first..v.last
Dbms_output.put_line(the elements are||v(i)); 6 dates will print
End loop;
Dbms_output.put_line(next element is||v.next(4)); 5
Dbms_output.put_line(next element is||v.prior(4)); 3
End;
/

Different Types of METHODS index by table:--

1)
2)
3)
4)
5)
6)
7)
8)

COUNT :-- Returns the total number of elements that a collection currently contains.
LIMIT :-- Returns the Maximum number of elements for a Varray or NULL for Nested Tables.
EXISTS(N) :-- Returns TRUE if the Nth element in a collection exists; otherwise FALSE.
FIRST :-- Returns the First index numbers in a collection that uses integer subscripts.
LAST :-- Returns the Last index numbers in a collection that uses integer subscripts.
PRIOR :-- Returns the index number that precedes index N in a collection
NEXT :-- Returns the index number that succeeds index N.
EXTEND :-- Add a null element to a collection.
DELETE(N) :-- DELETE N element from the collection

BULK COLLECT:-Bulk Collect is used to retrieve all the records from the cursor into the array in one short. It will increase
the performance and it will reduce the context switches between sql engine and plsql engine.
The examples of bulk collect
Declare
Type t_eno is table of emp.empno%type;
Type t_ename is table of emp.ename%type;
V_eno t_eno;
V_ename t_ename;
Cursor c1 is select empno,ename from emp;
Begin
Open c1;
Fetch c1 bulk collect into v_eno,v_ename;
Close c1;
For I in v_eno.first .. v_eno.last
Loop
Dbms_output.put_line(empno is ||v_eno(i) || emp name is ||v_ename(i));
End loop;
End;
2nd example
Declare
Type abc is table of emp%rowtype index by pls_integer;
V abc;
X number;
Y emp%rowtype;
Begin
Select * from bulk collect into v from emp;
X:=1;
Loop
Dbms_output.put_line(v(x).ename);
X:=v.next(x);
Exit when x is null;
End loop;
End;

For ALL or Bulk bind


Bulk binds with Insert, Update and Delete statements, you enclose the SQL statement within a
PL/SQL FORALL statement. To do bulk binds with Select statements, you include the Bulk Collect
INTO a collection clause in the SELECT Statement instead of using Simply into
Create table test (a varchar2(1000));
Declare
Type t_test is table of test.a%type index by pls_integer;
V_Rec t_Test;
Begin
For all I in v_rec.first..v_rec.last
Insert into test values(v_rec(i));
Commit;
End;
2nd example
CREATE OR REPLACE PROCEDURE fast_proc (p_array_size IN PLS_INTEGER DEFAULT 100)
IS
TYPE ARRAY IS TABLE OF all_objects%ROWTYPE;
l_data ARRAY;
CURSOR c IS
SELECT *
FROM all_objects;
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO l_data LIMIT p_array_size;
FORALL i IN 1..l_data.COUNT
INSERT INTO t2 VALUES l_data(i);
EXIT WHEN c%NOTFOUND;
END LOOP;
CLOSE c;
END fast_proc;
/
3rd example

create or replace procedure fast_proc is


type TObjectTable is table of ALL_OBJECTS%ROWTYPE;
ObjectTable$ TObjectTable;
begin
select
* BULK COLLECT INTO ObjectTable$
from ALL_OBJECTS;
forall x in ObjectTable$.First..ObjectTable$.Last
insert into t1 values ObjectTable$(x) ;
end;
/

EXCEPTIONS HANDLING
PL/SQL provides a feature to handle the Exceptions which occur in a PL/SQL Block known as exception
Handling. Using Exception Handling we can test the code and avoid it from exiting abruptly.
PL/SQL Exception message consists of three parts.
1) Type of Exception
2) An Error Code
3) a message
k
Syntax:-DECLARE
Declaration section
BEGIN
Exception section
EXCEPTION
WHEN ex_name1 THEN
-Error handling statements
WHEN ex_name2 THEN
-Error handling statements
WHEN Others THEN
-Error handling statements
END;
Types of Exception.
There are 3 types of Exceptions.

Implicit exception
a) Named System Exceptions or predefined exception
b) Unnamed System Exceptions or non-predefined exception
Explicit Exception
c) User-defined Exceptions
Named System Exceptions
System exceptions are automatically raised by Oracle, when a program violates a RDBMS rule. There are
some system exceptions which are raised frequently, so they are pre-defined and given a name in Oracle
which are known as Named System Exceptions.
BEGIN
Execution section
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line ('A SELECT...INTO did not return any row.');
END;
Pre-defined exceptions are
Exception

Raised when ...

CURSOR_ALREADY_OPEN

Your program attempts to open an already open cursor. A cursor


must be closed before it can be reopened. A cursor FOR loop
automatically opens the cursor to which it refers. So, your program
cannot open that cursor inside the loop.

DUP_VAL_ON_INDEX

Your program attempts to store duplicate values in a database


column that is constrained by a unique index.

INVALID_CURSOR

Your program attempts an illegal cursor operation such as closing an


unopened cursor.

INVALID_NUMBER

In a SQL statement, the conversion of a character string into a


number fails because the string does not represent a valid number.
(In procedural statements, VALUE_ERROR is raised.) This
exception is also raised when the LIMIT-clause expression in a bulk
FETCH statement does not evaluate to a positive number.

LOGIN_DENIED

Your program attempts to log on to Oracle with an invalid username

Exception

Raised when ...


and/or password.

NO_DATA_FOUND

A SELECT INTO statement returns no rows, or your program


references a deleted element in a nested table or an uninitialized
element in an index-by table. SQL aggregate functions such as AVG
and SUM always return a value or a null. So, a SELECT INTO
statement that calls an aggregate function never raises
NO_DATA_FOUND. The FETCH statement is expected to return no
rows eventually, so when that happens, no exception is raised.

NOT_LOGGED_ON

Your program issues a database call without being connected to


Oracle.

PROGRAM_ERROR

PL/SQL has an internal problem.

ROWTYPE_MISMATCH

The host cursor variable and PL/SQL cursor variable involved in an


assignment have incompatible return types. For example, when an
open host cursor variable is passed to a stored subprogram, the
return types of the actual and formal parameters must be compatible.

STORAGE_ERROR

PL/SQL runs out of memory or memory has been corrupted.

SUBSCRIPT_BEYOND_COUN Your program references a nested table or varray element using an


T
index number larger than the number of elements in the collection.

SUBSCRIPT_OUTSIDE_LIMIT Your program references a nested table or varray element using an


index number (-1 for example) that is outside the legal range.

TIMEOUT_ON_RESOURCE

A time-out occurs while Oracle is waiting for a resource.

TOO_MANY_ROWS

A SELECT INTO statement returns more than one row.

Exception

Raised when ...

VALUE_ERROR

An arithmetic, conversion, truncation, or size-constraint error occurs.


For example, when your program selects a column value into a
character variable, if the value is longer than the declared length of
the variable, PL/SQL aborts the assignment and raises
VALUE_ERROR. In procedural statements, VALUE_ERROR is
raised if the conversion of a character string into a number fails. (In
SQL statements, INVALID_NUMBER is raised.)

ZERO_DIVIDE

Your program attempts to divide a number by zero.

Unnamed System Exceptions


Those system exception for which oracle does not provide a name is known as unamed system exception.
These exception do not occur frequently. These Exceptions have a code and an associated message.
There are two ways to handle unnamed sysyem exceptions:
By using the WHEN OTHERS exception handler and by bind exception with an oracle error using
pragma exception init.
Pragma Exception_init:-- This directive binds a predefined Oracle error number to a programmer
defined exception name.
Syntax
DECLARE
exception_name EXCEPTION;
PRAGMA
EXCEPTION_INIT (exception_name, Err_code);
BEGIN
Execution section
EXCEPTION
WHEN exception_name THEN
handle the exception
END;
Example
Declare
My_except EXCEPTION;
PRAGMA Exception_init(my_except,-1400);
Begin

Insert into test values(1,india);


Insert into test values(2,usa);
Insert into test values(3,null);
Exception
When zero_Divide then
Dbms_output.put_line(exception occurred and terminated);
When my_except then
Dbms_output.put_line(cannot insert null values);
End;
/
Error Trapping Functions
1) SQLCODE :-- returns the latest code of the error that has occurred
2) SQLERRM:-- returns the relevant error msg of the sql code
By trapping error we can return it to a pragma exception init.
Declare
Err_code number;
Err_msg varchar2(100);
Num1 number;
Num2 number(2)
Begin
Num2:=20000;
Exception
While other then
Err_code:=SQLCODE;
Err_msg:=SQLERRM;
Dbms_output.put_line(err_Code ||
End;
/

---- || err_msg);

User-defined Exceptions
User defined exceptions are explicitly define exceptions based on business rules.
RAISE_APPLICATION_ERROR
Raise Application error is a procedure of package DBMS_STANDARD which allows to issue an user
defined error message from stored sub program or database trigger.
Eg:-Declare
V_empno emp.empno%type :=&empno;
V_sal number;
E_high_sal exception;
Begin
Select sal into v_sal from emp where empno=v_empno;

If v_sal>2000 then
Raise e_high_Sal;
End if;
Update emp set sal=sal*0.01 where empno=v_empno;
Exception
When e_high_sal then
Raise_application_error(-20001,Salary is to high);
End;
/
You could use the SQLERRM function to raise an error as follows:
Exception
When other then
Raise_application_error(-20001,an error was encountered ||SQLCODE||-ERROR-||SQLERRM);
END;
/
Or you could log the error to a table using the SQLERRM function as follows:
Exception
When others then
Err_code :=sqlcode;
Err_msg := SUBSTR(SQLERRM, 1, 200);
Insert into audit_table (error_number,error_message) values(err_code,err_msg);
End;
/
Triggers
A trigger is a pl/sql block structure which is fired when a DML statements like Insert, Delete, Update is
executed on a database table. A trigger is triggered automatically when an associated DML statement is
executed.
Syntax for Creating a Trigger
CREATE [OR REPLACE ] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF }
{INSERT [OR] | UPDATE [OR] | DELETE}
[OF col_name]
ON table_name
[REFERENCING OLD AS o NEW AS n]
[FOR EACH ROW]
WHEN (condition)
BEGIN
--- sql statements
END;

Types of PL/SQL Triggers


There are two types of triggers based on the which level it is triggered.
1) Row level trigger - An event is triggered for each row upated, inserted or deleted.
2) Statement level trigger - An event is triggered for each sql statement executed.

Advantages of Triggers
1) Audit data modifications.
2) Log events transparency
3) Ensure complex business rules derived columns values automatically
4) Implements complex security authorization
5) Maintains replicate tables

PL/SQL Trigger Execution Hierarchy


The following hierarchy is followed when a trigger is fired.
1) BEFORE statement trigger fires first.
2) Next BEFORE row level trigger fires, once for each row affected.
3) Then AFTER row level trigger fires once for each affected row. This events will alternates between
BEFORE and AFTER row level triggers.
4) Finally the AFTER statement level trigger fires.
Examples
CREATE TABLE product
(Message varchar2(50),
Current_Date number(32)
);
1) BEFORE UPDATE, Statement Level: This trigger will insert a record into the table
'product_check' before a sql update statement is executed, at the statement level.

CREATE or REPLACE TRIGGER Before_Update_Stat_product


BEFORE
UPDATE ON product
Begin

INSERT INTO product_check


Values('Before update, statement level',sysdate);
END;
/
BEFORE UPDATE, Row Level: This trigger will insert a record into the table 'product_check' before
each row is updated.

CREATE or REPLACE TRIGGER Before_Upddate_Row_product


BEFORE
UPDATE ON product
FOR EACH ROW
BEGIN
INSERT INTO product_check
Values('Before update row level',sysdate);
END;
/
3) AFTER UPDATE, Statement Level: This trigger will insert a record into the table 'product_check'
after a sql update statement is executed, at the statement level.
CREATE or REPLACE TRIGGER After_Update_Stat_product
AFTER
UPDATE ON product
BEGIN
INSERT INTO product_check
Values('After update, statement level', sysdate);
End;
/
4) AFTER UPDATE, Row Level: This trigger will insert a record into the table 'product_check' after
each row is updated.
CREATE or REPLACE TRIGGER After_Update_Row_product
AFTER
insert On product
FOR EACH ROW
BEGIN
INSERT INTO product_check
Values('After update, Row level',sysdate);
END;
/
DESC USER_TRIGGERS;
UNIX
cd
-- change directory
-------------------------------------------cd (also chdir in some shells) change directory
cd changes to user's home directory

cd / changes directory to the system's root


cd .. goes up one directory level
cd ../.. goes up two directory levels
cd ~username/directory changes directory to the named username's indicated directory
mkdir - make a directory
rmdir - remove directory
ls - list directory contents
The command to list your directories and files is ls. With options it can provide information about the
size, type of file, permissions, dates of file creation, change and access
Syntax
ls [options] [argument]
file access permissions: the first 3 characters refer to the permissions for the user, the next three for the
users in the Unix
group assigned to the file, and the last 3 to the permissions for other users on the system.
r read permission
w write permission
x execute permission
- no permission
Examples
To list the files in a directory:
% ls
demofiles frank linda
To list all files in a directory, including the hidden (dot) files try:
% ls -a
. .cshrc .history .plan .rhosts frank
.. .emacs .login .profile demofiles linda
To get a long listing:
% ls -al
total 24
drwxr-sr-x 5 workshop acs 512 Jun 7 11:12 .
drwxr-xr-x 6 root sys 512 May 29 09:59 ..
-rwxr-xr-x 1 workshop acs 532 May 20 15:31 .cshrc
-rw------- 1 workshop acs 525 May 20 21:29 .emacs
-rw------- 1 workshop acs 622 May 24 12:13 .history
-rwxr-xr-x 1 workshop acs 238 May 14 09:44 .login
-rw-r--r-- 1 workshop acs 273 May 22 23:53 .plan
-rwxr-xr-x 1 workshop acs 413 May 14 09:36 .profile
-rw------- 1 workshop acs 49 May 20 20:23 .rhosts
drwx------ 3 workshop acs 512 May 24 11:18 demofiles
drwx------ 2 workshop acs 512 May 21 10:48 frank
drwx------ 3 workshop acs 512 May 24 10:59 linda
cp - copy a file

cp old_filename new_filename
mv - move a file
Rename a file with the move command, mv.
mv old_filename new_filename
rm - remove a file
Remove a file with the rm, remove, command.
chmod - change file permissions
read=4, write=2, execute=1 or read=r, write=w, execute=x
+ add permissions
- remove permissions
= set permissions
chown - change ownership
chown new_owner file
chgrp - change group
chgrp new_group file
echo - echo a statement (print the value)
echo Hello Class or echo "Hello Class"
cat - concatenate a file
Display the contents of a file with the concatenate command, cat.
head - display the start of a file
head displays the head, or start, of the file
tail - display the end of a file
df - summarize disk block and file usage
du - report disk space in use
ps is used to report on processes currently running on the system.
kill - terminate a process
who - list current users
who reports who is logged in at the present time.
Syntax
who [am i]
whereis - report program locations
whereis reports the filenames of source, binary, and manual page files associated with command(s).
hostname/uname - name of machine
script - record your screen I/O
date - current date and time
Syntax
date [options] [+format]
Common Options
-u use Universal Time (or Greenwich Mean Time)
+format specify the output format
%a weekday abbreviation, Sun to Sat
%h month abbreviation, Jan to Dec
%j day of year, 001 to 366
%n <new-line>
%t <TAB>
%y last 2 digits of year, 00 to 99
%D MM/DD/YY date
%H hour, 00 to 23
%M minute, 00 to 59

%S second, 00 to 59
%T HH:MM:SS time
Examples
beauty condron>date
Mon Jun 10 09:01:05 EDT 1996
beauty condron>date -u
Mon Jun 10 13:01:33 GMT 1996
beauty condron>date +%a%t%D
Mon 06/10/96
beauty condron>date '+%y:%j'
96:162

lp/lpr - submit a print job


lp [options] filename
lpr [options] filename
example : -- lp ssh.ps
lpstat/lpq - check the status of a print job
cancel/lprm - cancel a print job
pr - prepare files for printing
Common Options
+page_number start printing with page page_number of the formatted input file
-column number of columns
-a modify -column option to fill columns in round-robin order
-d double spacing
-e[char][gap] tab spacing
-h header_string header for each page
-l lines lines per page
-t dont print the header and trailer on each page
-w width width of page
Examples
The file containing the list of P. G. Wodehouses Lord Emsworth books could be printed, at 14 lines
per page (including 5 header and 5 (empty) trailer lines) below, where the -e option specifies the
<tab> conversion style:
% pr -l 14 -e42 wodehouse
Apr 29 11:11 1996 wodehouse_emsworth_books Page 1
Something Fresh [1915] Uncle Dynamite [1948]
Leave it to Psmith [1923] Pigs Have Wings [1952]
Summer Lightning [1929] Cocktail Time [1958]
Heavy Weather [1933] Service with a Smile [1961]
Apr 29 11:11 1996 wodehouse_emsworth_books Page 2
Blandings Castle and Elsewhere [1935] Galahad at Blandings [1965]
Uncle Fred in the Springtime [1939] A Pelican at Blandings [1969]

Full Moon [1947] Sunset at Blandings [1977]

DUAL
This is a single row and single column dummy table provided by oracle. This is used to perform
mathematical calculations without using a table.

Group By
The Oracle GROUP BY Clause is used in a select statement to collect data across multiple records and
group the results by one or more columns.
Having By
The Oracle HAVING Clause is used in combination with the group by clause to restrict the groups of
returned rows to only those whose the condition is TRUE.
Where Clause
The Oracle WHERE clause is used to filter the results from a select,insert,update and delete statement.
From Clause
The Oracle/PLSQL FROM clause is used to list the tables and any join information required for the
Oracle query.
Distinct Clause
The Oracle DISTINCT clause is used to remove duplicates from the result set. The DISTINCT clause can
only be used with select statements.
Order By
The Oracle ORDER BY clause is used to sort the records in your result set. The ORDER BY clause can
only be used in select statements.

Mutating Error

Mutating error normally occurs when we are performing some DML operations and we are
trying to select the affected record from the same trigger. So basically we are trying to select
records in the trigger from the table that owns the trigger. This creates inconsistency and Oracle
throws a mutating error.

How can one see if somebody modified any code?


Code for stored procedures, functions and packages are stored in the Oracle Data
Dictionary. One can detect code changes by looking at the LAST_DDL_TIME column
in the USER_OBJECTS dictionary view. Example:
SELECTOBJECT_NAME,
TO_CHAR(CREATED,'DDMonRRHH24:MI)
CREATE_TIME,
TO_CHAR(LAST_DDL_TIME,'DDMonRRHH24:MI')MOD_TIME,
STATUS
FROMUSER_OBJECTS
WHERELAST_DDL_TIME>'&CHECK_FROM_DATE';
Back to top of file

How can one search PL/SQL code for a string/ key value?
The following query is handy if you want to know where a certain table, field or
expression is referenced in your PL/SQL source code.
SELECTTYPE,NAME,LINE
FROMUSER_SOURCE
WHEREUPPER(TEXT)LIKE'%&KEYWORD%';

How can one keep a history of PL/SQL code changes?


One can build a history of PL/SQL code changes by setting up an AFTER CREATE schema (or
database) level trigger (available from Oracle 8.1.7). This way one can easily revert to previous
code should someone make any catastrophic changes. Look at this example:

CREATETABLESOURCE_HISTCreatehistory
table
ASSELECTSYSDATECHANGE_DATE,USER_SOURCE.*
FROMUSER_SOURCEWHERE1=2;

CREATEORREPLACETRIGGERchange_histStorecodein
histtable
AFTERCREATEONSCOTT.SCHEMAChangeSCOTT
toyourschemaname
DECLARE
BEGIN
ifDICTIONARY_OBJ_TYPEin('PROCEDURE','FUNCTION',
'PACKAGE','PACKAGEBODY','TYPE')then
StoreoldcodeinSOURCE_HISTtable
INSERTINTOSOURCE_HIST
SELECTsysdate,user_source.*FROMUSER_SOURCE
WHERETYPE=DICTIONARY_OBJ_TYPE
ANDNAME=DICTIONARY_OBJ_NAME;
endif;
EXCEPTION

WHENOTHERSTHEN
raise_application_error(20000,SQLERRM);
END;
/
showerrors

How can I protect my PL/SQL source code?


PL/SQL V2.2, available with Oracle7.2, implements a binary wrapper for PL/SQL programs to
protect the source code.
This is done via a standalone utility that transforms the PL/SQL source code into portable
binary object code (somewhat larger than the original). This way you can distribute software
without having to worry about exposing your proprietary algorithms and methods. SQL*Plus
and SQL*DBA will still understand and know how to execute such scripts. Just be careful, there
is no decode command available.
The syntax is:
wrapiname=myscript.sqloname=xxxx.plb

Can one read/write files from PL/SQL?


Included in Oracle 7.3 is an UTL_FILE package that can read and write operating system files.
The directory you intend writing to has to be in your INIT.ORA file (see UTL_FILE_DIR=
parameter). Before Oracle 7.3 the only means of writing a file was to use DBMS_OUTPUT with
the SQL*Plus SPOOL command.
Copy this example to get started:
DECLARE
fileHandlerUTL_FILE.FILE_TYPE;

BEGIN
fileHandler:=UTL_FILE.FOPEN('/tmp','myfile','w');
UTL_FILE.PUTF(fileHandler,'Lookma,I''mwritingto
afile!!!\n');
UTL_FILE.FCLOSE(fileHandler);
EXCEPTION
WHENutl_file.invalid_pathTHEN
raise_application_error(20000,'ERROR:Invalid
pathforfileorpathnotinINIT.ORA.');
END;
/

Can one call DDL statements from PL/SQL?


One can call DDL statements like CREATE, DROP, TRUNCATE, etc. from PL/SQL by using
the EXECUTE IMMEDATE statement. Users running Oracle versions below 8i can look at the
DBMS_SQL package (see FAQ about Dynamic SQL).
begin
EXECUTEIMMEDIATE'CREATETABLEX(ADATE)';
end;

NOTE: The DDL statement in quotes should not be terminated with a semicolon.

Can one use dynamic SQL statements from PL/SQL?

Starting from Oracle8i one can use the EXECUTE IMMEDIATE statement to execute
dynamic SQL and PL/SQL statements (statements created at run-time). Look at these examples.
Note that statements are NOT terminated by semicolons:
EXECUTEIMMEDIATE'CREATETABLEx(aNUMBER)';

Usingbindvariables...
sql_stmt:='INSERTINTOdeptVALUES(:1,:2,:3)';
EXECUTEIMMEDIATEsql_stmtUSINGdept_id,dept_name,
location;

Returningacursor...
sql_stmt:='SELECT*FROMempWHEREempno=:id';
EXECUTEIMMEDIATEsql_stmtINTOemp_recUSINGemp_id;

One can also use the older DBMS_SQL package (V2.1 and above) to execute dynamic
statements. Look at these examples:
CREATEORREPLACEPROCEDUREDYNSQLAS
curinteger;
rcinteger;
BEGIN
cur:=DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(cur,'CREATETABLEX(YDATE)',
DBMS_SQL.NATIVE);

rc:=DBMS_SQL.EXECUTE(cur);
DBMS_SQL.CLOSE_CURSOR(cur);
END;
/

More complex DBMS_SQL example using bind variables:


CREATEORREPLACEPROCEDUREDEPARTMENTS(NOIN
DEPT.DEPTNO%TYPE)AS
v_cursorinteger;
v_dnamechar(20);
v_rowsinteger;
BEGIN
v_cursor:=DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(v_cursor,'selectdnamefromdept
wheredeptno>

',DBMS_SQL.V7);

DBMS_SQL.BIND_VARIABLE(v_cursor,':x',no);
DBMS_SQL.DEFINE_COLUMN_CHAR(v_cursor,1,v_dname,
20);
v_rows:=DBMS_SQL.EXECUTE(v_cursor);
loop
ifDBMS_SQL.FETCH_ROWS(v_cursor)=0then

exit;
endif;
DBMS_SQL.COLUMN_VALUE_CHAR(v_cursor,1,v_dname);
DBMS_OUTPUT.PUT_LINE('Deptartmentname:'||
v_dname);
endloop;
DBMS_SQL.CLOSE_CURSOR(v_cursor);
EXCEPTION
whenothersthen
DBMS_SQL.CLOSE_CURSOR(v_cursor);
raise_application_error(20000,'Unknown
ExceptionRaised:'||sqlcode||''||sqlerrm);
END;
/

How does one get the value of a sequence into a PL/SQL


variable?
As you might know, one cannot use sequences directly from PL/SQL. Oracle prohibits this:
i:=sq_sequence.NEXTVAL;

However, one can use embedded SQL statements to obtain sequence values:
selectsq_sequence.NEXTVALinto:ifromdual;

How does one loop through tables in PL/SQL?


Look at the following nested loop code example.
DECLARE
CURSORdept_curIS
SELECTdeptno
FROMdept
ORDERBYdeptno;
Employeecursorallemployeesforadeptnumber
CURSORemp_cur(v_dept_noDEPT.DEPTNO%TYPE)IS
SELECTename
FROMemp
WHEREdeptno=v_dept_no;
BEGIN
FORdept_recINdept_curLOOP
dbms_output.put_line('EmployeesinDepartment'||
TO_CHAR(dept_rec.deptno));
FORemp_recinemp_cur(dept_rec.deptno)LOOP
dbms_output.put_line('...Employeeis'||
emp_rec.ename);
ENDLOOP;

ENDLOOP;
END;
/

Is it better to put code in triggers or procedures? What is


the difference?
In earlier releases of Oracle it was better to put as much code as possible in procedures rather
than triggers. At that stage procedures executed faster than triggers as triggers had to be recompiled every time before executed (unless cached). In more recent releases both triggers and
procedures are compiled when created (stored p-code) and one can add as much code as one
likes in either procedures or triggers.

Is there a limit on the size of a PL/SQL block?


Yes, the max size is not an explicit byte limit, but related to the parse tree that is created when
you compile the code. You can run the following select statement to query the size of an existing
package or procedure:
SQL>select*fromdba_object_sizewherename=
'procedure_

Das könnte Ihnen auch gefallen