Você está na página 1de 23

BASE DE

DATOS II

Base de
Datos II

Errores PL/SQL
Bloque Pl/SQL
INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Agenda

Tipos de datos de PL/SQL.

La estructura de datos TABLE INDEX.

Manejo de Excepciones.

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Tipos de Datos escalares base



CHAR [ (longitud_maxima) ]

VARCHAR2 (longitud_maxima)

LONG

LONG RAW

NUMBER [ (precisión, escala) ]

BINARY_INTEGER

PLS_INTEGER

BOOLEAN

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Tipos de Datos escalares base



DATE

TIMESTAMP

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH LOCAL TIME
ZONE

INTERVAL YEAR TO MONTH

INTERVAL DAT TO SECOND

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Comentar el código

Prefije los comentarios con dos guiones ( -- ).

Coloque los comentarios multi-línea entre los símbolos /* y */.

Ejemplo:

DECLARE
DECLARE
...
...
v_sal
v_sal NUMBER
NUMBER (9,
(9, 22 );
);
BEGIN
BEGIN
/*
/* Calcula
Calcula el
el salario
salario anual
anual en
en base
base al
al salario
salario
mensual
mensual ingresado
ingresado por
por el
el usuario
usuario */*/
v_sal
v_sal :=
:= :g_monthly_sal
:g_monthly_sal ** 12;
12;
END;
END; ---- Este
Este es
es el
el final
final del
del bloque
bloque

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Tablas INDEX BY

Están compuestas por dos componentes:
− Llave primaria de tipo de datos
BINARY_INTEGER.
− Columna de tipo de dato escalar o registro.
− Puede crecer en tamaño de manera dinámica
porque no están restringidas.

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Crear una Tabla INDEX BY



Sintaxis:
TYPE
TYPE nombre_tipo
nombre_tipo IS
IS TABLE
TABLE OF
OF
{tipo_columna
{tipo_columna || variable%TYPE
variable%TYPE
|| tabla.columna%TYPE}
tabla.columna%TYPE} [NOT
[NOT NULL]
NULL]
|| tabla%ROWTYPE
tabla%ROWTYPE
[INDEX
[INDEX BY
BY BINARY_INTEGER];
BINARY_INTEGER];

Declare una tabla
identificador
INDEX BY para almacenar
nombre_tipo;
nombres.

Ejemplo:
identificador nombre_tipo;

……
TYPE
TYPE ename_table_type
ename_table_type IS
IS TABLE
TABLE OF
OF
employees.last_name%TYPE
employees.last_name%TYPE
INDEX
INDEX BY
BY BINARY_INTEGER;
BINARY_INTEGER;
ename_table
ename_table ename_table_type;
ename_table_type;
……
INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Crear una Tabla INDEX BY


DECLARE
DECLARE
TYPE
TYPE ename_table_type
ename_table_type IS IS TABLE
TABLE OF
OF
employees.last_name%TYPE
employees.last_name%TYPE
INDEX
INDEX BYBY BINARY_INTEGER;
BINARY_INTEGER;
TYPE
TYPE hiredate_table_type
hiredate_table_type IS IS TABLE
TABLE OF
OF DATE
DATE
INDEX
INDEX BYBY BINARY_INTEGER;
BINARY_INTEGER;
ename_table
ename_table ename_table_type;
ename_table_type;
hiredate_table
hiredate_tablehiredate_table_type;
hiredate_table_type;
BEGIN
BEGIN
ename_table(1)
ename_table(1):= := ‘CAMERON’;
‘CAMERON’;
hiredate_table(8)
hiredate_table(8) := := SYSDATE
SYSDATE ++ 7;
7;
IF
IF ename_table.EXISTS(1)
ename_table.EXISTS(1) THENTHEN
INSERT
INSERT INTO
INTO ……
……
END;
END;
//

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Usar Métodos de Tablas INDEX BY



Los siguientes métodos facilitan el
uso de tablas INDEX BY:
− EXISTS(n)
− COUNT
− FIRST y LAST
− PRIOR(n)
− NEXT(n)
− TRIM
− DELETE

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Tabla de Registros INDEX BY



Defina una variable TABLE con un tipo de dato
permitido en PL/SQL.

Declare una variable PL/SQL para almacenar
la información de un departamento.
DECLARE
DECLARE
TYPE
TYPE dept_table_type
dept_table_type IS
IS TABLE
TABLE OF
OF
departments%ROWTYPE
departments%ROWTYPE
INDEX
INDEX BY
BY BINARY_INTEGER;
BINARY_INTEGER;
dept_table
dept_table dept_table_type;
dept_table_type;
--
-- Each
Each element
element of
of dept_table
dept_table is
is aa record
record

INGENIERÍA
DE SOFTWARE
BASE DE

