9 PL SQL 100513155207 Phpapp02
9 PL SQL 100513155207 Phpapp02
PL-SQL
PL-SQL
SQL es un lenguaje de consulta para los
sistemas de bases de datos relacinales,
pero que no posee la potencia de los
lenguajes de programacin. Cuando se
desea realizar una aplicacin completa para
el manejo de una base de datos relacional,
resulta necesario utilizar alguna herramienta
que soporte la capacidad de consulta del
SQL y la versatilidad de los lenguajes de
programacin tradicionales. PL/SQL es el
lenguaje de programacin que proporciona
Oracle para extender el SQL estndar con
otro tipo de instrucciones.
BENEFICIOS
MODULARIDAD
INTEGRACION CON
HERRAMIENTAS
PORTABILIDAD
MANEJO DE EXCEPCIONES
ESTRUCTURA DE PL/SQL
Los bloques PL/SQL presentan una
estructura especfica compuesta de tres
partes bien diferenciadas:
La seccin declarativa en donde se
declaran todas las constantes y
variables que se van a utilizar en la
ejecucin del bloque.
La seccin de ejecucin que incluye las
instrucciones a ejecutar en el bloque
PL/SQL.
La seccin de excepciones en donde se
definen los manejadores de errores que
soportar el bloque PL/SQL.
Cada una de las partes anteriores se delimita por una
palabra reservada, de modo que un bloque PL/SQL se
puede representar como sigue:
DECLARE
/* Parte Declarativa */
BEGIN
/* Parte de Ejecucin */
EXCEPTIONS
/* Parte de Excepciones */
END;
De las anteriores, nicamente la seccin de ejecucin es
obligatoria, que quedara delimitada entre las clusulas
BEGIN y END
TIPOS DE BLOQUES
ANONYMO
US
[DECLARE]
BEGIN
--Instruccin
[EXCEPTION
]
END;
PROCEDU
RE
PROCEDUR
E name is
BEGIN
--Instruccion
[EXCEPTION
END;
FUNCTION
FUNCTION
name
RETURN
datatype IS
BEGIN
--Instruccion
RETURN
value;
[EXCEPTION]
END;
Declarando variables
Uso de Variables
Almacenar datos temporalmente
Manipular los valores almacenados
Reusabilidad
Declarar e Inicializar variable
Sintaxis:
Identificador [CONSTANT] datatype
[NOT NULL] [:=] | DEFAULT
expresion;
Tipos
CHAR [(longitud maxima)]
VARCHAR2(longitud maxima)
LONG
LONG RAW
NUMBER [(precision,escala)]
BINARY_INTEGER
PLS_INTEGER
BOOLEAN
BINARY_FLOAT
BINARY_DOUBLE
%type
El atributo %Type
- Es usado para declarar una variable de
acuerdo a :
* una columna definida en una base de datos
* otra variable declarada.
- Es prefijo con:
* La columna y la tabla de la base de datos
* El nombre de la variable declarada.
Sintaxis:
identificador tabla.columna_nombre%TYPE;
Declarando Boolean
Solo los valores TRUE, FALSE y
NULL pueden asignarse a una
variable boolean.
DECLARE
flag BOOLEAN := FALSE;
BEGIN
flag := TRUE;
END;
Declarando Variable ligadas e
imprimiendo
Creadas en el ambiente
Son llamadas en caliente
Son creadas con VARIABLE
Usadas en instrucciones SQL y bloques de PL/SQL.
VARIABLE nombre_name NUMBER
BEGIN
SELECT nombre INTO :nombre
FROM clientes WHERE RFC =DINA;
END;
/
PRINT nombre_name
Unidades lexicas
Delimitadores
+ Operador de agregacin.
- Resta o operador de negacin
* Operador de Multiplicacin
/ Operador de divisin
= Operador de igualdad
@ Indicador de acceso remoto
; Terminacin de instruccin
Smbolos compuesto
<> Operador de desigualdad
!= Operador de desigualdad
|| Operador de concatenacin
-- Indicador de linea comentada
/* Inicio de comentario
*/ Terminacin de comentario
:= Operador de asignacin
FUNCIONES DE SQL en
PL/SQL
Funciones de numricas con un solo
registro
De carcter con solo un registro
Conversin de tipos de datos
Fecha
Timestamp
Varias
Decode
Grupo
OPERADORES
** Potencia
+, - Suma y negacin
*, / Multiplicacin y Divisin
=, <, >, <=, >=, <>, !=, is null, like,
between, in comparacin.
Not negacin lgica
And Conjuncin
Or Disyuncin
Instruccin de SELECT
Carga datos desde la base de datos con un
Select.
SELECT select_list
INTO { variable_name [, variable_name]
| record_name}
FROM table
[WHERE condicin];
Manipulacin de datos
Puede hacer cambios a las tablas de
la base de datos usando DM.
INSERT
UPDATE
DELETE
CURSORES
Un cursor es un punto en el rea de la
memoria privada del servidor de
oracle.
Esta tiene dos tipos de cursores:
1. Cursores implcitos: Creados y
administrados internamente por el
servidor de oracle cuando se ejecuta la
instruccin.
2. Cursores Explcitos: Declarados
explcitamente por el programador.
Atributos para cursores implicitos
SQL%Found
SQL%NOTFOUND
SQL%ROWCOUNT
SENTENCIAS DE CONTROL
DE FLUJO
En PL/SQL es posible ejecutar un bloque de
instrucciones u otro en funcin del valor de alguna
expresin lgica, mediante la utilizacin de la sentencia
IF:
IF expresin_lgica THEN intrucciones_PL/SQL;
[ELSIF expresin_lgica THEN intrucciones_PL/SQL;]
[ELSE intrucciones_PL/SQL;]
END IF;
Tal y como aparece en la sintaxis de esta sentencia, se
pueden presentar diferentes alternativas, aunque al
menos deben presentarse las clusulas IF ... THEN ...
END IF.
INSTRUCCIN CASE
CASE selector
WHEN expression1 THEN
statement1
statement2
..
WHEN expression2 THEN
statement1
statement2
..
[ELSE
statement1
statement2
..
]
END CASE;
CASE EXPRESION
Variable_name :=
CASE selector
WHEN expression1 THEN result1
WHEN expression2 THEN result2
...
WHEN expressionN THEN resultN
[ELSE resultN+1]
END;
BUCLES
LOOP
intrucciones_PL/SQL
EXIT [WHEN expresin_lgica];
END LOOP;
WHILE expresin_lgica LOOP
intrucciones_PL/SQL
END LOOP;
FOR ndice IN [REVERSE] expr_entera .. expr_entera LOOP
intrucciones_PL/SQL
END LOOP;
FOR variable_fila IN cursor | variable_fila IN sentencia_SQL
LOOP
intrucciones_PL/SQL
END LOOP;
Tipos de Datos Estructurados
Entre los tipos de datos estructurados que proporciona PL/SQL estn los
registros (RECORD) y los vectores (TABLE y VARRAY). Todos ellos se
declaran en la seccin DECLARE.
Para declarar un tipo registro se emplea la siguiente sintaxis:
TYPE nombre_tipo IS RECORD (campo [, campo] ...);
TYPE tipo_empleado_reg IS RECORD(
nombre VARCHAR2(10),
puesto VARCHAR2(8),
sueldo NUMBER(6));
v_empleado_reg tipo_empleado_reg;
Alternativamente se puede indicar que el tipo de la variable sea el de los
registros de una tabla existente:
v_empleado_reg empleado%ROWTYPE;
Para declarar los vectores se emplea la siguiente
sintaxis:
TYPE nombre_tipo IS VARRAY (tamao_maximo) OF
tipo_datos [NOT NULL];
TYPE nombre_tipo IS TABLE OF tipo_datos [NOT NULL];
En ambos casos los ndices se empiezan a contar
a partir de 1, y para poder utilizar los vectores,
deben ser previamente creados vacos o con
elementos. A partir de entonces para insertar
elementos adicionales se tienen que extender,
como muestra el siguiente ejemplo:
DECLARE
TYPE t_varray IS VARRAY (50) OF empleado.nombre%TYPE;
v_varray1 t_varray;
v_varray2 t_varray;
BEGIN
...
v_varray1 := t_varray(Ana, Lola);-- se crea con dos elementos
v_varray1.EXTEND;
v_varray1(3) := Luis;
-- v_varray1(4) := Juan; Esto sera un error porque no se ha
extendido
v_varray2 := t_varray(); -- se crea vaco
IF v_varray2 IS NULL THEN
v_varray2 := v_varray1; --asignacin de vectores
END IF;
....
END;
Una diferencia que hay entre TABLE y
VARRAY es que en el primer caso el vector
puede crecer ilimitadamente, pero en el
segundo caso solo puede crecer hasta el
tamao mximo definido. Otra diferencia es
que en los tipos VARRAY no se pueden
borrar elementos, por lo que sus posiciones
se deben ocupar consecutivamente. Sin
embargo, en los tipos TABLE se pueden
borrar elementos con la instruccin DELETE,
pudiendo quedar huecos intermedios vacos
y sin poderse referenciar, aunque se pueden
volver a llenar con una asignacin. La
funcin EXISTS nos permite saber si un
elemento se puede referenciar o ha sido
borrado.
DECLARE
TYPE t_table IS TABLE OF empleado.nombre%TYPE;
v_table1 t_table;
v_table2 t_table;
BEGIN
...
v_table1 := t_table(Ana, Lola);
v_table1(2) := NULL; --Dejar una posicin vaca no es igual que borrarla
v_table1.DELETE(1);--As es como se borra una posicin
v_table1.EXTEND;
v_table1(3) := Luis;
-- v_table1(4) := Juan; Esto sera un error porque no se ha extendido
v_table2 := t_table();
IF v_table1(1).EXISTS THEN ...;
ELSE v_table1(1) := Pepe; --se vuelve a crear el elemento 1
END IF;
...
END;
Algunos de los mtodos predefinidos para manejar vectores son: EXISTS, COUNT, FIRST,
LAST,
PRIOR, NEXT, EXTEND, TRIM, DELETE.
CURSORES EXPLICITOS
En un cursor explicito se tiene que
realizar los siguientes pasos:
DECLARAR
ABRIR
CARGAR ACTUAL REGISTRO DENTRO
DE VARIABLES
VER SI EXISTEN MAS REGISTROS Y SI
EXISTEN RETORNAR A CARGAR OTRO
REGISTRO
CERRAR
DECLARE
CURSOR emp_cursor IS
SELECT EMPLEADO_ID, NOMBRE FROM
TRABAJADORES;
EMPNO TRABAJADOR.EMPLEADO_ID%TYPE;
NOMBRE TRABAJADOR.NOMBRE%TYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO empno, nombre;
EXIT WHEN emp_cursor%NOTFOUND;
Dbms_output.put_line(empno|| ||nombre);
END LOOP;
.
END;
CURSORES CON FOR
LOOPS
FOR name_registro IN name_cursor
LOOP
Instruccin;
Instruccin;
END LOOP;
ATRIBUTOS CURSORE
EXPLICITOS
%ISOPEN, BOOLEAN
%NOTFOUND, BOOLEAN
%FOUND, BOOLEAN
%ROWCOUNT, NUMERICO
CURSORES CON
PARAMETROS
CURSOR nombre_cursor
[(parameter_name tipo_dato, ..)]
IS instruccin_select;
OPEN
nombre_cursor(parameter_value,);
LA CLAUSULA FOR UPDATE
SELECT .
FROM .
FOR UPDATE [ OF columna_referencia]
[NOWAIT | WAIT n];
Bloquea el acceso a otra sessin
mientras dura la transaccin.
Bloquea los registros antes de actualizar
o borrar;
EXCEPCIONES
El manejo de excepciones es muy importante en el
dilogo con los sistemas de gestin de bases de datos,
ya que permite responder ante cualquier problema que
pueda ocurrir en la ejecucin de cualquier operacin.
Por defecto, la ejecucin de la aplicacin finaliza al
presentarse algn error grave, pero con la definicin de
manejadores especficos es posible realizar una serie
de acciones y continuar la ejecucin de la aplicacin.
WHEN excepciones THEN instrucciones_PL/SQL;
Donde excepciones: excep_mltiples | OTHERS
Donde excep_mltiples: excepcin | excepcin OR
excep_mltiples
La activacin de una excepcin la realiza el
sistema, cuando se produce un error interno, o el
programa mediante utilizacin de la sentencia
RAISE:
RAISE excepcin_vlida;
donde se entiende por excepcin vlida a
cualquier excepcin predefinida o a una
excepcin definida en la parte declarativa del
bloque PL/SQL. Cuando una excepcin se
activa, la ejecucin contina en la parte de
manejadores de excepciones si la hubiera, en
caso contrario se finaliza la ejecucin del bloque
y se mantiene la excepcin por si tuviera que ser
tratada en otro nivel. En la parte de
manejadores.
Existe un conjunto de excepciones predefinidas por Oracle cuyos
nombres aparecen a continuacin agrupados por su funcionalidad.
NO_DATA_FOUND, TOO_MANY_ROWS. Ocurren cuando un
select no selecciona nada o selecciona varias filas cuando slo se
esperaba una.
INVALID_NUMBER, VALUE_ERROR, ZERO_DIVIDE,
DUP_VAL_ON_INDEX. Las tres primeras situaciones se producen
por operaciones invalidas de tratamiento de nmeros, y la ultima
cuando se intenta insertar una clave primaria duplicada.
CURSOR_ALREADY_OPEN, INVALID_CURSOR. La primera
situacin ocurre al intentar abrir un cursor ya abierto, y la segunda al
intentar hacer una operacin invalida sobre un cursor
PROGRAM_ERROR, STORAGE_ERROR,
TIMEOUT_ON_RESOURCE. Detectan errores de almacenamiento
o de ejecucin.
Estas excepciones pueden aparecer incluso en la parte de
declaracin, si se intenta inicializar una variable con un valor no
permitido.
DECLARE
e_hay_emp EXCEPTION;
v_depnum departamento.depnum%TYPE := 777;
BEGIN
IF (SELECT COUNT(*) FROM empleados WHERE depnum = v_depnum)=0
THEN DELETE FROM departamento WHERE depnum = v_depnum;
ELSE RAISE e_hay_emp;
END IF;
COMMIT;
EXCEPTION
WHEN e_hay_emp THEN
RAISE_APPLICATION_ERROR(-20001, No se puede borrar el departamento ||
TO_CHAR(v_depnum)|| ya que tiene empleados.);
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(abortado por error
desconocido);
END;
Funciones y Procedimientos
Los bloques PL/SQL se pueden almacenar como
objetos de la base de datos para ser ejecutados
repetidamente. Los parmetros de entrada y salida
permiten comunicarse con los procedimientos o
funciones. Para ejecutarlos se invocan por su nombre
con el comando EXECUTE, aunque previamente deben
ser compilados con el comando START. Para depurar
los errores de compilacin se puede utilizar el comando
SHOW ERRORS. Para conocerlos se pueden utilizar
dos vistas del diccionario de datos user_objects y
user_source, y para borrarlos se utiliza los comandos
DROP PROCEDURE nombre_procedimiento o DROP
FUNCTION nombre_funcion.
La sintaxis de definicin de funciones y procedimientos
es como sigue:
CREATE [OR REPLACE] FUNCTION nombre_funcion
(argumento1 [modo1] tipodato1, argumento2 [modo2]
tipodato2, ...) RETURN tipodato IS|AS
-- declaracion de variables
BEGIN
Bloque PL/SQL;
RETURN valor_retorno
END; mode =
IN, OUT, IN OUT
CREATE [OR REPLACE] PROCEDURE
Nombre_procedimiento(argumento1 [modo1] tipodato1,
argumento2 [modo2] tipodato2, ...) IS|AS
-- declaracion de variables
BEGIN
Bloque PL/SQL;
END;
El tipo de un parmetro no puede
tener restricciones de tamao y su
modo por defecto es IN, aunque
tambin se puede definir como OUT o
IN OUT. Si no hay parmetros, se
omiten los parntesis. Las funciones
devuelven siempre un valor con la
instruccin RETURN, aunque pueden
devolver ms valores con parmetros
de tipo OUT. En el bloque PL/SQL
asociado a un procedimiento o funcin
se debe omitir la palabra DECLARE.
TRIGGERS
El siguiente diagrama resume la sintaxis para
la creacin de disparadores (triggers) en
Oracle.
CREATE [OR REPLACE] TRIGGER trigger
{BEFORE | AFTER | INSTEAD OF}
[DELETE] [OR INSERT] [OR UPDATE [OF
columna [,columna]] ON tabla | vista
[REFERENDING [OLD [AS] old] [NEW [AS]
new]]
[FOR EACH {ROW | STATEMENT}]
[WHEN condicin]
Bloque PL/SQL
Para declarar el disparador, despus de su nombre, hay que
indicar si se tiene que ejecutar antes, despus o en lugar de
la ejecucin de la sentencia SQL (delete, insert, update) que
ha causado su disparo. Un mismo disparador puede tener
varios sucesos asociados, y una instruccin SQL slo se
corresponde con un suceso, aunque afecte a varias tuplas.
Para diferenciar dentro del bloque PL/SQL cul de los
posibles sucesos es el que ha activado al disparador, se
pueden utilizar los predicados condicionales INSERTING,
UPDATING y DELETING.
IF INSERTING THEN
v_valor := I;
ELSIF UPDATING THEN
v_valor := U;
ELSE
v_valor := D;
END IF;
A continuacin va la palabra ON y el nombre
de la tabla a la que se asocia el disparador.
La clusula REFERENCING sirve para
asignar alias a las variables externas old y
new, las cuales almacenan respectivamente
los valores de una tupla antes y despus de
ejecutar sobre ella la instruccin que lanza al
disparador. Sin embargo, estas variables
solamente se pueden utilizar cuando se
escoge la opcin de ejecutar el disparador
tupla por tupla (for each row), es decir
ejecutarlo separadamente para cada una de
las tuplas afectadas por la instruccin SQL
que ha activado al disparador.
En el caso de que el disparador se tenga que ejecutar una sola vez
para la instruccin que causa su disparo (for each statement),
entonces las variables old y new no se pueden utilizar, ya que la
instruccin puede afectar a varias tuplas. La clusula optativa
WHEN sirve para especificar una condicin adicional que debe
cumplirse para que el cuerpo del disparador sea ejecutado. El
cuerpo del disparador consiste en un bloque PL/SQL.
Para activar un disparador se tiene que compilar con xito, y se
puede desactivar con la instruccin siguiente:
ALTER TRIGGER nombre_disparador [DISABLE|ENABLE]
Para borrar un disparador se ejecuta la accin:
DROP TRIGGER nombre_disparador
Para consultar la informacin de los disparadores se puede ejecutar
la siguiente consulta sobre el diccionario de datos:
SELECT trigger_type, table_name, triggering_event
FROM user_triggers
WHERE trigger_name = ...;
Paquetes
Un paquete es una estructura PL/SQL que
permite almacenar juntos una serie de
objetos relacionados. Un paquete tiene dos
partes bien diferenciadas, la especificacin y
el cuerpo del paquete, los cuales se
almacenan por separado en el diccionario de
datos. Dentro de un paquete se pueden
incluir procedimientos, funciones, cursores,
tipos y variables. Posteriormente, estos
elementos se pueden referenciar desde otros
bloques PL/SQL, con lo que los paquetes
permiten disponer de variables globales en
PL/SQL.
CREATE [OR REPLACE] PACKAGE
nombre_paquete IS|AS
especificacin de procedimiento o funcion
|declaracin de variable
|declaracin de tipo
|declaracin de excepcion
|declaracin de cursor
END nombre_paquete;
CREATE [OR REPLACE] PACKAGE BODY
nombre_paquete IS|AS
cuerpos de procedimiento o funcion
[BEGIN instruccin de inicializacin]
END nombre_paquete;