Professional Documents
Culture Documents
3. VARIABLES
DECLARE
nombre_variable tipo_variable [NOT NULL] [:= expr | DEFAULT expr] ;
Ejemplos:
DECLARE
nombre_empleado VARCHAR2(30);
contador NUMBER(6) NOT NULL := 0 ;
porcentaje NUMBER(3) DEFAULT 16 ;
fecha_alta DATE DEFAULT sysdate ;
correcto BOOLEAN NOT NULL := TRUE ;
NOT NULL : Es opcional y restringe la variable para que tenga que contener
un valor no nulo. Las variables NOT NULL deben ser inicializadas
obligatoriamente.
Dos variables pueden tener el mismo nombre. Sí, habéis leído bien.
Siempre y cuando estén definidas en distintos bloques. Si se trata de
bloques anidados, la vigente es la definida en el bloque actual.
Pág 1 de 16
Curso de PL/SQL
Pág 2 de 16
Curso de PL/SQL
DECLARE
v_nombre EMPLEADOS.nombre%TYPE ;
DECLARE
v_balance NUMBER(7,2) ;
v_balance2 v_balance%TYPE := 10 ;
3.3.1 REGISTROS
Pág 3 de 16
Curso de PL/SQL
• Cada registro definido puede tener tantos campos como sea necesario.
• Se les pueden asignar valores iniciales y pueden definirse como NOT
NULL.
• Los campos sin valores iniciales se rellenan con NULL.
• Podemos usar también la palabra clave DEFAULT.
• Podemos definir el tipo registro (RECORD) y declarar variables de de ese
tipo dentro de la parte de declaraciones de cualquier bloque,
subprograma ó paquete.
• Un registro puede formar parte de otro registro.
DECLARE
TYPE tipo_reg_empleado IS RECORD (nom EMPLEADOS.nombre%TYPE,
dep EMPLEADOS.departamento%TYPE) ;
registro_empleado tipo_reg_empleado ;
nombre_registro.nombre_campo
Por ejemplo:
DECLARE
TYPE tipo_reg_empleado IS RECORD (nom EMPLEADOS.nombre%TYPE,
dep EMPLEADOS.departamento%TYPE) ;
registro_empleado tipo_reg_empleado ;
Pág 4 de 16
Curso de PL/SQL
BEGIN
....
....
registro_empleado.nom := 'Pepe' ;
registro_empleado.dep := 10;
....
....
END;
DECLARE
TYPE tipo_reg_empleado IS RECORD (fila EMPLEADOS%ROWTYPE) ;
reg_empleado tipo_reg_empleado ;
DECLARE
reg_empleado EMPLEADOS%ROWTYPE ;
nombre_registro.nombre_campo
Este método tiene la misma ventaja que el atributo %TYPE para las
variables. Es decir: si cambiamos la estructura de la tabla referenciada,
añadiéndole o quitándole campos, las definiciones de variables quedan
inalterables. Lo malo es que en el código sí tendremos que “retocar” esos
cambios, ya que deberemos referenciar los nuevos campos ó eliminar las
referencias a los campos eliminados. Pero algo es algo ¿no?.
Pág 5 de 16
Curso de PL/SQL
DECLARE
reg_empleado EMPLEADOS%ROWTYPE ;
BEGIN
SELECT * INTO reg_empleados FROM EMPLEADOS ;
....
....
END;
• Una clave primaria del tipo de datos BINARY_INTEGER que indexa la tabla
PL/SQL
• Una columna de un tipo de datos escalar o de registro, que almacena los
elementos de la tabla PL/SQL.
DECLARE
TYPE tipo_tabla_fechas IS TABLE OF DATE INDEX BY BINARY_INTEGER ;
tabla_fechas tipo_tabla_fechas ;
DECLARE
TYPE tipo_tabla_fechas IS TABLE OF DATE INDEX BY BINARY_INTEGER ;
tabla_fechas tipo_tabla_fechas ;
BEGIN
tabla_fechas(1) := sysdate ;
tabla_fechas(2) := TO_DATE('01/01/2004','DD/MM/RRRR') ;
....
....
END ;
Pág 6 de 16
Curso de PL/SQL
DECLARE
TYPE tipo_tabla_reg_dep IS TABLE OF DEPARTAMENTOS%ROWTYPE
INDEX BY BINARY_INTEGER ;
tabla_dep tipo_tabla_reg_dep ;
tabla_dep(indice).campo
4. CURSORES
Pág 7 de 16
Curso de PL/SQL
Pág 8 de 16
Curso de PL/SQL
SI
DECLARE ---> OPEN ---> FETCH ---> ¿VACIO? -------> CLOSE
^ |
|___________| NO
DECLARE
v_codigo EMPLEADOS.codigo%TYPE ;
v_nombre EMPLEADOS.nombre%TYPE ;
1 Pepito Boss
2 Manolito Programmer <---- puntero actual
25 Juanito Administrator
4 Luisito Perez
Pág 9 de 16
Curso de PL/SQL
DECLARE
CURSOR c_empleados IS SELECT codigo, nombre
FROM EMPLEADOS
WHERE departamento=3 ;
reg_empleado c_empleados%ROWTYPE ;
BEGIN
OPEN c_empleados ;
..
FETCH c_empleados INTO reg_empleado ;
..
END;
Pág 10 de 16
Curso de PL/SQL
5. ESTRUCTURAS DE CONTROL
IF – THEN
IF – THEN – ELSE
IF – THEN – ELSIF
La sintaxis es:
IF condicion THEN
sentencias ;
[ELSIF condicion THEN
sentencias ;]
[ELSE
sentencias ;
END IF] ;
IF v_departamento = 10 THEN
v_jefe := 1 ;
v_sueldo := 2000 ;
ELSE
v_sueldo := 1000 ;
END IF;
Pág 11 de 16
Curso de PL/SQL
IF v_departamento = 10 THEN
v_jefe := 1 ;
v_sueldo := 2000 ;
ELSIF v_departamento = 20 THEN
v_jefe := 2 ;
v_sueldo := 1500 ;
ELSE
v_sueldo := 1000 ;
END IF;
Bucle básico: La forma más simple. Utilizaremos el LOOP – END LOOP. Sin
una sentencia EXIT, el bucle sería infinito.
Sintaxis:
LOOP
sentencia1 ;
sentencia2 ;
...
...
EXIT [WHEN condicion] ;
END LOOP ;
Pág 12 de 16
Curso de PL/SQL
DECLARE
v_contador NUMBER(2):= 1 ;
BEGIN
LOOP
INSERT INTO DEPARTAMENTOS
VALUES(v_contador,'Departamento '||TO_CHAR(v_contador));
v_contador := v_contador + 1 ;
EXIT WHEN v_contador > 10 ;
END LOOP ;
END;
Bucle FOR: Los bucles FOR tienen la misma estructura general que el bucle
básico. Además tiene una sentencia de control delante de la palabra clave
LOOP para determinar el número de repeticiones.
Sintaxis:
FOR indice IN [REVERSE] n..m LOOP
sentencia1 ;
sentencia2 ;
...
...
END LOOP ;
REVERSE: Hace que el índice disminuya con cada iteración desde el límite
superior al límite inferior.
n: Límite inferior
m: Límite superior
DECLARE
n NUMBER := 1 ; m NUMBER := 100 ;
suma NUMBER(5) := 0 ;
suma2 NUMBER(5) := 0 ;
BEGIN
FOR i IN n..m LOOP
suma := suma + i ;
END LOOP ;
FOR i IN REVERSE n..m LOOP
suma2 := suma2 + i ;
END LOOP ;
END;
Pág 13 de 16
Curso de PL/SQL
Sintaxis:
WHILE condicion LOOP
sentencia1;
sentencia2;
....
....
END LOOP ;
Ejemplo:
DECLARE
i NUMBER := 100 ;
j NUMBER := 1 ;
BEGIN
WHILE i<>j LOOP
i := i - 1 ;
j := j + 1 ;
END LOOP;
END ;
Para finalizar con los bucles, decir que se pueden anidar sin ningún
problema y de distinto tipo, claro. Nombraré de pasada que los bucles se
pueden “etiquetar” para hacer un EXIT etiqueta en caso de que tengamos
bucles anidados, pero no es algo que me guste ya que se puede implementar
mediante código estructurado. Si a alguien le interesa me puede preguntar
o ya sabéis: http://www.google.com
Pág 14 de 16
Curso de PL/SQL
DECLARE
CURSOR c_empleados IS SELECT codigo, nombre
FROM EMPLEADOS
WHERE departamento=3 ;
reg_empleado c_empleados%ROWTYPE ;
BEGIN
--- Si no está abierto el cursor, lo abrimos.
--- Esto se hace por precaución.
IF NOT c_empleados%ISOPEN THEN
OPEN c_empleados ;
END IF;
--- Bucle básico
LOOP
-- Recuperamos datos y adelantamos el cursor.
FETCH c_empleados INTO reg_empleado ;
DECLARE
CURSOR c_empleados IS SELECT codigo, nombre
FROM EMPLEADOS
WHERE departamento=3 ;
BEGIN
--- Bucle FOR de cursor
FOR fila IN c_empleados LOOP
... sentencias para tratar los datos
END LOOP;
END;
Pág 15 de 16
Curso de PL/SQL
BEGIN
--- Bucle FOR de cursor
FOR fila IN (SELECT codigo, nombre
FROM EMPLEADOS
WHERE departamento=3) LOOP
... sentencias para tratar los datos
END LOOP;
END;
Vaya, pues hemos dejado el código en nada o casi nada. (Ya dije que
yo utilizaba los bucles FOR para los cursores, ¿verdad?).
Para terminar, recordaros que la SELECT del cursor puede ser todo lo
compleja que queráis, pudiendo utilizar tablas y vistas. Yo os he puesto
SELECT's muy sencillitas pero en el siguiente capítulo (“Conceptos
avanzados de cursores explícitos”) donde veremos, entre otras cosas, los
cursores con parámetros, ya pondremos más “tela”.
Pág 16 de 16