Ejemplo de Tabla de Registros INDEX


DATOS II

BY SET
SET SERVEROUTPUT
SERVEROUTPUT ON
DECLARE
DECLARE
ON

TYPE
TYPE emp_table_type
emp_table_type IS IS TABLE
TABLE OF
OF
employees%ROWTYPE
employees%ROWTYPE
INDEX
INDEX BYBY BINARY_INTEGER;
BINARY_INTEGER;
my_emp_table
my_emp_table emp_table_type;
emp_table_type;
v_count
v_count NUMBER(3)
NUMBER(3) := := 104;
104;
BEGIN
BEGIN
FOR
FOR ii IN
IN 100..v_count
100..v_count
LOOP
LOOP
SELECT
SELECT ** INTO
INTO my_emp_table(i)
my_emp_table(i) FROM
FROM employees
employees
WHERE
WHERE employee_id
employee_id == i; i;
END
END LOOP;
LOOP;
FOR
FOR ii IN
IN my_emp_table.FIRST..my_emp_table.LAST
my_emp_table.FIRST..my_emp_table.LAST
LOOP
LOOP
DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name);
DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name);
END
END LOOP;
LOOP;
END;
END;
INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Manejo de errores

Una condición de error se denomina excepción
(exception).

Puede ser definida Internamente (por el
sistema en tiempo de ejecución) ó por el
usuario.

Ejemplos:
−ZERO_DIVIDE: ORA-22056 (value string is divided
by zero).
−STORAGE_ERROR: ORA-27102 (out of memory).

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Ejemplo de manejo de excepciones


