Download Spis treści 1 Cursors

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Database wikipedia , lookup

Oracle Database wikipedia , lookup

Clusterpoint wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Database model wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Relational model wikipedia , lookup

SQL wikipedia , lookup

PL/SQL wikipedia , lookup

Transcript
Table of Contents
Spis treści
1 Cursors
1.1 SQL in PL/SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1
2 Exceptions
2.1 Predefined Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Non-predefined Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Defining Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
5
6
6
3 Summary
8
4 Resources
9
1
Cursors
1.1
SQL in PL/SQL
SQL in PL/SQL
Inside PL/SQL we can use some of SQL statements:
• queries: SELECT with INTO,
• DML: INSERT, UPDATE, DELETE, MERGE,
• TCL: COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION, LOCK.
SELECT Statement
SELECT statement must return only one row !!!
The INTO clause is required !!!
The names of database columns take precedence over the names of local
variables !!!
SELECT select_list
INTO {variables_list | record_name}
FROM ...;
SELECT example
DECLARE
v_first_name employees.first_name%TYPE;
BEGIN
SELECT first_name INTO v_first_name
FROM employees
WHERE employee_id = 200;
DBMS_OUTPUT.PUT_LINE(’First name is ’
|| v_first_name);
END;
/
1
Cursor
A Cursor
is a pointer to a private SQL area (known as context area) that stores information about
the processing of a SELECT or data manipulation language (DML) statement (INSERT,
UPDATE, DELETE, or MERGE).
Types of cursor
• Implicit cursors - created automatically for all SQL data manipulation statements
and PL/SQL SELECT statement
• Explicit cursors - created and managed by a programmer for queries that return
more than one row
Explicit cursor control
You will use three statements to control a cursor (after declaring it):
• OPEN
• FETCH
• CLOSE
Declaring a Cursor
CURSOR name [(parameter1 typ [:=|DEFAULT value1]
[, parameter2...]...)]
[RETURN rowtype] IS SELECT...;
Examples:
CURSOR c_bosses IS
SELECT DISTINCT manager_id FROM employees;
CURSOR c_dep (p_id NUMBER) IS
SELECT * FROM employees WHERE department_id=p_id;
CURSOR c_dep_2 (p_id NUMBER := 10) IS
SELECT * FROM employees WHERE department_id=p_id;
CURSOR c_employees RETURN employees%ROWTYPE;
Opening the Cursor
OPEN name (parameters_list);
Example:
DECLARE
CURSOR c_dep (p_id NUMBER) IS
SELECT * FROM employees WHERE department_id=p_id;
...
BEGIN
OPEN c_dep(50);
...
END;
2
Fetching Data from the Cursor
FETCH name INTO {variables_list|record};
Example:
DECLARE
CURSOR c_dep (p_id NUMBER) IS
SELECT * FROM employees WHERE department_id=p_id;
vr_employee employees%ROWTYPE;
...
BEGIN
OPEN c_dep(50);
FETCH c_dep INTO vr_employee;
...
END;
Closing the Cursor
CLOSE name;
Example:
DECLARE
CURSOR c_dep (p_id NUMBER) IS
SELECT * FROM employees WHERE department_id=p_id;
vr_employee employees%ROWTYPE;
...
BEGIN
OPEN c_dep(50);
FETCH c_dep INTO vr_employee;
CLOSE c_dep;
...
END;
Attributes of Explicit Cursors
• %ISOPEN - returns TRUE if its cursor or cursor variable is open; otherwise, returns
FALSE (for implicit always FALSE),
• %FOUND - After a cursor or cursor variable is opened but before the first fetch, %FOUND
returns NULL. After any fetches, it returns TRUE if the last fetch returned a row, or
FALSE if the last fetch did not return a row,
• %NOTFOUND - Before the first fetch, returns NULL. If FETCH never executes successfully,
the loop is never exited, because the EXIT WHENstatement executes only if its WHEN
condition is true.
• %ROWCOUNT - Before the first fetch, %ROWCOUNT yields zero. Thereafter, it yields the
number of rows fetched so far. The number is incremented if the last fetch returned
a row.
3
Loops and Cursors
DECLARE
CURSOR c_dep (p_id NUMBER) IS
SELECT * FROM employees WHERE department_id=p_id;
vr_employee employees%ROWTYPE;
BEGIN
OPEN c_dep(50);
LOOP
FETCH c_dep INTO vr_employee;
EXIT WHEN c_dep%NOTFOUND OR c_dep%NOTFOUND IS NULL;
DBMS_OUTPUT.PUT_LINE(c_dep%ROWCOUNT || ’ . ’
|| vr_employee.last_name);
END LOOP;
DBMS_OUTPUT.PUT_LINE(c_dep%ROWCOUNT || ’ employees ’);
CLOSE c_dep;
END;
/
Cursor FOR Loops
DECLARE
CURSOR c_dep (p_id NUMBER) IS
SELECT * FROM employees WHERE department_id=p_id;
--vr_employee employees%ROWTYPE;
BEGIN
FOR vr_employee IN c_dep(50) LOOP
DBMS_OUTPUT.PUT_LINE(c_dep%ROWCOUNT || ’ . ’
|| vr_employee.last_name);
END LOOP;
END;
/
Cursor FOR loops
DECLARE
v_id employees.department_id%TYPE := &id;
BEGIN
FOR vr_employee IN (SELECT * FROM employees
WHERE department_id = v_id ) LOOP
DBMS_OUTPUT.PUT_LINE(vr_employee.last_name);
END LOOP;
END;
/
2
Exceptions
What is an exception?
4
Exception
An exception
is a PL/SQL error that is raised during program execution. It can be raised implicitly
by the Oracle Server, explicitly by the program. It can be handled by trapping it with a
handler or by propagating it to the calling environment.
Exception Types
• Implicitly raised
– predefined
– non-predefined
• Explicitly raised - user defined exceptions
2.1
Predefined Exceptions
Predefined PL/SQL Exceptions
• CASE_NOT_FOUND - None of the choices in the WHEN clauses of a CASE statement is
selected, and there is no ELSE clause.
• CURSOR_ALREADY_OPEN - A program attempts to open an already open cursor. A
cursor must be closed before it can be reopened.
• DUP_VAL_ON_INDEX - A program attempts to store duplicate values in a column that
is constrained by a unique index.
• INVALID_CURSOR - A program attempts a cursor operation that is not allowed, such
as closing an unopened cursor.
• INVALID_NUMBER - n 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.)
• LOGIN_DENIED - A program attempts to log on to the database with an invalid
username 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.
• NOT_LOGGED_ON - A program issues a database call without being connected to the
database.
• TIMEOUT_ON_RESOURCE - A time out occurs while the database is waiting for a
resource.
• TOO_MANY_ROWS - A SELECT INTO statement returns more than one row.
• VALUE_ERROR - An arithmetic, conversion, truncation, or size-constraint error occurs.
• ZERO_DIVIDE - A program attempts to divide a number by zero.
5
Useful functions
• SQLERRM - error code,
• SQLCODE - message text.
Trapping Exceptions
EXCEPTION
WHEN exception1 [OR exception2 ...] THEN
statements1;
[WHEN exception3 [OR exception4 ...] THEN
statements2;
...]
[WHEN OTHERS THEN
statements_n;]
WHEN OTHERS
• OTHERS exception handler is uded to trap any exception that wasn’t specified.
• OTHERS must be the last exception handler on the list.
2.2
Non-predefined Exceptions
Non-predefined Exceptions
• They are any other standard Oracle Server errors
• They must be declared within declarative section
• We need to associate given name with this external error number by using: PRAGMA EXCEPTION_INIT
Trapping Non-predefined Exceptions
DECLARE
e_insert EXCEPTION;
PRAGMA EXCEPTION_INIT(e_insert, -014000);
BEGIN
INSERT INTO departments (department_id, department_name)
VALUES(300, ’Executives’)
EXCEPTION
WHEN e_insert THEN
DBMS_OUTPUT.PUT_LINE (’Insertion error’);
END;
/
2.3
Defining Exceptions
User-Defined Exceptions
How to create and handle my own exception?
6
Defining Your Own PL/SQL Exceptions
• Declaring
e_name EXCEPTION;
• raising:
RAISE e_name;
• handling:
EXCEPTION
WHEN e_name1 THEN
statements1;
WHEN e_name2 THEN
statements2;
...
WHEN OTHERS THEN
statements_n;
Using RAISE to Raise a User-Defined Exception
DECLARE
e_zero_value EXCEPTION;
...
BEGIN
...
IF v_id = 0 THEN
RAISE e_zero_value;
END IF;
...
EXCEPTION
WHEN e_zero_value THEN
dbms_output.put_line(’Invalid ID value.’);
END;
Propagation Rules I
BEGIN
...
BEGIN
...
IF v_id = 0 THEN
RAISE e_zero_value;
END IF;
...
EXCEPTION
WHEN e_zero_value THEN
dbms_output.put_line(’Invalid ID value.’);
7
END;
...
EXCEPTION
...
END;
Propagation Rules II
BEGIN
...
BEGIN
...
IF v_id = 0 THEN
RAISE e_zero_value;
END IF;
...
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line(’Too many rows.’);
END;
...
EXCEPTION
WHEN e_zero_value THEN
dbms_output.put_line(’Invalid ID value.’);
END;
Propagation Rules III
BEGIN
...
BEGIN
...
IF v_id = 0 THEN
RAISE e_zero_value;
END IF;
...
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line(’Too many rows.’);
END;
...
EXCEPTION
WHEN VALUE_ERROR THEN
dbms_output.put_line(’Value error’);
END;
Raise application error
The RAISE_APPLICATION_ERROR procedure lets you issue user-defined error messages
from stored subprograms. That way, you can report errors to your application and avoid
returning unhandled exceptions. Syntax:
raise_application_error(
error_number, message[, {TRUE | FALSE}]);
8
where error_number is a negative integer in the range -20000..-20999 and message is a
character string up to 2048 bytes long. If the optional third parameter is TRUE, the error
is placed on the stack of previous errors. If the parameter is FALSE (the default), the error
replaces all previous errors. For example:
IF v_id = 0 THEN
Raise_application_error(-20002,
’Invalid ID’);
ELSE
...
END IF;
3
Summary
Summary
PL/SQL allows you to use:
• use variables, constants,
• control instructions,
• sequential processing - oriented on data,
• handling exceptions,
• using predefined packages and libraries,
• and many others, as in the next lecture ...
4
Resources
Resources
• http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/toc.htm
• M. Lentner, Oracle 9i Kompletny podręcznik użytkownika, PJWSTK - W-wa, 2003
• http://www.ploug.org.pl/showhtml.php?file=szkola/szkola_9/materialy
• http://plsql-tutorial.com/index.htm
• http://www.toadworld.com/platforms/oracle/w/wiki/8243.plsql-obsession.
aspx
9