OCL4 Oracle 10g: SQL & PL/SQL Session #6: Matthew P. Johnson Cisdd, Cuny June, 2005
OCL4 Oracle 10g: SQL & PL/SQL Session #6: Matthew P. Johnson Cisdd, Cuny June, 2005
This time:
SPs in PL/SQL
Next time:
More PL/SQL
Triggers
But Pascal-like:
BEGIN END, not { }
AND OR, not && ||
vars defined at top of procedure
how return works
Programming languages:
C/C++, Java, etc.
Scripting languages:
PL/SQL, Perl, PHP, Unix shell, DOS batch files, Python, Excel
BEGIN
BEGIN
----print
printout
outmessage
message
DBMS_OUTPUT.PUT_LINE('Hello
DBMS_OUTPUT.PUT_LINE('HelloWorld,
World,from
fromPL/SQL');
PL/SQL');
END;
END;
//
SQL>
SQL> exec
execdbms_output.put_line('hi
dbms_output.put_line('hi');
');
dbms_output.put_line('there'
dbms_output.put_line('there'
BEGIN
BEGIN
INSERT
INSERTINTO
INTOLikes
LikesVALUES(‘Izzy',
VALUES(‘Izzy',‘milk');
‘milk');
DELETE
DELETEFROM
FROMLikes
Likes
WHERE
WHEREdrinker
drinker==‘Izzy'
‘Izzy'AND
AND
beverage
beverage==‘Beaujolais
‘BeaujolaisNouveau
Nouveau';';
COMMIT;
COMMIT;
END;
END;//
Another example:
http://pages.stern.nyu.edu/~mjohnson/oracle/plsql/age.sql
Matthew P. Johnson, OCL4, CISDD CUNY, Sept 2005 19
Procedures
Stored database objects that use a PL/SQL
statement(s) in their body
Create/drop similar to other SQL objects:
CREATE
CREATEPROCEDURE
PROCEDURE<my-proc>
<my-proc>
(<params>)
(<params>) AS
AS
<procedure
<procedurebody
bodyas
asabove>;
above>;
CREATE
CREATEOR ORREPLACE
REPLACEPROCEDURE
PROCEDURE
<my-proc>(<params>)
<my-proc>(<params>)AS
AS
<procedure
<procedurebody
bodyas
asabove>;
above>;
DROP
DROPPROCEDURE
PROCEDURE<my-proc>;
<my-proc>;
Matthew P. Johnson, OCL4, CISDD CUNY, Sept 2005 20
Example procedure
Define the procedure:
CREATE
CREATEPROCEDURE
PROCEDUREtestProcedure
testProcedureAS
AS
BEGIN
BEGIN
INSERT
INSERTINTO
INTOStudent
StudentVALUES
VALUES(5,
(5,'Joe');
'Joe');
END;
END;
CREATE
CREATEororreplace
replacePROCEDURE
PROCEDUREhike_prices(old_price
hike_prices(old_pricenumber,
number,
new_price
new_priceout
outnumber,
number,
percent_hike
percent_hikenumber
number:=:=5)
5)is
is
Begin
Begin
new_price
new_price:=:=old_price
old_price++old_price
old_price**percent_hike/100;
percent_hike/100;
End;
End;
//
Convert to a function
DROP
DROP FUNCTION
FUNCTION <functionName>;
<functionName>;
Big strength: can be called from SQL itself
Matthew P. Johnson, OCL4, CISDD CUNY, Sept 2005 27
Function example
CREATE
CREATEOR ORREPLACE
REPLACEFUNCTION
FUNCTIONmaxval(a
maxval(a
IN
INint,
int,bbIN
INint)
int) RETURN
RETURNint
int AS
AS
BEGIN
BEGIN
IF
IFaa>>bbTHEN
THENRETURN
RETURNa;a;
ELSE
ELSERETURN
RETURNb; b;
END
ENDIF; IF;
END
ENDmaxval;
maxval;
INSERT
INSERTINTO
INTORRVALUES('abc',
VALUES('abc', maxval(5,10));
maxval(5,10));
http://pages.stern.nyu.edu/~mjohnson/oracle/plsql/maxval.sql
Introduction to PL/SQL:
http://www.geocities.com/cliktoprogram/plsql/introduction.html
IF
IF <condition>
<condition> THEN
THEN IF
IF <expression>
<expression> THEN
THEN
ELSE
ELSE ELSEIF
ELSEIF <expression>
<expression>
END
END IF;
IF; ELSE
ELSE
END
END IF;
IF;
declare
Run example: declare
xxnumber
number:= :=1;
1;
begin
begin
case
casexx
when
when22then
then
dbms_output.put_line('2');
dbms_output.put_line('2');
……
SELECT
SELECT
CASE
CASE
WHEN
WHENcomm
commisisnull
nullTHEN
THEN00
ELSE
ELSEcomm
comm
END
END
FROM
FROM emp;
emp;
WHILE
WHILE condition
condition
LOOP
LOOP
while loop:
executable_statements;
executable_statements;
END
END LOOP;
LOOP;
progra len
lenPLS_INTEGER
PLS_INTEGER:=
inside_a_word
inside_a_wordBOOLEAN;
:=NVL(LENGTH(str),0);
BOOLEAN;
NVL(LENGTH(str),0);
BEGIN
m BEGIN
FOR
FORi iIN IN1..len
1..len++11 LOOPLOOP
IF
IFASCII(SUBSTR(str,
ASCII(SUBSTR(str,i,i,1)) 1))<<33 33OR
ORi i>>len
len
THEN
THEN
IFIFinside_a_word
inside_a_word
THEN
THEN
words
words:= :=words
words++1; 1;
inside_a_word
inside_a_word:= :=FALSE;
FALSE;
END
ENDIF; IF;
ELSE
ELSE
inside_a_word
inside_a_word:= :=TRUE;
TRUE;
END
ENDIF; IF;
END
ENDLOOP;LOOP;
RETURN
RETURN words;
words;
Matthew P. Johnson, OCL4, CISDD CUNY, Sept 2005 52
END;
END;
Explicit cursors v. for loop cursors
DECLARE
DECLARE
CURSOR
CURSORoccupancy_cur
occupancy_curISIS
SELECT
SELECTpet_id,
pet_id,room_number
room_number
FROM
FROMoccupancy
occupancyWHERE
WHEREoccupied_dt
occupied_dt==TRUNC
TRUNC(SYSDATE);
(SYSDATE);
occupancy_rec
occupancy_recoccupancy_cur%ROWTYPE;
occupancy_cur%ROWTYPE;
BEGIN
BEGIN
OPEN
OPENoccupancy_cur;
occupancy_cur;
LOOP
LOOP
FETCH
FETCHoccupancy_cur
occupancy_curINTO
INTOoccupancy_rec;
occupancy_rec;
EXIT
EXITWHEN
WHENoccupancy_cur%NOTFOUND;
occupancy_cur%NOTFOUND;
update_bill
update_bill
(occupancy_rec.pet_id,
(occupancy_rec.pet_id,occupancy_rec.room_number);
occupancy_rec.room_number);
END
ENDLOOP;
LOOP;
CLOSE
CLOSEoccupancy_cur;
occupancy_cur;
END;
END; Matthew P. Johnson, OCL4, CISDD CUNY, Sept 2005 53
Explicit cursors v. for loop cursors
DECLARE
DECLARE
CURSOR
CURSORoccupancy_cur
occupancy_curISIS
SELECT
SELECTpet_id,
pet_id,room_number
room_number
FROM
FROMoccupancy
occupancyWHERE
WHEREoccupied_dt
occupied_dt==TRUNC
TRUNC(SYSDATE);
(SYSDATE);
BEGIN
BEGIN
FOR
FORoccupancy_rec
occupancy_recIN INoccupancy_cur
occupancy_cur
LOOP
LOOP
update_bill
update_bill(occupancy_rec.pet_id,
(occupancy_rec.pet_id,occupancy_rec.room_number);
occupancy_rec.room_number);
END
ENDLOOP;
LOOP;
END;
END;
select
selectprodname
prodnameinto
intopn
pn
from
fromproducts
products
where
wheremfg
mfg==manuf;
manuf;
return
returnpn;
pn;
end;
end;
//
select
selectprodname
prodnameinto
intopn
pn
from
fromproducts
products
where
wheremfg
mfg==manuf;
manuf;
return
returnpn;
pn;
Exception
Exception
When
WhenTOO_MANY_ROWS
TOO_MANY_ROWSthen then
dbms_output.put_line('got
dbms_output.put_line('gottoo
toomany');
many');
end;
end;
//
Matthew P. Johnson, OCL4, CISDD CUNY, Sept 2005 56
Programs and rights
By default, only the creator of a program may run it
(apart from the admin)
If others should run, must GRANT them permission:
SQL>
SQL> GRANT
GRANT EXECUTE
EXECUTE ON ON wordcount
wordcount TO
TO george;
george;
Permissions can be revoked:
SQL>
SQL> REVOKE
REVOKE EXECUTE
EXECUTE FROM FROM wordcount
wordcount TO
TO george;
george;
Can also grant to particular roles or everyone:
SQL>
SQL> GRANT
GRANT EXECUTE
EXECUTE ON ON wordcount
wordcount TOTO dba_role;
dba_role;
SQL>
SQL> GRANT
GRANT EXECUTE
EXECUTE ON ON wordcount
wordcount TOTO public;
public;
Wider/narrower grant ops are independent…
CREATE
CREATEOR ORREPLACE
REPLACEFUNCTION
FUNCTIONrowCountrowCount((
tabname
tabnameIN INVARCHAR2)
VARCHAR2)return
returninteger
integer asas
retval
retvalinteger;
integer;
begin
begin
execute
executeimmediate
immediate'select
'select count(*)
count(*) from
from ' '||||tabname
tabnameinto
into
retval;
retval;
return
returnretval;
retval;
end;
end;
//
Here’s an e.g.:
CREATE
CREATEOR ORREPLACE
REPLACEprocedure
procedure
dropproc(procname
dropproc(procnameininvarchar2)
varchar2) as
as
begin
begin
execute
executeimmediate
immediate'drop
'dropprocedure
procedure' '||||procname;
procname;
end;
end;
//
Directory of examples:
http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/