Upload
allen-berry
View
251
Download
2
Embed Size (px)
Citation preview
PL/SQL
ISYS 464
PL/SQL Block-Structured
• Variable declaration section
• Executable section
• Exception-handling section
Variable Declaration
• Variable name: begin with a letter and up to 30 characters.
• Data types:– Character: CHAR(n), VARCHAR2(n)– Number: INTEGER, INT, SMALLINT– DECIMAL(i,j), NUMBER(i,j)– Boolean– Date
Examples
• DECLAREEid CHAR(3);
Ename VARCHAR2(25);
HireDate DATE DEFAULT SYSDATE;
Salary NUMBER(7,2)
TaxRate NUMBER(4,2) :=5.25
%TYPE
• Use a column’s data type as the data type for the variable:– CustomerName Customer.Cname%TYPE;
Executable Section
• BEGIN– Statements
• END;
• /– “/ “ signals the end of program.
Assignment Statement
• Tax := Salary * TaxRate
• Arithemetic operators:– +, -, *, /, **
• Concatenation:– ||
• FullName := (FirstName || ‘ ‘ || LastName);
Substitution Variables
• &variableName– Ex. &Salary
• On screen you will see:– Enter value for Salary:
• Select * from Customer• Where CID=‘&CID’;
• Ex1: Get input from screen:– Salary := &Salary;
SELECT … INTO
• SELECT columns separated by commas• INTO variables separated by commas• FROM tablename• WHERE condition;• Ex1:
– SELECT cid, cname INTO custID, customername– FROM customer– WHERE cid = ‘c01’;
• Ex2: Using substituion variable– SELECT cid, cname INTO custID, customername– FROM customer– WHERE cid = ‘&cid’;
Decisions
• IF condition THEN– Statements /* each statement ends with ; */
• END IF;
• IF … THEN … ELSE …END IF;
• IF … THEN ELSIF ……ELSE … END IF;
Loop
• WHILE condition LOOP– Statements
• END LOOP;
• FOR i IN 1 .. 10 LOOP– Statements
• END LOOP
Printing
• SET SERVEROUTPUT ON;• DBMS_OUTPUT.PUT_LINE(string to print);
– DBMS_OUTPUT is a build in package, PUT_LINE is a procedure in that package.
• Ex.– Tax:=Salary * TaxRate;
– DBMS_OUTPUT.PUT_LINE(‘Your tax is: ‘ || Tax);
Caltax.sqldeclare taxRate number(3,2); eid emp.empid%type; empSalary emp.salary%type; tax number(7,2);begin taxRate :=&taxRate; select salary into empSalary from emp where empid = '&eid';tax := empSalary * taxRate;dbms_output.put_line('Tax is : ' || tax);end;/
Exceptions
• Exceptions are errors.
• Predefined exceptions:– No_Data_Found: Select statement returns no row.
– Too_Many_Rows: Single-Row Select statement returns more than one row.
– Value_Error: Data conversion errors.
Handling Exceptions
• Exception– WHEN exceptionname THEN
– Statements
– WHEN OTHERS THEN– Statements
• Ex: PLSQLException.SQL
DeclareCustName Customer.Cname%Type;
begin select Cname into Custname from customer where cid='&CID';
dbms_output.put_line('Customer name is : ' || Custname);exception when no_data_found then dbms_output.put_line('Customer record not exist');end;/
Creating Stored Procedure
• A procedure is a named program block:CREATE [OR REPLACE] PROCEDURE procedurename
IS[Variable declarations]BEGIN
Statements
END;/
Note: To run a procedure: EXECUTE procedurename
create or replace procedure addorder (
ordid orders.oid%TYPE,
custID orders.cid%TYPE,
salesID orders.sid%TYPE,
orddate orders.odate%TYPE)
is
tempid customers.cid%TYPE;
begin
select cid into tempid from customers where cid=custid;
insert into orders values(ordid,custid,salesid,orddate);
exception
when no_data_found then
dbms_output.put_line('Customer record not exist');
end;
/
Note: To run a stored procedure: execute addorder('O8','C1','S3','05-NOV-07');
Functions
CREATE [OR REPLACE] FUNCTION functionname
IS[Variable declarations]BEGIN
StatementsRETURN expression;
END;/
create or replace function emptax(sal emp.salary%type)
return number is
tax number(6,2);
begin
if sal < 2000.0 then
tax:=sal*0.1;
elsif sal <4000.0 then
tax:=sal*0.2;
else
tax:=sal*0.3;
end if;
return tax;
end;
/
Using the User-defined Function with SQL
• SELECT empid, ename, emptax(salary)
• FROM emp;
Cursors
• A cursor is a pointer to a set of records returned by a SQL statement. It enables you to take a set of records and deal with it on a row-by-row basis.
Defining and Using Cursors
• Declare cursor:– CURSOR cursorname IS SQL statement
• Ex: cursor maleemp is
select empid,ename,salary from emp where sex='M';
Open cursor:OPEN maleemp;
Fetch data into variables:FETCH maleemp into eid,empname,sal;
Use %FOUND to test if record exist
CLOSE cursor
declare
eid emp.empid%type;
empname emp.ename%type;
sal emp.salary%type;
cursor maleemp is
select empid,ename,salary from emp where sex='M';
begin
open maleemp;
fetch maleemp into eid,empname,sal;
while maleemp%found loop
dbms_output.put_line(eid || empname || sal);
fetch maleemp into eid,empname,sal;
end loop;
close maleemp;
end;
/ Note: To run a cursor: SQL> Start C:\Empcursor1.sql
Cursor with Argumentsdeclare
eid emp.empid%type;
empname emp.ename%type;
sal emp.salary%type;
cursor gender(s emp.sex%type) is
select empid,ename,salary from emp where sex=s;
begin
open gender('&gender');
fetch gender into eid,empname,sal;
while gender%found loop
dbms_output.put_line(eid || empname || sal);
fetch gender into eid,empname,sal;
end loop;
close gender;
end;
/ Note: ecursor2.sql
declare eid emp.empid%type; empname emp.ename%type; sal emp.salary%type; gender emp.sex%type; bonus number(6,2);cursor e isselect empid,ename,salary,sex from emp;beginopen e;fetch e into eid,empname,sal,gender;while e%found loop if gender='M' then if sal < 3000 then bonus := sal*.2; else bonus := sal*.1; end if; else if sal < 3000 then bonus:= sal*.25; else bonus:=sal*.15; end if; end if; dbms_output.put_line(eid || empname || sal||gender||bonus); fetch e into eid,empname,sal,gender;end loop;close e;end;/ Note: EmpBonusCursor.SQL
Triggers
• A trigger is a program stored in the database and is called automatically when a triggering event occurs.
• Update events: – Insert, Delete, Update
• BEFORE Insert|Delete|Update ON tablename
• AFTER Insert|Delete|Update ON tablename
• Accessing new value and old value:– :NEW.fieldname
– :OLD.fieldname
• FOR EACH ROW
Demo :New and :Oldcreate or replace trigger changesal
after update on emp
for each row
begin
dbms_output.put_line(:old.ename || ' old salary is:' || :old.salary);
dbms_output.put_line('new salary is: ' || :new.salary);
end;
/
Note: EmpSaltrigger.sql
create or replace trigger adddetail
before insert on orderdetail
for each row
declare
stocks product.onhand%type;
begin
select onhand into stocks
from hproduct where pid=:new.pid;
if stocks < :new.qty then
update product
set onhand=0
where pid = :new.pid;
dbms_output.put_line('not enough stock');
else
update product
set onhand=onhand - :new.qty
where pid=:new.pid;
end if;
end;
/ Note: AddDetailTrigger.sql