PLSQL For Beginners 4
PLSQL For Beginners 4
PLSQL For Beginners 4
Training Guide
PL/SQL
for
Beginners
Workbook
Training Guide www.appltop.com
[email protected]
PL/SQL for Beginners - Workbook
Workbook
This workbook should be worked through with the
associated Training Guide, PL/SQL for Beginners.
Good Luck!
Exercise Hints
When you write any PL/SQL from within SQL*Plus,
remember to use the following SQL*Plus
commands:-
ed Invoke editor
save Save contents of SQL buffer to a file
get Load file into SQL buffer
start Load and execute file
@ Execute file
/ Execute contents of SQL buffer
Section One
Introduction to PL/SQL
Quiz
2. What is PL/SQL?
Section Two
PL/SQL Fundamentals
Quiz
7. What is a Constant?
15. How can you view compile (syntax) errors in a PL/SQL block?
DECLARE
l_done BOOLEAN := FALSE;
BEGIN
WHILE NOT l_done
l_total := l_total + 10;
END LOOP;
END;
<<block1>>
DECLARE
l_x NUMBER := 10;
l_y NUMBER := 20;
BEGIN
DBMS_OUTPUT.put_line(l_x);
<<block2>>
DECLARE
l_x NUMBER := 50;
l_y NUMBER := 60;
l_z NUMBER;
BEGIN
DBMS_OUTPUT.put_line(l_x);
DBMS_OUTPUT.put_line(block1.l_y);
DBMS_OUTPUT.put_line(block2.l_z);
END;
END;
Exercises
1. Create a program that accepts two numbers from
substitution variables, display one of the following
messages:-
Section Three
SQL within PL/SQL
Quiz
1. What kind of SQL statements cannot be directly run from
within a PL/SQL program?
7. What is SQL%NOTFOUND?
Exercises
1. Write a program that gives all employees in department 10 a
15% pay increase. Display a message displaying how many
employees were awarded the increase.
Section Four
Exceptions
Quiz
1. What is an Exception?
Exercises
1. Write the code for question 5 on the quiz
Section Five
Explicit Cursors
Quiz
1. What is an Explicit Cursor?
BEGIN
OPEN employee_cur(10);
LOOP
FETCH r_employee INTO employee_cur;
EXIT employee_cur.NOTFOUND;
END LOOP;
CLOSE;
END;
Exercises
1. Create a program that mimics selecting all columns and rows
from the dept table. There is no need to format the output,
just select all columns and all rows. Use a cursor FOR loop.
Section Six
Stored Procedures &
Functions
Quiz
1. What are differences between stored subprograms and
anonymous blocks?
Exercises
1. Create a procedure that deletes rows from the old_emp
table. It should accept 1 parameter, job; only delete the
employee's with that job. Display how many employees were
deleted. Write a program to invoke the procedure.
Section Seven
Packages
Quiz
1. What is a package?
RETURN l_ename;
END;
Exercises
Read the following specification:-
Our developers require some software that will act as an API (Application
Programming Interface) for the items table. We need to protect our
data and want to ensure no developers writes any code that will directly
access this table.
All API functions and procedures should work with the item_id.
Section Eight
Triggers
Quiz
1. What is a trigger?
COMMIT;
END;
Exercises
To compliment the package developed in the last section, the user
has come up with the following addition to the specification.
When items are removed using the new API you provided, we need to
ensure the item is archived in a table called items_archive.
We also want any changes in item cost to be audited, record the details
of each change in the audit_cost table.
NOTE
The above changes could just as easily be implemented within the
package created in the last section. Remember, you provided an
API to the items table so ALL changes to the data are controlled
through the package, in theory, ALL developers should use the
package. Implementing the changes using triggers is a more
secure method because even if any changes to the data are made
not using the package, the triggers will still do their job.
Answers
Section 1 Quiz
Section 2 Quiz
4. 20
11. 25.
18. TRUE
20. TRUE.
22. GOTO can make your code unstructured and hard to read/
debug.
Section 2 Exercises
1. DECLARE
l_number1 NUMBER := &1;
l_number2 NUMBER := &2;
BEGIN
END;
2. DECLARE
l_times NUMBER := &1;
BEGIN
END;
BEGIN
END;
Section 3 Quiz
1. DDL cannot be used in PL/SQL directly, only DML.
Section 3 Exercises
1. BEGIN
UPDATE emp
SET sal = sal * 1.15
WHERE deptno = 10;
DBMS_OUTPUT.put_line(TO_CHAR(SQL%ROWCOUNT)||
' employee(s) updated');
END;
2. DECLARE
l_old_job emp.job%TYPE := '&1';
l_new_job emp.job%TYPE := '&2';
BEGIN
UPDATE emp
SET job = l_new_job
WHERE job = l_old_job;
IF SQL%FOUND THEN
DBMS_OUTPUT.put_line(TO_CHAR(SQL%ROWCOUNT)||
' employee(s) changed job');
ELSE
DBMS_OUTPUT.put_line('No employee found with job'||
' of '||l_old_job);
END IF;
END;
Section 4 Quiz
1. An Exception is an identifier within PL/SQL that can be used
to trap for a specific condition. Exceptions are typically
associated with an error. Exceptions are either raised
automatically by PL/SQL or they can be raised explicitly.
3. EXCEPTION
5. DECLARE
l_name emp.ename%TYPE;
l_empno emp.empno%TYPE := &1;
BEGIN
SELECT ename
INTO l_name
FROM emp
WHERE empno = l_empno;
Section 4 Exercises
1. See answer to question 5 in the quiz.
2. DECLARE
l_number1 NUMBER := &1;
l_number2 NUMBER := &2;
e_bigger EXCEPTION;
BEGIN
IF l_number1 > l_number2 THEN
RAISE e_bigger;
END IF;
EXCEPTION
WHEN e_bigger THEN
DBMS_OUTPUT.put_line
('EXCEPTION : first is bigger than second');
END;
3. BEGIN
UPDATE transactions
SET comments = 'THIS IS A COMMENT LINE';
END;
4. DECLARE
l_error VARCHAR2(100);
e_too_big EXCEPTION;
PRAGMA EXCEPTION_INIT(e_too_big,-1401);
BEGIN
UPDATE transactions
SET comments = 'THIS IS A COMMENT LINE';
EXCEPTION
WHEN e_to_big THEN
l_error := 'Error : Could not update '||
'transactions table - '||SQLERRM;
DBMS_OUTPUT.put_line(l_error);
INSERT INTO messages
(logged_at
, message) VALUES
( SYSDATE
, l_error);
END;
Section 5 Quiz
1. An Explicit Cursor is a named construct within PL/SQL that is
used to retrieve data from the database.
4. 6 errors.
DECLARE
CURSOR employee_cur(p_deptno emp.deptno)
IS
SELECT ename
, job Missing %TYPE
FROM emp
WHERE deptno = l_deptno;
Section 5 Exercises
1. DECLARE
CURSOR dept_cur
IS
SELECT deptno
, dname
, loc
FROM dept;
BEGIN
FOR r_dept in dept_cur
LOOP
DBMS_OUTPUT.put_line(r_dept.deptno);
DBMS_OUTPUT.put_line(r_dept.dname);
DBMS_OUTPUT.put_line(r_dept.loc);
END LOOP;
END;
2. DECLARE
CURSOR dept_cur
IS
SELECT deptno
, dname
, loc
FROM dept;
r_dept dept_cur%ROWTYPE;
BEGIN
OPEN dept_cur;
LOOP
FETCH dept_cur INTO r_dept;
DBMS_OUTPUT.put_line(TO_CHAR(dept_cur%ROWCOUNT)||
' department(s) copied');
CLOSE dept_cur;
END;
Section 6 Quiz
1. Stored programs are stored within the database in compiled
form and executed on the database, whereas anonymous
blocks are usually held in a host file and are parsed and
compiled at runtime, they are explicitly executed in a client
tool, typically SQL*Plus.
8. 3 errors
Keywords the wrong way round
9. DECLARE
l_ename emp.ename%TYPE;
l_sal emp.sal%TYPE;
BEGIN
EmpInfo( 7900
, l_ename
, l_sal);
END;
Exercises
1. CREATE OR REPLACE PROCEDURE DelEmp(p_job IN emp.job%TYPE)
IS
BEGIN
DELETE old_emp
WHERE job = p_job;
DBMS_OUTPUT.put_line(TO_CHAR(SQL%ROWCOUNT)||' removed');
END;
p_count := SQL%ROWCOUNT;
END;
RETURN SQL%ROWCOUNT;
END;
Section 7 Quiz
1. A package is a named PL/SQL block that is stored in
compiled form and executed within the database. Packages
can contain subprograms and data.
11. No, because the function has an OUT parameter, these are
not allowed when invoking a function from DML.
Section 7 Exercises
Here is the finished package, though I have not included any
exception handling and some of the code could probably have
been written in a more generic/complete way, I have tried to keep
it simple as the main concern here is the creation of the actual
package and not what it does.
--
-- Private procedures/functions
--
PROCEDURE p(p_text IN VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.put_line(p_text);
END;
--
-- Public procedure/function definitions
--
BEGIN
INSERT INTO items
( item_id
, item_number
, description
, status
, cost ) VALUES
( items_item_id_s.NEXTVAL
, p_item_number
, p_description
, c_test_status
, c_new_cost);
p('Item created');
END;
r_items items_cur%ROWTYPE;
BEGIN
OPEN items_cur(p_item_id);
p('Item promoted');
END IF;
END IF;
END IF;
CLOSE items_cur;
END;
-- Give feedback
IF SQL%NOTFOUND THEN
p('Test item not found');
ELSE
p('Item deleted');
END IF;
END;
-- Give feedback
IF SQL%NOTFOUND THEN
p('Item not found');
ELSE
p('Cost changed');
END IF;
END;
END items_api;
Section 8 Quiz
1. A trigger is a named PL/SQL block that fires implicitly when a
particular database event occurs.
7. 4 errors:-
CREATE OR REPLACE TRIGGER set_stock
BEFORE INSERT ON transactions
Used EVERY FOR EVERY ROW
instead of EACH WHEN (:new.transaction_type IN ('ISS','RCT'))
BEGIN
Missing colon (:) before new
No need for UPDATE stock
colon (:) here SET quantity = quantity + new.quantity
WHERE item_id = :new.item_id;
COMMIT; COMMIT not allowed in a trigger
END; (unless AUTONOMOUS_TRANSACTION)
8. DML statements.
Exercises
1. CREATE OR REPLACE TRIGGER items_archive_t
BEFORE DELETE ON items
FOR EACH ROW
BEGIN
INSERT INTO items_archive
( item_id
, item_number
, description
, status
, cost
, date_archived ) VALUES
( :old.item_id
, :old.item_number
, :old.description
, :old.status
, :old.cost
, SYSDATE);
END;