DECLARE
DECLARE
stock_price
stock_price NUMBER
NUMBER :=
:= 9.73;
9.73;
net_earnings
net_earnings NUMBER
NUMBER :=
:= 0;
0;
pe_ratio
pe_ratio NUMBER;
NUMBER;
BEGIN
BEGIN
--
-- Calculation
Calculation might
might cause
cause division-by-zero
division-by-zero error.
error.
pe_ratio
pe_ratio :=
:= stock_price
stock_price // net_earnings;
net_earnings;
DBMS_OUTPUT.PUT_LINE('Price/earnings
DBMS_OUTPUT.PUT_LINE('Price/earnings ratio
ratio == '' ||
|| pe_ratio);
pe_ratio);
EXCEPTION
EXCEPTION -- -- exception
exception handlers
handlers begin
begin
--
-- Only
Only one
one of
of the
the WHEN
WHEN blocks
blocks is
is executed.
executed.
WHEN
WHEN ZERO_DIVIDE
ZERO_DIVIDE THEN
THEN --
-- handles
handles 'division
'division by
by zero'
zero' error
error
DBMS_OUTPUT.PUT_LINE('Company
DBMS_OUTPUT.PUT_LINE('Company must
must have
have had
had zero
zero earnings.');
earnings.');
pe_ratio
pe_ratio :=:= NULL;
NULL;
WHEN
WHEN OTHERS
OTHERS THEN
THEN ---- handles
handles all
all other
other errors
errors
DBMS_OUTPUT.PUT_LINE('Some
DBMS_OUTPUT.PUT_LINE('Some other
other kind
kind of
of error
error occurred.');
occurred.');
pe_ratio
pe_ratio :=
:= NULL;
NULL;
END;
END; --
INGENIERÍA
-- exception
exception handlers
handlers and
and block
block end
end here
here
DE SOFTWARE
BASE DE
DATOS II

Manejo de errores

Puede definir excepciones personalizadas
(user exceptions) asociadas a un identificador,
en un bloque PL/SQL, subprograma o paquete.

Ejemplo:
−insufficient_funds:
excepción para indicar una
cuenta bancaria sobregirada.

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Manejo de errores

Las excepciones personalizadas deben
provocarse explícitamente con:
−La sentencia RAISE
−Invocando al procedimiento
DBMS_STANDARD.RAISE_APPLICATION_ERROR.

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Manejo de errores

Para manejar excepciones, se escribe rutinas
separadas denominadas exception handlers.

Luego de ejecutar un exception handler, se
detiene la ejecución del bloque actual y el bloque
superior continúa con la siguiente sentencia.

Si no hay bloque superior, el control retorna al
entorno host.

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Uso de excepciones personalizadas


DECLARE
DECLARE
past_due
past_due EXCEPTION;
EXCEPTION;
acct_num
acct_num NUMBER;
NUMBER;
BEGIN
BEGIN
DECLARE
DECLARE ----------
---------- sub-block
sub-block begins
begins
past_due
past_due EXCEPTION; -- this declaration
EXCEPTION; -- this declaration prevails
prevails
acct_num NUMBER;
acct_num NUMBER;
due_date
due_date DATE
DATE :=
:= SYSDATE
SYSDATE -- 1;
1;
todays_date
todays_date DATE
DATE :=:= SYSDATE;
SYSDATE;
BEGIN
BEGIN
IF
IF due_date
due_date << todays_date
todays_date THEN
THEN
RAISE
RAISE past_due; -- this is
past_due; -- this is not
not handled
handled
END IF;
END IF;
END;
END; -------------
------------- sub-block
sub-block ends
ends
EXCEPTION
EXCEPTION
--
-- Does
Does not
not handle
handle raised
raised exception
exception
WHEN
WHEN past_due
past_due THEN
THEN
DBMS_OUTPUT.PUT_LINE('Handling
DBMS_OUTPUT.PUT_LINE('Handling PAST_DUE
PAST_DUE exception.');
exception.');
WHEN OTHERS THEN
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE
DBMS_OUTPUT.PUT_LINE
('Could
('Could not
not recognize
recognize PAST_DUE_EXCEPTION
PAST_DUE_EXCEPTION in in this
this scope.');
scope.');
END;
END;
INGENIERÍA
DE SOFTWARE
BASE DE

Asociar una excepción con un número


DATOS II

de error

Para manejar condiciones de error
(normalmente mensajes ORA-n) que no tienen
nombre predefinido, debe usar el manejador
OTHERS o el pragma EXCEPTION_INIT.

Pragma es una directiva para el compilador que
se procesa en tiempo de compilación, no en
tiempo de ejecución.
PRAGMA
PRAGMA EXCEPTION_INIT(exception_name,
EXCEPTION_INIT(exception_name,
-Oracle_error_number);
-Oracle_error_number);

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Uso de PRAGMA EXCEPTION_INIT


DECLARE
DECLARE
deadlock_detected
deadlock_detected EXCEPTION;
EXCEPTION;
PRAGMA
PRAGMA EXCEPTION_INIT(deadlock_detected,
EXCEPTION_INIT(deadlock_detected, -60); -60);
BEGIN
BEGIN
NULL;
NULL; --
-- Some
Some operation
operation that
that causes
causes an
an ORA-00060
ORA-00060 error
error
EXCEPTION
EXCEPTION
WHEN
WHEN deadlock_detected
deadlock_detected THENTHEN
NULL;
NULL; --
-- handle
handle the
the error
error
END;
END;
//

INGENIERÍA
DE SOFTWARE
BASE DE

Definir mensajes de error


DATOS II

personalizados

Con RAISE_APPLICATION_ERROR puede
producir mensajes ORA-n personalizados.

raise_application_error(error_number,
raise_application_error(error_number,
● message[,
RAISE_APPLICATION_ERROR es parte del
message[,
{TRUE
{TRUE || FALSE}]);
FALSE}]);
paquete DBMS_STANDARD, cuyos métodos
no requieren especificar nombre de paquete.

INGENIERÍA
DE SOFTWARE
BASE DE

Definir mensajes de error


DATOS II

personalizados

error_number: entero negativo en el rango
-20000..-20999.

Message: cadena de caracteres de hasta 2048
bytes.

Tercer parámetro (opcional):
−TRUE, error colocado en la pila de errores
anteriores.
−FALSE (por defecto), error reemplaza los errores
anteriores.

INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Uso de RAISE_APPLICATION_ERROR
DECLARE
DECLARE
num_tables
num_tables NUMBER;
NUMBER;
BEGIN
BEGIN
SELECT
SELECT COUNT(*)
COUNT(*) INTO
INTO num_tables
num_tables FROM
FROM USER_TABLES;
USER_TABLES;
IF
IF num_tables
num_tables << 1000
1000 THEN
THEN
/*
/* Issue
Issue your
your own
own error
error code
code (ORA-20101)
(ORA-20101)
with
with your
your own
own error
error message.
message. You
You need
need not
not
qualify
qualify RAISE_APPLICATION_ERROR
RAISE_APPLICATION_ERROR with with
DBMS_STANDARD
DBMS_STANDARD */ */
RAISE_APPLICATION_ERROR
RAISE_APPLICATION_ERROR
(-20101,
(-20101, 'Expecting
'Expecting at at least
least 1000
1000 tables');
tables');
ELSE
ELSE
--
-- Do
Do rest
rest of
of processing
processing (for
(for nonerror
nonerror case)
case)
NULL;
NULL;
END
END IF;
IF;
END;
END;
//
INGENIERÍA
DE SOFTWARE
BASE DE
DATOS II

Resumen

Los tipos de datos utilizados en PL/SQL.

El tipo de dato TABLE INDEX.

Manejo de errores en PL/SQL.

INGENIERÍA
DE SOFTWARE

Você também pode gostar