Documente Academic
Documente Profesional
Documente Cultură
Introduccin
Se transforma requerimientos del negocio dentro de una base de datos operacional.
Estrategia y anlisis Diseo Construccin y documentacin Transicin
Produccin
Una BD es una coleccin de informacin organizada, hay 4 tipos jerrquica, red,
relacional y relacional de objetos
Concepto de BD relacional
Coleccin de objetos o relaciones
Un grupo de operadores pueden actuar en las relaciones para producir otras relaciones
Integridad de los datos para exactitud y consistencia
Definicin de una BD relacional
Es una coleccin de relaciones o tablas en dos dimensiones
Modelos de datos
Son la piedra angular del diseo ayudan a entender lo que quiere el cliente.
Modelos ER
Los datos son divididos dentro de categoras discretas o entidades, un modelo de
relacin entre entidades es una ilustracin de varias entidades en el negocio y la
relacin entre estas, los modelos separan la informacin requerida por los negocios de
las actividades de estos.
Componentes
Entidad : Objeto que representa la informacin que se necesita
Atributo : Describe o califica la entidad
Relacin : Asociacin entre entidades mostrando opcionalidad y grado(cardinalidad).
Identificadores nicos
Son una combinacin de atributos o relaciones o ambos, este hace que cada
ocurrencia de una entidad sea nica Smbolo #, secundario (#)
Relacionando mltiples tablas
Cada tabla contiene datos que describen exactamente una entidad, las categoras de
los datos son listados en los atributos y los casos individuales en las filas.
Las llaves forneas son basadas en valores de datos y son puramente lgicos, no
fsicos, apuntadores.
Propiedades de una BD relacional
Puede ser accedida y modificada con sentencias structured query language (SQL) el
cual permite comunicarse con el servidor
Contiene una coleccin de tablas
Usa un grupo de operadores
Sistema de BD relacional
Se puede almacenar y administrar datos con todas las ventajas de la estructura
relacional PL/SQL
Oracle 8 : Sistema de administracin de BD relacionales de objetos
Provee una nueva mquina que trae programacin orientada a objetos, tipos de datos
complejos, objetos de negocio complejos y total compatibilidad con el mundo
relacional.
Usuario define tipos de datos y objetos
Soporta objetos grandes y multimeda
2
Oracle 8i : BD en plataforma internet
Contiene herramientas avanzadas para administrar todos los tipos de datos en web
sites.
iFS Internet File System combina el poder de Oracle 8i con el fcil uso de un FS, los
usuarios pueden fcilmente acceder a los archivos y folders en un iFS usando una
variedad de protocolos como HTML, FTP, IMAP4 .
Oracle 8i incluye una robusta, integrada y escalable mquina virtual de java dentro
del servidor Jserver
O8i provee full integracin con Microsoft Transaction Server (MTS)
Plataforma de internet Oracle
Para e-commerce y data warehousing es construida en 3 piezas principales
1. Clientes Browser based para procesar presentacin
2. Servidores de aplicacin para ejecutar lgica de los negocios y lgica de la
presentacin para clientes browser-based
3. Bases de datos para ejecutar lgica de negocios intensiva y servicio de datos
Sentencias SQL
SELECT
Recuperacin de datos
INSERT
UPDATE
DELETE
DML
CREATE
ALTER
DROP
RENAME
TRUNCATE
DDL
COMMIT
ROLLBACK
SAVEPOINT
Control transaccional
GRANT
REVOKE
Mquina PL/SQL
PL/SQL
BLOCK
PL/SQL
BLOCK
Ejecutor de sentencias
procedimentales
4
SQL
SQL*Plus
Lenguaje
Es ANSI
SQL*Plus
Categora
Environment
Format
File Manipulatin
Executin
Edit
Interaccin
Miscellaneous
Propsito
Afecta en general todas las sentencias SQL para la sesin
Formatea resultados de la consulta
Saves, Loads y corre archivos de scripts
Envia sentencias SQL del buffer al servidor
Modifica sentencias SQL en el buffer
Permite que se pase y se cree variables para sentencias SQL
Contiene varios comandos para conectarse a la BD, manipular
el ambiente y desplegar definiciones de columnas
DESC[RIBE] tablename
Comandos de edicin de SQL*Plus
Comando
A[PPEND] text
C[HANGUE] text/old/new
C[HANGUE] /text/
CL[EAR] BUFF[ER]
DEL
I[NPUT]
I[NPUT] text
L[IST]
L[IST] n
L[IST] m n
N
n text
0 text
Descripcin
Adiciona texto al final de la lneas corriente
Cambia texto viejo por nuevo en la lneas corrienta
Borra texto de la lneas corriente
Borra todas las lneas del SQL buffer
Borra la lneas corriente
Inserta un nmero indefinido de lneas
Inserta una lneas con el texto
Lista todas las lneas en el SQL buffer
Lista la lneas n
Lista las lneas entre m y n
Especifica la lneas a ser la lneas corriente
Reemplaza la lneas n con el texto
Inserta una lneas antes de la lneas 1
Command
SAV[E] filename [.ext]
[REP[LACE]APP[END]]
GET filename[.ext]
STA[RT] filename[.ext]
@filename
ED[IT]
EDIT [Filename[.ext]]
SPO[OL] [filaname[.ext]]
OFF|OUT
EXIT
Descripcin
Salva las lneas corrientes del SQL buffer a un archivo
Trae un archivo salvado al SQL buffer
7
Aritmtica con fechas
Operacin
Date + number
Date date
Date + number/24
Result
Date
Nmero das
Date
Descripcin
Adiciona un nmero de das
Sustrae una fecha e otra
Adiciona nmero de horas
Funciones de fecha
MONTHS_BETWEEN(date1,date2) : Meses entre las dos fechas negativo o positivo
(01-SEPT-95,11-JAN-94) = 19.6774194
ADD_MONTHS(date,n): n positivo o negativo
(11-JAN-94,6) = 11-JUL-94
NEXT_DAY(date, char) : Encuentra la fecha de el prximo da especificado de la
semana.
(01-SEPT-95,FRIDAY) = 08-SEPT-95
LAST_DAY(date) : Encuentra el ultimo da del mes
(01-SEPT-95) = 30-SEPT-95
ROUND(date[,fmt]) : Retorna la fecha en la unidad especificada en el format model,
si el format model es omitido la fecha es redondeada al da mas cercano.
ROUND(25-JUL-95,MONTH) 01-AUG-95
ROUND(25-JUL-95,YEAR) 01-JAN-96
TRUNC(date[,fmt]) : Retorna la fecha con el tiempo de la porcin del da truncada
TRUNC(25-JUL-95,MONTH) = 01-JUL-95
TRUNC(25-JUL-95,YEAR) = 01-JAN-95
Conversin de tipos de datos implcita
Para evaluacin de expresiones
VARCHAR2 o CHAR
NUMBER
VARCHAR2 o CHAR
DATE
---NUMBER
VARCHAR2
DATE
VARCHAR2
Conversin explicita
TO_CHAR(number | date,[fmt],[nlsparams]) : nlsparams especifica carcter decimal,
separador de grupo, smbolo de moneda local, smbolo de moneda internacional o las
abreviaciones para el da el mes , tiene un elemento fm para remover blancos o
suprimir ceros
TO_NUMBER(char,[fmt],[nlsparams]) : Convierte un string de caracteres que
contienen dgitos a un nmero en el formato especificado.
TO_DATE(char,[fmt],[nlsparams]) : Si fmt es omitido se usa el default DD-MONYY
Elementos del modelo del formato de fecha
YYY
YEAR
MM Mes en dos dgitos
MONTH Nombre completo del mes
DY Abreviacin de tres letras para el da de la semana
DAY
SCC o CC Siglos S prefijo BC con
IYYY,IYY,IY,I 4, 3 ,2 1 digito del ao basado en el estndar ISO
RM mes en nmeros romanos
WW o W semana del ao o del mes
DDD o DD o D da del ao, mes o semana
J da juliano
HH24:MI:SS AM
DD of MONTH
15:45:32 PM
12 of OCTOBER
8
Nmero de sufijos para nmeros
Ddspth fourteenth
AM o PM
Indicador de meridiano
A.M o P.M Indicador de meridiano con periodos
HH o HH12 o HH24
Hora del da u hora (1-12) u hora (0-23)
MI
Minuto de 0-59
SS
Segundo de 0-59
SSSS
Segundos pasados la media noche (0-86399)
/. , Puntuacin es reproducida en el resultado
TH
Nmero ordinario (Ej DDTH para 4TH)
SP
Ej DDSP para FOUR
SPTH o THSP Ej DDSPTH para FOURTH
Usando funcin TO_CHAR con fechas
SELECT ename, TO_CHAR(hiredate, fmDD Month YYYY)
FROM emp
KING
17 November 1981
9999 1234
0999 001234
$999 $1234
L999 FF1234
9.999 1.234
9,999 9,999
99MI 123499PR <1234>
99.999EEEE 1.234E+03
9V99 100
B9999.99
1234.00
YY
El siglo corriente
El siglo corriente
Funcin NVL
NVL (expr1, expr2 ) convierte a nmeros, fechas y char o varchar2
Funcin DECODE
Fcilita el trabajo condicional como el CASE
DECODE (col/expresin ,
search1 , result1
[ , search2 , result2 , ..... ,]
[ , default ]
Si el default es omitido retorna NULL si la cadena no coincide con ninguna condicin
9
SELECT
job, sal,
DECODE( job,
ANALYST , SAL*1.1,
CLERK , SAL*1.15,
SAL )
FROM emp;
Funciones anidadas
Funciones de una sola fila pueden ser anidadas a cualquier nivel , y son evaluadas
desde la ms profunda a la menos profunda. o sea de adentro hacia fuera
10
11
12
Captulo 6 subqueries
Se pueden colocar en : WHERE , HAVING, FROM
SELECT select_list
FROM table
WHERE exp operator
( SELECT select list
FROM table);
Los operadores de comparacin caen en dos clases una sola fila ( <, >,=,< >,<=,>= ) y
multiples filas (IN, ALL, ANY )
El sub query se ejecuta primero y su salida completa el query total.
No adicionar una clausula ORDER BY a un subquery.
Tipos de subqueries : De una sola fila, multiples filas, multiples columnas
Se pueden usar funciones de grupo en los subqueries
SELECT ename, job
FROM emp
WHERE sal = ( SELECT MIN(sal) FROM emp );
SELECT deptno , MIN(sal)
FROM emp
GROUP BY deptno
HAVING MIN(sal) > (SELECT MIN(sal) FROM emp WHERE deptno = 20);
Subqueries de multiples filas
Operador
IN
ANY
ALL
Significado
Igual a cualquier miembro de la lista
Compara el valor con cada valor retornado de la lista
Compara el valor con todos los valores de la lista
SELECT empno
FROM emp
WHERE sal < ANY ( SELECT sal FROM emp WHERE job= CLERK)
AND job <> CLERK;
SELECT empno
FROM emp
WHERE sal > ALL ( SELECT AVG(sal) FROM emp GROUP BY deptno);
El operador NOT puede ser usado con ANY, IN , ALL
13
14
15
TERM[OUT] {OFF | ON } Determina si la salida es desplegada enla pantalla
El archivo login.sql contiene los SET estandar y otros comandos SQL*Plus que se
implementan en el login.
COL[UMN] [column option ] Controla el formato de las columnas
TTI[TLE] [text |OFF | ON ] Especifica el encabezado de cada pagina
BTI[TLE] [text |OFF | ON ] Especifica el pie de cada pagina
BRE[AK] [ON report_element ]
Si se da un alias a la columna este debe ser especificado, no el nombre de la columna
El comando COLUMN
COL[UMN] [ {column | alias } [ option ] ]
CLE[AR] limpia cualquier formato de columna
FOR[MAT] format Cambia el despliegue de una columna usando el formato
HEA[DING] text Setea el encabezado de la columna ( una barra vertical (|) forza un
line feed )
JUS[TIFY] {aling} Justifica el encabezado de la columna derecha, izq o centro
NOPRI[NT] no imprime la columna
NUL[L] text Especifica el texto a ser desplegado para valores NULL
PRI[NT] muestra la columna
TRU[NCATED] Trunca el string al final de la primera lneas desplegada
WRA[PPED]
COLUMN ename HEADING Employee|name FORMAT A15
COLUMN sal JUSTIFY LEFT FORMAT $99,999.00
COLUMN mgr FORMAT 9999999 NULL no manager
COL[UMN] ename Despliega los valores corrientes para una columna
COL[UMN] ename CLE[AR] Limpia los valores seteados para la columna
CLE[AR] COL[UMN] Limpia los valores seteados para todas las columnas
Si se tiene un comando muy largo se puede continuar colocando (-)
Modelos de formato de columnas
An
despliega un ancho n
9
Solo digitos 9999 1234
0
Fuerza al cero lider 099999 01234
$
Smbolo de dlar $9999 $1234
L
Moneda local L9999 L1234
.
,
El servidor Oracle despliega (#) si el nmero excede el tamao dado en el formato,
tambien si el valor e alfanumerico mientras el actual es numerico
BREAK ON ename ON job Suprime duplicados para asegurar que trabaja
correctamente usar ORDER BY.
BREAK ON ename SKIP 4 ON job SKIP 2
BREAK on column [ |alias|row ] [skip n | dup | page ] on .. [on report ]
Donde
page Tira una nueva pagina cuando el valor del break cambia
skip n
Salta un nmero de lneas cuando el valor cambia
break se activa con columna, fila , pagina, reporte
duplicate despliega valores duplicados
Para limpiar todos los juegos de BREAK usar CLEAR
CLEAR BREAK
16
17
Si un DDL falla, el usuario no puede volver a los datos anteriores porque este tiene
autocommit.
Consistencia de lectura
Garantiza una vista consistente de los datos todo el tiempo.
Cambios hechos por un usuario no tienen conflicto con los cambios hechospor otro
usuario.
El propsito es asegurar que cada usuario mire los datos como estaban con el ultimo
COMMIT, antes de que la operacin DML arrancara.
El LOCKING es efectivo debido a que previene acciones destructivas entre
operaciones concurrentes.
No requiere accin de l usuario
Usa el nivel mas bajo de restriccin.
Permanece por el tiempo que dure la transaccin.
Tiene dos modos Exclusive : Previene que un recurso sea compartido la primera
transaccin bloquea el recurso exclusivamente y Shared
18
19
DROP TABLE table;
Los sinonimos permanecen pero son invalidos, cualquier transaccin pendiente es
commited, lo puede hacer el dueo o usuarios con grant DROP ANY TABLE.
Para cambiar el nombre de una tabla, vista, secuencia o sinnimo.
RENAME old_name TO new_name;
Truncando una tabla
Libera el espacio de almacenamiento usado por la tabla, DELETE no. No se puede
hacer ROLLBACK, lo hace el dueo o un usuario con el grant DELETE TABLE.
Adicionando comentarios
COMMENT ON TABLE table | COLUMN IS xxxxxxx; para consultar
ALL_COL_COMMENTS, USER_COL_COMMENTS, ALL_TAB_COMMENTS,
USER_TAB_COMMENTS.
20
:
: Especifica una columna o columnas cuyo valor debe ser unico
El nombre del constraint es por default SYS_Cn, se puede crear con la tabla o
despus, se hace a nivel de tabla o columna, son almacenados en diccionario de datos,
USER_CONSTRAINTS.
CREATE TABLE [schema.]table
(column datatype [DEFAULT expr]
[column constraint ],
....
[ table_constraint ] [, ... ]);
column_name datatype CONSTRAINT const_name NOT NULL...
UNIQUE KEY permite nulos a menos que se le especifique NOT NULL se puede
definir a nivel de tabla o columna, Oracle crea un indice unico
CREATE TABLE deptno ( deptno
NUMBER(2),
Dname
VARCHAR2(14),
CONSTRAINT dept_name_uk UNIQUE (dname));
CREATE TABLE deptno ( deptno
NUMBER(2),
Dname
VARCHAR2(14),
CONSTRAINT dept_name_pk PRIMARY KEY (deptno));
CREATE TABKE emp
(....
deptno NUMBER (2) CONSTRAINT emp_deptno_fk FOREIGN KEY (deptno )
REFERENCES dept(deptno),
.....
);
ON DELETE CASCADE permite el borrado en la tabla padre y las filas dependientes
en las tablas hijas.
CHECK no se puede usar CURRVAL, NEXTVAL, LEVEL y ROWNUM ni
llamadas a SYSDATE, UID, USER y USERENV, se pueden definir mas de uno por
columna a nivel de columna o de tabla.
ALTER TABLE table ADD [ CONSTRAINT constraint ] type (column );
Para adicionar constraint NOT NULL con MODIFY.
ALTER TABLE table DROP PRIMARY KEY | UNIQUE (column) |
CONSTRAINT constraint [CASCADE];
ALTER TABLE table DISABLE CONSTRAINT constraint [CASCADE];
Se puede deshabilitar un constraint en la creacin de una tabla o con un ALTER.
ALTER TABLE table ENABLE CONSTRAINT constraint;
21
Se se habilita UNIQUE o PRIMARY KEY un indice se crea automaticamente, un
constraint se puede habilitar en la creacin de la tabla o con ALTER.
CASCADE CONSTRAINTS
Se usa con DROP COLUMN, borra todos los constraints dependientes, borra
constraints multicolumnas.
USER_CONSTRAINTS, USER_CONS_COLUMNS.
22
23
24
Que es un indice
Es un objeto, acelera la recuperacin de filas, reduce I/O utilizando un metodo de
acceso de camino rapido, es independiente de la tabla, es mantenido por el servidor.
Automticos : PK, UNIQUE
Manuales : no unicos creados por el usuario
CREATE INDEX index ON table (column,[column,...]);
Se crea cuando la columna es frecuentemente usada en el WHERE, la columna
cintiene un amplio rango de valores, contiene un gran nmero de valores NULL, la
tabla es grande y la mayoria de los querys esperan del 2-4% de las filas.
No se deben usar cuando la tabla es actualizada frecuentemente y las inversas de lo
anterior.
USER_INDEXES, USER_IND_COLUMNS.
Indices basados en funcin.
Es un indice basado en expresiones, la expresin se construye con columnas,
constantes, funciones SQL y funciones definidas por el usuario.
CREATE INDEX index ON table (expr)
Para asegurarse de que se usa el indice debe aasegurarse que el valor de la funcin es
NOT NULL.
SELECT * FROM emp WHERE UPPER(ename) IS NOT NULL;
DROP INDEX; El dueo o tener DROP ANY INDEX;
Sinonimos
Simplifica el acceso a los objetos, el objeto no puede estar contenido en un paquete.
CREATE SYNONYM [PUBLIC] FOR object;
DROP SYNONYM synonym;
Solo el DBA borra sinonimos publicos.
25
ROLE_SYS_PRIVS
Privilegios del sistema concedidos a los roles
ROLE_TAB_PRIVS
Privilegios de las tablas concedidos a los roles
USER_ROLE_PRIVS
Roles accesibles por el usuario
USER_TAB_PRIVS_MADE Privilegios de objeto concedidos a los objetos del
usuario
USER_TAB_PRIVS_RECD Privilegios de objeto concedidos al usuario
USER_COL_PRIVS_MADE Privilegios de objeto concedido a las columna de los
objetos del usuario
USER_COL_PRIVS_RECD Privilegios de objeto concedidos al usuario en columnas
especificas
REVOKE {privilege [, privilege ...] | ALL} ON object FROM {user [,user...] | role |
PUBLIC} [ CASCADE CONSTRAINTS ];
CASCADE CONSTRAINTS : Remueve cualquier constraint de integridad
referencial hechos al objeto por medio de REFERENCES
26
27
V_location VARCHAR2(13) NOT NULL := CHICAGO;
emp.ename%TYPE;
NUMBER(7,2);
v_balan%TYPE;
28
DBMS_OUTPUT.PUT_LINE alternativa para desplegar datos en un bloque
PL/SQL, se debe habilitar SQL*Plus con SET SERVER OUTPUT ON
mbito y visibilidad de variables
La variable ser local para el bloque en el que ha sido declarada y global para los
bloque hijos de ste, mientras que las variables declaradas en los bloque hijos no son
globales a los bloques padre.
<<l_Outer>>
DECLARE
v_AvailableFlag BOOLEAN;
v_SSN
NUMBER(9);
BEGIN
1
DECLARE
v_SSN
CHAR(11);
v_StartDate DATE;
BEGIN
2
v_AvailableFlag y
v_SSN son visibles
END;
3
END;
v_AvailableFlag y
v_SSN son visibles
del
-- Restriccin incorrecta
Sin embargo, hay una forma de evitar esta limitacin, declarando una variable ficticia
del tipo deseado (con la restriccin) y utilizando %TYPE en la definicin del subtipo:
DECLARE
v_DummyVar
NUMBER(4);
--Variable ficticia que no se usa
SUBTYPE t_LoopCounter IS v_DummyVar%TYPE;
-- Devuelve
NUMBER(4)
v_Counter
t_LoopCounter;
-- Declara una variable del subtipo
29
Las declaraciones de variables de un subtipo no restringido tambin pueden
restringir el tipo:
DECLARE
SUBTYPE t_Numeric IS NUMBER;
restringido
v_Counter is t_Numeric(5);
--
Define
un
subtipo
no
30
31
32
Y aqu hay algunas buenas noticias: Oracle hace que sea muy fcil escribir y
ejecutar sentencias SQL en PL/SQL. La mayor parte de las veces, simplemente
escribiremos las sentencias SQL directamente en nuestro bloque PL/SQL y despus
agregaremos el cdigo necesario para la interfaz entre las sentencias SQL y el cdigo
PL/SQL.
Supongamos, por ejemplo, que tenemos una tabla llamada empleados, con una
columna clave primaria id_empleado, y una columna apellido. Podemos ver el
apellido del empleado con ID 138, como sigue:
SELECT apellido
FROM empleados
WHERE id_empleado = 138
Ahora querramos ejecutar esta misma consulta dentro de nuestro bloque PL/SQL y
desplegar el nombre. Para hacer esto, necesitaremos copiar el apellido desde la
tabla a una variable local, lo cual podemos hacer con la clusula INTO:
DECLARE
v_apellido empleados.apellido%TYPE;
BEGIN
SELECT apellido
INTO v_apellido
FROM empleados
WHERE id_empleado = 138;
DBMS_OUTPUT.put_line(v_apellido);
END;
33
v_id_departamento empleados.id_departamento%TYPE := 10;
BEGIN
UPDATE empleados
SET salario = salario * 1.2
WHERE id_departamento = v_id_departamento;
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;
En este bloque, provemos los valores de las columnas como literales, en lugar de
variables, directamente dentro de la sentencia SQL.
34
35
Los loops se pueden anidar , se puede usar labels para distiguir entre loops
(<<label>>) se colocan antes de LOOP, se puede salir del loop con EXIT
referenciando el label, el label se puede incluir en el END LOOP por claridad
BEGIN
<<outer_loop>>
LOOP
EXIT WHEN v_count > 10
<<inner_loop>>
LOOP
EXIT outer_loop WHEN total = YES
EXIT inner_loop WHEN inner_done = YES
END LOOP inner_loop;
END LOOP outer_loop;
END;
36
37
Usando metodos de tablas PL/SQL
Table_name.method_name[(parameters)]
EXISTS(n)
COUNT
FIRST
LAST
PRIOR(n)
NEXT(n)
EXTEND(n,i) *
TRIM *
DELETE
38
Cursores explcitos
Procesa cada fila retornada por un SELECT de multiples filas. El grupo de filas
retornado es llamdo grupo activo, se guarda un rastro de cual es la fila corriente, el
programador lo controla manualmente.
Se usa OPEN ejcuta el query asociado, identifica el grupo activo y la posicin del
cursor , FETCH recupera la fila corriente y avanza el cursor a la proxima fila,
CLOSE deshabilita el cursor y libera lass filas.
CURSOR cursor_name IS
Select_statement;
39
Abriendo el cursor
OPEN cursor_name;
Dinamicamente asigna memoria para el rea de contexto, Parsea el SELECT, obtiene
posiciones de memoria de las variables de entrada, identifica el grupo activo,
posiciona el puntero justamente antes de la primera fila.
Si no retorna filas no se da una excepcin , perso se puede probar la salida con los
atributos del cursor.
Para cursores declarados FOR UPDATE, se bloquean las filas.
FETCH cursor_name INTO [variable1, ... | record_name ];
Recupera la fila corriente dentro de variables, incluye el mismo nmero de variables,
se debe probar el curosr para ver si contiene filas.
...
Open defined_cursor;
LOOP
FETCH defined_cursor INTO defined_variables;
EXIT WHEN ....;
END LOOP;
...
CLOSE cursor_name;
Se debe cerrar para liberar recursos, esta ligado con el parmetro OPEN_CURSORS.
Atributos : %ISOPEN , %NOTFOUND, %FOUND, %ROWCOUNT nmero de
filas que trae el cursor.
Toman los valores TRUE, FALSE o NULL dependiendo de la situacin:
Atributo
%NOTFOUND
%FOUND
%ISOPEN
%ROWCOUNT
Antes de abrir
ORA-1001
ORA-1001
FALSE
ORA-1001
Al
abrir
NULL
NULL
TRUE
0
Durante la
recuperacin
FALSE
TRUE
TRUE
*
Al finalizar la
recuperacin
TRUE
FALSE
TRUE
**
Despus de
cerrar
ORA-1001
ORA-1001
FALSE
ORA-1001
40
Hay implicitamente OPEN, FECTH y CLOSE. y el cursor es implcitamente
declarado.
Cursores en LOOPS que usan subqueries
No se necesita declarar el cursor, y no puede usar los atributos de cursor.
BEGIN
FOR em IN ( SELECT empno FROM emp )
LOOP
Sentencias;
END LOOP;
END;
El siguiente ejemplo ilustra el trabajo con un cursor explcito. Hay que tener en
cuenta que al leer los datos del cursor debemos hacerlo sobre variables del mismo
tipo de datos de la tabla (o tablas) que trata el cursor.
DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;
co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
CLOSE cpaises;
END;
41
Cursores de actualizacin
Los cursores de actualizacin se declaran igual que los cursores explcitos,
aadiendo FOR UPDATE al final de la sentencia select.
CURSOR nombre_cursor IS
instruccin_SELECT
FOR UPDATE
Para actualizar los datos del cursor hay que ejecutar una sentencia UPDATE
especificando la clusula WHERE CURRENT OF <cursor_name>.
UPDATE <nombre_tabla> SET
<campo_1> = <valor_1>
[,<campo_2> = <valor_2>]
WHERE CURRENT OF <cursor_name>
42
CURSOR_ALREADY_OPEN
DUP_VAL_ON_INDEX
INVALID_CURSOR
INVALID_NUMBER
Se ejecuta ...
SQLCODE
El programa intent asignar valores a los
-6530
atributos de un objeto no inicializado
El programa intent asignar valores a una
-6531
tabla anidada an no inicializada
El programa intent abrir un cursor que ya se
encontraba abierto. Recuerde que un cursor de
-6511
ciclo FOR automticamente lo abre y ello no
se debe especificar con la sentencia OPEN
El programa intent almacenar valores
duplicados en una columna que se mantiene
-1
con restriccin de integridad de un ndice
nico (unique index)
El programa intent efectuar una operacin
-1001
no vlida sobre un cursor
En una sentencia SQL, la conversin de una
cadena de carcteres hacia un nmero falla
-1722
cuando esa cadena no representa un nmero
43
vlido
El programa intent conectarse a Oracle con
LOGIN_DENIED
un nombre de usuario o password invlido
Una sentencia SELECT INTO no devolvi
valores o el programa referenci un elemento
NO_DATA_FOUND
no inicializado en una tabla indexada
El programa efectu una llamada a Oracle sin
NOT_LOGGED_ON
estar conectado
PL/SQL tiene un problema interno
PROGRAM_ERROR
Los elementos de una asignacin (el valor a
asignar y la variable que lo contendr) tienen
tipos incompatibles. Tambin se presenta este
ROWTYPE_MISMATCH
error cuando un parmetro pasado a un
subprograma no es del tipo esperado
El parmetro SELF (el primero que es pasado
SELF_IS_NULL
a un mtodo MEMBER) es nulo
La memoria se termin o est corrupta
STORAGE_ERROR
El programa est tratando de referenciar un
elemento de un arreglo indexado que se
SUBSCRIPT_BEYOND_COUNT
encuentra en una posicin ms grande que el
nmero real de elementos de la coleccin
El programa est referenciando un elemento
de un arreglo utilizando un nmero fuera del
SUBSCRIPT_OUTSIDE_LIMIT
rango permitido (por ejemplo, el elemento 1)
La conversin de una cadena de carcteres
hacia un tipo rowid fall porque la cadena no
SYS_INVALID_ROWID
representa un nmero
Se excedi el tiempo mximo de espera por
TIMEOUT_ON_RESOURCE
un recurso en Oracle
Una sentencia SELECT INTO devuelve ms
TOO_MANY_ROWS
de una fila
Ocurri un error aritmtico, de conversin o
truncamiento. Por ejemplo, sucede cuando se
VALUE_ERROR
intenta calzar un valor muy grande dentro de
una variable ms pequea
El programa intent efectuar una divisin por
ZERO_DIVIDE
cero
-1017
100
-1012
-6501
-6504
-30625
-6500
-6533
-6532
-1410
-51
-1422
-6502
-1476
DECLARE
E_emps EXCEPTION;
PRAGMA EXCEPTION INIT ( e_emps, -2292);
BEGN
....
EXCEPTION
WHEN e_emps THEN
....
END;
Funciones para atrapar excepciones
44
SQLCODE retorna el valor numerico del error 0 no hay excepcin, 1 excepcin
definida por el usuario, +100 NO_DATA_FOUND, nmero negativo otro error
Oracle
SQLERRM retorna el mensaje asociado
DECLARE
V_error_code NUMBER;
V_error_message VARCHAR2(255);
BEGN
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
V_error_code := SQLCODE;
V_error_message := SQLERRM;
END;
DECLARE
err_num NUMBER;
err_msg VARCHAR2(255);
result NUMBER;
BEGIN
SELECT 1/0 INTO result
FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SQLERRM;
DBMS_OUTPUT.put_line('Error:'||TO_CHAR(err_num));
DBMS_OUTPUT.put_line(err_msg);
END;
Tambin es posible entregarle a la funcin SQLERRM un nmero negativo que represente un error
de Oracle y sta devolver el mensaje asociado.
DECLARE
msg VARCHAR2(255);
BEGIN
msg := SQLERRM(-1403);
DBMS_OUTPUT.put_line(MSG);
END;
45
DECLARE
-- Declaramos una excepcion identificada por VALOR_NEGATIVO
VALOR_NEGATIVO EXCEPTION;
valor NUMBER;
BEGIN
-- Ejecucion
valor := -1;
IF valor < 0 THEN
RAISE VALOR_NEGATIVO;
END IF;
EXCEPTION
-- Excepcion
WHEN VALOR_NEGATIVO THEN
dbms_output.put_line('El valor no puede ser negativo');
END;
RAISE_APPLICATION_ERROR
En ocasiones queremos enviar un mensaje de error personalizado al producirse una
excepcin PL/SQL.
Para ello es necesario utilizar la instruccion RAISE_APPLICATION_ERROR;
La sintaxis general es la siguiente:
RAISE_APPLICATION_ERROR(<error_num>,<mensaje>);
Siendo:
DECLARE
v_div NUMBER;
BEGIN
SELECT 1/0 INTO v_div FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001,'No se puede dividir por cero');
END;
Ambientes llamados
SQL*Plus Despliega el nmero del error y el mensaje en la pantalla
Procedure builder
Oracle Developer Forms utiliza ERROR_CODE y ERROR_TEXT
Aplicacin precompilada accede al nmero de la excepcin atravez de SQLCA
Bloque PL/SQL atrapa la excepcin en el manejador de excepciones
RAISE_APPLICATION_ERROR (error_number, message[ , {TRUE | FALSE}]);
Permite usar mensajes de error definidos por el usuario
Error_number 20000 a 20999
TRUE | FALSE si TRUE los errores en la pila de los errores previos, FALSE el error
default reemplaza los errores previos. Se puede usar en la seccin ejecutable y la
seccin de excepciones.
DECLARE
fecha DATE;
FUNCTION fn_fecha RETURN DATE
IS
fecha DATE;
BEGIN
SELECT SYSDATE INTO fecha
FROM DUAL
WHERE 1=2;
RETURN fecha;
EXCEPTION
46
WHEN ZERO_DIVIDE THEN
dbms_output.put_line('EXCEPCION ZERO_DIVIDE CAPTURADA
EN fn_fecha');
END;
BEGIN
fecha := fn_fecha();
dbms_output.put_line('La fecha es '||TO_CHAR(fecha,
'DD/MM/YYYY'));
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('EXCEPCION NO_DATA_FOUND CAPTURADA EN
EL BLOQUE PRINCIPAL');
END;
47
48
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);
END;
Se
ejecuta
la
funcin
pExeSuiComercial
del
paquete
olbgenerainfosuicomer_48765. Se enva un mensaje de terminacin correcta y de
no ser as se enva el cdigo y mensaje de error respectivo.
BEGIN
olbgenerainfosuicomer_48765.pExeSuiComercial(7,
To_Date('01-04-2013','DD-MM-YYYY'),
To_Date('30-04-2013','DD-MM-YYYY'));
Dbms_Output.put_line('Proceso Ok');
EXCEPTION
WHEN Others THEN
Dbms_Output.put_line(SQLCODE || ':' || SQLERRM);
END;
Ejecutando el PL/SQL
Una vez que hemos escrito un bloque de cdigo PL/SQL ste se puede ejecutar.
Existen muchas herramientas para ejecutar cdigo PL/SQL. La ms bsica es
SQL*Plus, una interfaz de lnea de comandos para ejecutar sentencias SQL as como
bloques PL/SQL. La Figura 1 muestra un ejemplo de ejecucin del ms simple de los
bloques de ejemplo de nuestro Hola Mundo! en SQL*Plus.
SQL Tools
Oracle SQL Developer, de Oracle
Toad y SQL Navigator, de Quest Software
PL/SQL Developer, de Allround Automations
49
Cada herramienta ofrece, con algunas diferencias, ventanas y pasos para crear,
guardar, y ejecutar bloques PL/SQL, as como habilitar y deshabilitar la salida del
servidor.
Otra opcin de ejecucin es SQL Tools:
50
Con esto hemos extendido PL/SQL. Adems de llamar a los programas creados por
Oracle e instalados en la base de datos (como DBMS_OUTPUT.PUT_LINE),
podemos llamar a nuestro propio subprograma dentro de un bloque PL/SQL:
BEGIN
hola_mundo;
END;
Hemos escondido todos los detalles de cmo decir hola al mundo dentro del cuerpo
(body), o implementacin, de nuestro procedimiento. Ahora podemos llamar a este
procedimiento hola_mundo y mostrar el mensaje deseado sin tener que escribir la
llamada a DBMS_OUTPUT.PUT_LINE o averiguar la forma correcta de darle
formato al texto. Podemos llamar a este procedimiento desde cualquier lugar en
nuestra aplicacin. As que si alguna vez necesitamos cambiar ese texto, lo vamos a
hacer en un solo lugar, el nico punto de definicin de ese texto.
El procedimiento hola_mundo es muy simple. Tus procedimientos tendrn mucho
ms cdigo, y casi siempre tambin tendrn parmetros. Los parmetros pasan
informacin a los subprogramas, cuando stos son llamados, y es lo que permite crear
subprogramas ms flexibles y genricos. Se pueden usar en muchos contextos
diferentes.
He mencionado antes que algn da puede ser que desee mostrar "Hola Universo!"
en lugar de "Hola Mundo!". Podra hacer una copia de nuestro procedimiento
hola_mundo y cambiar el texto que se muestra:
CREATE OR REPLACE PROCEDURE hola_universo IS
l_mensaje VARCHAR2(100) := 'Hola Universo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
END hola_universo;
51
Podramos, sin embargo, terminar con las decenas de variantes del mismo
procedimiento hola, que hara muy difcil mantener nuestra aplicacin. Un enfoque
mucho mejor es analizar el procedimiento e identificar qu partes se mantienen
incambiadas (son estticas) cuando el mensaje tiene que cambiar y qu partes
cambian. Luego podemos pasar las partes que cambian como parmetros y tener un
procedimiento nico que se puede utilizar en diferentes circunstancias.
As que vamos a cambiar hola_mundo (y hola_universo) a un nuevo procedimiento,
hola_lugar:
CREATE OR REPLACE PROCEDURE hola_lugar (lugar_in IN VARCHAR2) IS
l_mensaje VARCHAR2(100);
BEGIN
l_mensaje := 'Hola ' || place_in;
DBMS_OUTPUT.put_line(l_mensaje);
END hola_lugar;
Justo despus del nombre del procedimiento, aadimos entre parntesis de apertura y
cierre, un nico parmetro. Podemos tener varios parmetros, pero cada parmetro de
la misma forma bsica:
nombre_de_parametro
modo_de_parametro
tipo_de_datos
52
Teniendo el cdigo necesario para construir el mensaje dentro de la funcin
hola_mensaje, podemos utilizar este mensaje de mltiples maneras. Podemos, por
ejemplo, llamar a la funcin para obtener el mensaje y asignrselo a una variable:
DECLARE
l_mensaje VARCHAR2(100);
BEGIN
l_mensaje := hola_mensaje('Universo');
END;
Nota que llamamos a la funcin hola_mensaje como parte de una sentencia PL/SQL
(en este caso, la asignacin de un texto a una variable). La funcin hola_mensaje
devuelve un string, por lo que se puede utilizar en lugar de un string en cualquier
sentencia ejecutable.
Tambin podemos volver a nuestro procedimiento hola_lugar y reemplazar el cdigo
utilizado para crear el string con una llamada a la funcin:
CREATE OR REPLACE PROCEDURE
hola_lugar(place_in IN VARCHAR2) IS
BEGIN
DBMS_OUTPUT.put_line(hola_mensaje(place_in));
END hola_lugar;
Aunque la lgica del mensaje hola es muy simple, demuestra el poder de asignar
nombres a una o ms sentencias ejecutables (un algoritmo) y luego referenciar el
algoritmo simplemente especificando el nombre y los parmetros requeridos.
Los bloques PL/SQL con nombre, permiten construir aplicaciones complejas que
pueden ser comprendidas y mantenidas con relativa fcilidad.
Sobre los nombres en una base Oracle
Ahora que ya se aprecia la importancia de asignar nombres a la lgica, es tiempo de
hablar sobre las reglas para los nombres (o, para ser ms precisos, identificadores)
tanto en PL/SQL como, de forma ms general, en una base Oracle.
Estas son las reglas para construir identificadores vlidos en una base Oracle:
El largo mximo es de 30 carcteres.
El primer carcter debe ser una letra, pero cada carcter despus del primero puede
ser una letra, un nmero (0 a 9), un signo de pesos ($), un guin bajo (_), o un
numeral (#). Todos los siguientes son identificadores vlidos:
hola_mundo
hola$mundo
hola#mundo
pero estos son invlidos:
1hola_mundo
hola%mundo
PL/SQL es case-insensitive (no es sensitivo a maysculas y minsculas) con
respecto a los identificadores. PL/SQL trata todos los siguientes como el mismo
53
identificador:
hola_mundo
Hola_Mundo
HOLA_MUNDO
Para ofrecer ms flexibilidad, Oracle permite evitar las restricciones de la segunda y
tercera regla, encerrando al identificador entre comillas dobles. Un quoted identifier
(identificador encerrado entre comillas) puede contener cualquier secuencia de
carcteres imprimibles excluyendo las comillas dobles; las diferencias entre
maysculas y minsculas sern adems preservadas. As, todos los siguientes
identificadores son vlidos y distintos:
"Abc"
"ABC"
"a b c"
Es muy raro encontrar identificadores entre comillas en cdigo PL/SQL; algunos
grupos de desarrollo los usan para conformar con sus convenciones de nombres o
porque encuentran que una mezcla de maysculas y minsculas resulta ms fcil de
leer.
Estas mismas reglas aplican a los nombres de los objetos de base de datos como
tablas, vistas y procedimientos, con una regla adicional: a menos que se encierren
entre comillas los nombres de estos objetos, Oracle los mantendr en maysculas.
As que cuando creamos un procedimiento como el que sigue:
CREATE OR REPLACE PROCEDURE hola_mundo IS
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END hola_mundo;
54
Captulo 26 Procedimientos
Procedimientos almacenados
Un procedimiento es un subprograma que ejecuta una accin especfica y que no
devuelve ningn valor. Un procedimiento tiene un nombre, un conjunto de
parmetros (opcional) y un bloque de cdigo.
La sintaxis de un procedimiento almacenado es la siguiente:
CREATE [OR REPLACE]
PROCEDURE <procedure_name> [(<param1> [IN|OUT|IN OUT] <type>,
<param2> [IN|OUT|IN OUT] <type>, ...)]
IS
-- Declaracion de variables locales
BEGIN
-- Sentencias
[EXCEPTION]
-- Sentencias control de excepcion
END [<procedure_name>];
55
Una vez creado y compilado el procedimiento almacenado podemos
ejecutarlo. Si el sistema nos indica que el procedimiento se ha creado con errores de
compilacin podemos ver estos errores de compilacion con la orden SHOW
ERRORS en SQL *Plus.
Existen dos formas de pasar argumentos a un procedimiento almacenado a la hora
de ejecutarlo (en realidad es vlido para cualquier subprograma). Estas son:
BEGIN
Actualiza_Saldo(200501,2500);
COMMIT;
END;
BEGIN
Actualiza_Saldo(cuenta => 200501,new_saldo
COMMIT;
END;
=> 2500);
nombre_prodecimiento;
56
Captulo 27 Funciones
Funciones en PL/SQL
Una funcin es un subprograma que devuelve un valor.
La sintaxis para construir funciones es la siguiente:
57
Para eliminar una funcion usamos:
DROP FUNCTION
nombre_funcion;
58
Captulo 26 Procedimientos
Por qu anidar bloques?
Podemos poner BEGIN antes de cualquier conjunto de una o ms sentencias
ejecutables seguidas de un END, creando un bloque anidado con esas sentencias. Hay
dos ventajas principales para hacer esto: (1) posponer la asignacin de memoria para
variables que se necesitan nicamente en el bloque anidado, y (2) limitar la
propagacin de una excepcin lanzada por una de las sentencias del bloque anidado.
Consideremos el siguiente bloque:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
l_mensaje2 VARCHAR2(100) := ' Mundo!';
BEGIN
IF SYSDATE >= TO_DATE('01-JAN-2012')
THEN
l_mensaje2 := l_mensaje1 || l_mensaje2;
DBMS_OUTPUT.put_line(l_mensaje2);
ELSE
DBMS_OUTPUT.put_line(l_mensaje1);
END IF;
END;
59
END;
DBMS_OUTPUT.put_line(l_mensaje1);
END;