Using Oracle PL/SQL: More Powerful Than SQL
Using Oracle PL/SQL: More Powerful Than SQL
Using Oracle PL/SQL: More Powerful Than 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
block structure
DECLARE
/* Declarative section: variables, types, and local subprograms. */
BEGIN
/* Executable section: procedural and SQL statements go here. */
EXCEPTION
/* Exception handling section: error handling statements go here. */
END;
Execute a PL/SQL
• To execute a PL/SQL program
must follow the program text itself by
– A line with a single dot ("."), and then
– A line with run;
• with Oracle SQL programs, we can invoke
a PL/SQL program by typing it in sqlplus
Variables and Types
• Type
– 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
• E.G.
DECLARE
price NUMBER;
myBeer VARCHAR(20);
Variables and Types
• %TYPE operator
DECLARE
myBeer Beers.name%TYPE;
• %ROWTYPE operator
DECLARE
beerTuple Beers%ROWTYPE;
Variables and Types
• ":=" operator
• e.g
DECLARE
a NUMBER := 3;
BEGIN
a := a + 1;
END;
.
run;
Simple Programs in PL/SQL
• Plain SQL
CREATE TABLE T1(
e INTEGER,
f INTEGER
);
T1
e f
DELETE FROM T1;
1 3
INSERT INTO T1 VALUES(1, 3);
INSERT INTO T1 VALUES(2, 4); 2 4
Simple Programs in PL/SQL
T1
• PL/SQL program e f
DECLARE 1 3
a NUMBER; 2 4
b NUMBER; 4 2
BEGIN
SELECT e,f INTO :a,:b FROM T1 WHERE e>1;
INSERT INTO T1 VALUES(:b,:a);
END;
.
run;
Control Flow in PL/SQL
• IF statement
IF <condition_1> THEN ...
ELSIF <condition_2> THEN ...
... ...
ELSIF <condition_n> THEN ...
ELSE ...
END IF;
Control Flow in PL/SQL
• E.g.
DECLARE
a NUMBER;
b NUMBER;
BEGIN
SELECT e,f INTO :a, :b FROM T1 WHERE e>1;
IF b=1 THEN
INSERT INTO T1 VALUES(:b,:a);
ELSE
INSERT INTO T1 VALUES(:b+10,:a+10);
END IF;
END;
.
run;
Control Flow in PL/SQL
• Loops :
LOOP
<loop_body> /* A list of statements. */
END LOOP;
• EXIT
EXIT WHEN <condition>;
• E.G.
DECLARE
i NUMBER := 1;
BEGIN
LOOP
INSERT INTO T1 VALUES(:i,:i);
i := i+1;
EXIT WHEN i>100;
END LOOP;
END;
.
run;
Control Flow in PL/SQL
• WHILE loop
WHILE <condition> LOOP
<loop_body>
END LOOP;
• FOR loop
FOR <var> IN <start>..<finish> LOOP
<loop_body>
END LOOP;
DECLARE
x NUMBER := 100;
BEGIN
FOR i IN 1..10 LOOP
IF MOD(i,2) = 0 THEN -- i is even
INSERT INTO temp VALUES (i,: x, 'i is even');
ELSE
INSERT INTO temp VALUES (i, :x, 'i is odd');
END IF;
x := x + 100;
END LOOP;
COMMIT;
END;
.
run
DECLARE
acct_balance NUMBER(11,2);
acct CONSTANT NUMBER(4) := 3;
debit_amt CONSTANT NUMBER(5,2) := 500.00;
BEGIN
SELECT bal INTO :acct_balance FROM accounts
WHERE account_id = :acct
FOR UPDATE OF bal;
IF acct_balance >= debit_amt THEN
UPDATE accounts SET bal = bal - :debit_amt
WHERE account_id = :acct;
ELSE
INSERT INTO temp VALUES
(:acct, :acct_balance, 'Insufficient funds');
-- insert account, current balance, and message
END IF;
COMMIT;
END;
DECLARE
salary emp.sal%TYPE;
mgr_num emp.mgr%TYPE;
last_name emp.ename%TYPE;
starting_empno CONSTANT NUMBER(4) := 7902;
BEGIN
SELECT sal, mgr INTO :salary, :mgr_num FROM emp
WHERE empno = :starting_empno;
WHILE salary < 4000 LOOP
SELECT sal, mgr, ename INTO :salary, :mgr_num, :last_name
FROM emp
WHERE empno = :mgr_num;
END LOOP;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO :my_ename, :my_empno, :my_sal;
EXIT WHEN (c1%ROWCOUNT > 5) OR (c1%NOTFOUND);
INSERT INTO temp VALUES (my_sal, my_empno, my_ename);
COMMIT;
END LOOP;
CLOSE c1;
END;
DECLARE
num1 data_table.n1%TYPE; -- Declare variables
num2 data_table.n2%TYPE; -- to be of same type as
num3 data_table.n3%TYPE; -- database columns
result temp.num_col1%TYPE;
CURSOR c1 IS
SELECT n1, n2, n3 FROM data_table
WHERE exper_num = 1;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO :num1, :num2, :num3;
EXIT WHEN c1%NOTFOUND;
-- the c1%NOTFOUND condition evaluates
-- to TRUE when FETCH finds no more rows
/* calculate and store the results */
result := num2/(num1 + num3);
INSERT INTO temp VALUES (result, NULL, NULL);
END LOOP;
CLOSE c1;
COMMIT;
END;
I/O Control
• DBMS_OUTPUT.NEW_LINE();
• DBMS_OUTPUT.PUT_LINE();
• DBMS_OUTPUT.PUT();
I/O Example
BEGIN
/* Get Current User Name */
SELECT username INTO :l_current_user FROM USER_USERS;
DBMS_OUTPUT.NEW_LINE();
DBMS_OUTPUT.PUT('Connect As '||l_current_user);
DBMS_OUTPUT.PUT(' And Add Details For '||RTRIM(Empname));
DBMS_OUTPUT.PUT_LINE(' having Id '||RTRIM(empid));