Sql

29
2 2011 Erwin Fischer Bases de Datos Unidad El Lenguaje PL/SQL

Transcript of Sql

Page 1: Sql

22011 Erwin Fischer

Bases de Datos

Unidad

El Lenguaje PL/SQL

Page 2: Sql

32011 Erwin Fischer

PL/SQL

• Es una extensión procedimental de SQL diseñada por Oracle

• Se basa en conceptos similares a los lenguajes de programación modernos. (declaracion de

variables y constantes, estructuras de control, manejo de excepciones y modularización).

• Es un lenguaje con estructura de bloques: Los bloques pueden ser completamente independientes o estar anidados uno dentro de otros

• Las unidades básicas son : Procedimientos, funciones y bloques anonimos.

Page 3: Sql

42011 Erwin Fischer

Estructura general de un bloque PL/SQL

[DECLARE

- declaraciones]

Opcional

BEGIN

- instrucciones ejecutables

Obligatorio

[EXCEPTION

- rutinas de manejo de excepciones]

Opcional

END; Obligatorio

Page 4: Sql

52011 Erwin Fischer

Declaraciones en PL/SQL

• Las variables y constantes deben declararse antes de

poder referenciarlas.

• Ej:

– vNumEmpleado VARCHAR2(5);

– vRenta NUMBER(6,2) NOT NULL := 600;

– MAX_PROPIEDADES CONSTANT NUMBER := 100

• Es posible declarar variables de acuerdo al tipo de

otras variables

• vNumEmpleado Empleado.numEmpleado%TYPE;

• vNumEmpleado1 vNumEmpleado%TYPE;

• beerTuple Beers%ROWTYPE;

Page 5: Sql

62011 Erwin Fischer

Asignaciones en PL/SQL

• Se pueden asignar variables de dos formas

distintas: Utilizando (:=) o como resultado de

una instrucción SELECT o FETCH

• Ej:

– vNumEmpleado := ‘SG14’;

– vRenta := 500;

– SELECT COUNT(*) INTO XFROM Propiedad

WHERE numEmpleado = vNumEmpleado;

Page 6: Sql

72011 Erwin Fischer

Un programa Simple en PL/SQL

drop table T1; // Se elimina la tabla en caso que exista, si no existe da un error, pero no importa

CREATE TABLE T1(

e INTEGER,

f INTEGER

);

Begin

DELETE FROM T1;

INSERT INTO T1 VALUES(1, 3);

INSERT INTO T1 VALUES(2, 4);

End

select * from t1

/* Lo de arriba es SQL; debajo es el programa PL/SQL */

DECLARE

a NUMBER;

b NUMBER;

BEGIN

SELECT e,f INTO a,b

FROM T1

WHERE e>1;// Este select asigna el atributo e->a y f->b, de todos aquellos registros cuyo atributo e > 1

INSERT INTO T1 VALUES(b,a);

END;

Page 7: Sql

82011 Erwin Fischer

Veamos que ocurre 1

• Se crea la tabla t1 y se insertan dos registros.

Page 8: Sql

92011 Erwin Fischer

El procedimiento anónimo

DECLARE

a NUMBER;

b NUMBER;

BEGIN

SELECT e,f INTO a,b

FROM T1

WHERE e>1

INSERT INTO T1 VALUES(b,a);

END;

select * from t1

select * from t1

Page 9: Sql

102011 Erwin Fischer

¿Qué ocurre si ejecuto nuevamente el procedimiento anónimo?

• Escribir en el Blog, una explicación a lo que ocurre al ejecutar nuevamente el procedimiento:

DECLARE

a NUMBER;

b NUMBER;

BEGIN

SELECT e,f INTO a,b

FROM T1

WHERE e>1

INSERT INTO T1 VALUES(b,a);

END;

select * from t1

Page 10: Sql

112011 Erwin Fischer

Instrucciones de Control en PL/SQL

• PL/SQL soporta los mecanismos

habituales de control de flujo condicional,

iterativo y secuencial

• IF-THEN-ELSE-END IF;

• LOOP-EXIT WHEN-END LOOP;

• FOR-END LOOP;

• WHILE-END LOOP;

• GOTO;

Page 11: Sql

122011 Erwin Fischer

Instrucción IF

Syntax #1: IF-THEN

IF condition THEN

{...statements...}

END IF;

Syntax #2: IF-THEN-ELSE

IF condition THEN

{...statements...}

ELSE

{...statements...}

END IF;

Syntax #3: IF-THEN-ELSIF

IF condition THEN

{...statements...}

ELSIF condition THEN

{...statements...}

ELSE

{...statements...}

END IF;

Page 12: Sql

132011 Erwin Fischer

Un programa Simple en PL/SQL

DECLARE

a NUMBER;

b NUMBER;

BEGIN

SELECT e,f INTO a,b FROM T1 WHERE e>1;

IF b=1 THEN

INSERT INTO T1 VALUES(b,a);

ELSE

INSERT INTO T1 VALUES(b+10,a+10);

END IF;

END;

Page 13: Sql

142011 Erwin Fischer

¿Qué hace este Procedimiento anónimo?

DECLARE

a NUMBER;

b NUMBER;

BEGIN

SELECT e,f INTO a,b FROM T1 WHERE e>1;

IF b=1 THEN

INSERT INTO T1 VALUES(b,a);

ELSE

INSERT INTO T1 VALUES(b+10,a+10);

END IF;

END;

select * from t1

Page 14: Sql

152011 Erwin Fischer

Instrucción Loop

LOOP

{.statements.}

END LOOP;

Ejemplo

LOOP

monthly_value := daily_value * 31;

EXIT WHEN monthly_value > 4000;

END LOOP;

Page 15: Sql

162011 Erwin Fischer

Un programa Simple en PL/SQL

DECLARE

i NUMBER := 1;

BEGIN

LOOP

INSERT INTO T1 VALUES(i,i);

i := i+1;

EXIT WHEN i>100;

END LOOP;

END;

Page 16: Sql

172011 Erwin Fischer

El ciclo FOR

FOR loop_counter IN [REVERSE]

lowest_number..highest_number

LOOP

{.statements.}

END LOOP;

Page 17: Sql

182011 Erwin Fischer

Ejemplos de Ciclo FOR

FOR Lcntr IN 1..20

LOOP

LCalc := Lcntr * 31;

END LOOP;

FOR Lcntr IN REVERSE 1..15

LOOP

LCalc := Lcntr * 31;

END LOOP;

Page 18: Sql

192011 Erwin Fischer

El Ciclo While

WHILE condition

LOOP

{.statements.}

END LOOP;

Page 19: Sql

202011 Erwin Fischer

Ejemplo de ciclo While

WHILE monthly_value <= 4000

LOOP

monthly_value := daily_value * 31;

END LOOP;

Page 20: Sql

212011 Erwin Fischer

Cursores

Page 21: Sql

222011 Erwin Fischer

Cursores

• La instrucción SELECT puede utilizarse si la consulta

devuelve una fila y solo una fila.

• Los cursores se utilizan para el tratamiento de una

consulta que pueda devolver un numero arbitrario de

filas (es decir cero, una o más filas)

• En la practica el cursor actúa como un puntero que

dirige hacia una fila concreta el resultado de la

consulta.

• El cursor puede avanzar una posición para acceder a la

siguiente fila.

• Es necesario declarar y abrir los

cursores antes de utilizarlos

Page 22: Sql

232011 Erwin Fischer

Cursores, un Ejemplo

1. DECLARE

2. vIdEmpleado employees.employee_id%TYPE;

3. vNombre employees.first_name%TYPE;

4. vApellido employees.last_name%TYPE;

5. CURSOR ListaEmpleadoCursor IS

6. SELECT employee_id, first_name, last_name FROM employees FOR UPDATE;

7. BEGIN

8. OPEN ListaEmpleadoCursor;

9. LOOP

10. FETCH ListaEmpleadoCursor INTO vIdEmpleado, vNombre, vApellido;

11. EXIT WHEN ListaEmpleadoCursor%NOTFOUND;

12. dbms_output.put_line ('Id : '||vIdEmpleado

13. ||' Nombre : '|| vNombre

14. || 'Apellido : '|| vApellido);

15. END LOOP;

16. CLOSE ListaEmpleadoCursor;

17. END;

Page 23: Sql

242011 Erwin Fischer

Un cursor dentro de otro cursor - obtieneTablas

• Un cursor que lista todas las tablas con sus respectivas columnas, correspondiente al propietario HR

Page 24: Sql

252011 Erwin Fischer

Tablas all_tables y all_tab_columns

select distinct tablas.owner, tablas.table_name

from all_tables tablas

where tablas.owner = 'HR';

select distinct col.column_name

from all_tab_columns col

where upper(col.owner) = 'HR'

and lower(col.table_name) = 'employees';

Page 25: Sql

262011 Erwin Fischer

Declarando las Variables y los cursores

DECLARE

vPropietario varchar2(40);

vNombreTabla varchar2(40);

vNombreColumna varchar2(100);

/* Primer cursor */

cursor obtieneTablas is

select distinct t.owner, t.table_name

from all_tables t

where t.owner = 'HR';

/* Segundo cursor */

cursor obtieneColumnas is

select distinct c.column_name

from all_tab_columns c

where c.owner = vPropietario

and c.table_name = vNombreTabla;

Page 26: Sql

272011 Erwin Fischer

El cuerpo del cursor

begin

open obtieneTablas;

dbms_output.put_line('Abriendo Cursor - obtieneTablas');

loop fetch obtieneTablas into vPropietario, vNombreTabla;

exit when obtieneTablas%NOTFOUND;

dbms_output.put_line('Tabla : ‘||Propietario||'.'||vNombreTabla);

open obtieneColumnas;

loop fetch obtieneColumnas into vNombreColumna;

exit when obtieneColumnas%NOTFOUND;

dbms_output.put_line(‘=>’||vNombreTabla||'.'||vNombreColumna);

end loop;

close obtieneColumnas;

end loop;

close obtieneTablas;

EXCEPTION

WHEN OTHERS THEN

raise_application_error(-20001,'Se ha detectado un error -

'||SQLCODE||' -ERROR- '||SQLERRM);

end;

Page 27: Sql

282011 Erwin Fischer

Paso de Parámetros en Cursores

CURSOR obtieneTablas(pPropietario VARCHAR2) IS

select distinct t.owner, t.table_name

from all_tables t

where t.owner = pPropietario;

Con lo que podríamos abrir el cursor

OPEN obtieneTablas (´HR’);

OPEN obtieneTablas(´SYSTEM’);

Actividad : Modifique el cursor aplicando paso de parámetros, y

publique en su blog.

Page 28: Sql

292011 Erwin Fischer

Tarea Cursor ParImpar

• Agregue un atributo a la tabla EMPLOYEES, denominado TipoId, que va a contener un string.

• Desarrolle un cursor que permita completar dicho atributo de acuerdo al siguiente criterio:

SI employee_id es Par

Entonces

TipoId = ‘PAR’

Si-no

TipoId = ‘IMPAR’

• Suba la solución a su Blog HOY.

Page 29: Sql

302011 Erwin Fischer

Unidad - PL/SQL

• Fin