Vous êtes sur la page 1sur 9

Ampliación de Base de Datos

Ingeniería Técnica en Informática de Gestión - Curso 2010/2011


PRÁCTICA 1: INTRODUCCIÓN A PL/SQL

Objetivos

• Empezar a conocer el lenguaje PL/SQL


• Conocer conceptos básicos: estructura, tipos de datos, declaración variables
• Hacer un primer programa sencillo en PL/SQL

Contenido

1. Introducción.

SQL es un lenguaje de consulta para los sistemas de bases de datos relaciónales, pero que no posee la potencia de los lenguajes
de programación. Cuando se desea realizar una aplicación 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
programación tradicionales. PL/SQL es el lenguaje de programación que proporciona Oracle para extender el SQL estándar con
otro tipo de instrucciones.
PL/SQL es un lenguaje procedimental utilizado para interactuar con las bases de datos Oracle y que permite el uso de comandos
SQL embebidos en el mismo código. Además de ser procedimental, este lenguaje es modulable, es decir, es posible encapsular el
código para su reutilización posterior. De esa forma eliminamos la posibilidad de que exista código redundante, se mejora la
eficiencia de las aplicaciones, la seguridad, etc.

Los módulos de PL/SQL están divididos en cuatro categorías: Procedimientos, Funciones, Paquetes y Triggers.

• Procedimientos: código encapsulado que acepta parámetros de entrada y que no devuelve ningún tipo de valor.

• Funciones: código encapsulado que acepta parámetros de entrada y que devuelve un valor.

• Paquete: conjunto de procedimientos y funciones. Tiene dos partes: la especificación, con la cabecera de las funciones,
procedimientos y la declaración de variables, y el cuerpo, con el código de estos módulos. Es una forma de aglutinar
módulos relacionados entre si. Se utiliza como una biblioteca.

• Triggers: código pl/sql asociado a una tabla que se activa siempre que se de un determinado evento (insert, update,
delete). Se utilizan para implementar restricciones complejas en las tablas.

Todos estos módulos, una vez creados, se compilarán en la BD transformándose en objetos propios de dicha BD. De tal forma que
pueden ser utilizados por cualquier usuario u otro código, siempre que se tenga permiso para ello.

2. Bloques PL/SQL

La unidad básica en PL/SQL es el bloque. Todos los programas PL/SQL están compuestos por bloques que pueden estar anidados.
Un bloque PL/SQL está compuesto de tres partes principales:

• Sección declarativa (opcional).


• Sección ejecutable (obligatoria).
• Sección de excepciones (opcional).

Para empezar a estudiar el lenguaje PL/SQL utilizaremos los llamados bloques PL/SQL anónimos. Son trozos de código PL/SQL sin
nombre, por lo que no se pueden almacenar como objetos compilados en la base de datos. No obstante, se suelen guardar en
scripts .SQL, los cuales pueden ser lanzados en la BD cuando sea necesario.

Ampliación de Base de datos 1


Práctica 1:Introducción a PL/SQL

La estructura general de un bloque es:

[DECLARE
Variables, constantes, excepciones de usuario...]
BEGIN
Órdenes SQL y PL/SQL

[EXCEPTION
Acciones a realizar al ocurrir un error]
END;
/

Para que dicho bloque se pueda ejecutar es necesario ponerle al final la barra /

Todas las sentencias en el lenguaje PL/SQL acaban en ' ; ' .


Existen dos tipos de comentarios:

- - Comentarios de línea
/* Comentarios de
bloque */
3. Unidades léxicas

Los identificadores se emplean para dar nombre a objetos PL/SQL: variables, literales, cursores, tipos y subprogramas. Los
identificadores constan de una letra, seguida por una secuencia opcional de caracteres, entre los cuales encontramos: letras,
números, signos de dólar ($), caracteres de subrayado (_) y almohadillas (#). Los demás caracteres están prohibidos. La longitud
máxima es de 30 caracteres.

En PL/SQL no se distingue entre mayúscula y minúscula.

Si alguna vez necesitamos utilizar un identificador que incumpla las reglas anteriores o sea igual a una palabra reservada (BEGIN,
END, EXCEPTION, etc..) podemos encerrar dicho identificador entre dobles comillas:

“A number”
“5/X”

Los delimitadores son símbolos que tienen un significado especial y que sirven para separar unos identificadores de otros. A
continuación os mostramos los más relevantes:

‘ : Delimitador de cadena de caracteres


+ : Operador suma
- : Operador resta
* : Operador producto
/ : Operador división
= : Operador igualdad
> : Operador mayor que
< : Operador menor que
<> : Operador distinto de
¡= : Operador distinto de (equivalente a <>)
>= : Operador mayor/igual que
<= : Operador menor/igual que
:= : Operador asignación
AND : Operador Y lógico
OR : Operador O lógico
NOT : Operador NO lógico
<space> : Espacio
<tab> : Tabulación
<cr> : Retorno de carro o salto de línea

Ampliación de Base de datos 2


Práctica 1:Introducción a PL/SQL

4. Tipo en PL/SQL

En primer lugar hablaremos de los tipos disponibles. Los tipos más corrientes en variables PL/SQL son los que ya habíamos visto al
estudiar los tipos de datos que ofrecía el gestor Oracle, es decir:

NUMBER (size, precision): puede contener un valor numérico entero o de punto flotante. Es igual al tipo NUMBER de la base de
datos.
BINARY_INTEGER: los literales de tipo NUMBER son almacenados en formato decimal por cuestiones de optimización. Por ello no
se utilizan directamente en las operaciones aritméticas y si se utilizan, Oracle los convierte durante y al final del proceso. El tipo
BINARY_INTEGER está formado por números enteros con signo: del -2147483647 al 2147483647 y lo usaremos para valores que
solo intervengan en cálculos y no sean almacenados en la base de datos.
PLS_INTEGER: en versiones anteriores de Oracle este tipo era igual que el tipo anterior pero gestionado más eficientemente. En la
versión 10 de Oracle esa diferencia desapareció. Por lo cual, se puede utilizar cualquiera de los dos indistintamente.
BINARY_FLOAT: tipo de 32 bits para reales representados en coma flotante formato IEEE 754. Introducido en la versión 10 de
Oracle, son tipos muy eficientes para desarrollar cálculos complejos o en el intercambio de datos con otros lenguajes de
programación.
BINARY_DOUBLE: Ídem que el anterior, pero de 64 bits.
CHAR (s): las variables de este tipo con cadenas de caracteres de longitud fija.
VARCHAR2(s): pueden contener cadenas de caracteres de longitud variable, con una longitud máxima especificada.
DATE: se comporta de la misma manera que el tipo equivalente de la base de datos.
LONG: a diferencia del tipo LONG de la base de datos, que puede contener hasta dos gigabytes de datos, el tipo LONG de PL/SQL
es una cadena de longitud variable con una longitud máxima de 32760 bytes. Son variables muy similares a las de tipo VARCHAR2.
RAW: se emplea para almacenar datos binarios de longitud fija. Es parecido al CHAR pero sin sufrir conversiones entre conjuntos
de caracteres al ser transmitidos entre dos bases de datos diferentes.
LONG RAW: son similares a los datos LONG, excepto por el hecho de que PL/SQL no realizará conversiones entre conjuntos de
caracteres.
BOOLEAN: Las variable BOOLEANAS pueden tomar el valor TRUE, FALSE o NULL. Se pueden combinar mediante Operadores
lógicos (NOT, AND, OR). Las expresiones lógicas devuelven valores BOOLEANOS utilizando Operadores relacionales (<, <=...)
TABLE/RECORD: tipo registro. Puede almacenar una fila completa de una tabla.

5. Literales

Un literal es un valor numérico, booleano o carácter que no es un identificador.

 Literales de carácter

Los literales de carácter están delimitados por comilla simple y se asignan a variables de tipo CHAR o VARCHAR2.

Para poder incluir una comilla simple dentro de una cadena es necesario poner dos comillas simples, una detrás de la otra. Por
ejemplo: para representar la cadena Peter’s Friends pondremos ‘Peter’’s Friends’.

La cadena vacía se representa mediante dos comillas simples: ‘ ’. En PL/SQL este literal que representa a la cadena de longitud
cero es equivalente al valor NULL.

 Literales numéricos

Representan a números reales o enteros y pueden ser asignados a variables de tipo NUMBER o INTEGER. Estos son los únicos
literales que pueden formar parte de una expresión aritmética.

En los números reales, la parte decimal se separa de la entera mediante un punto. Por ejemplo: 22.3 ó 1124.56

 Literales booleanos

Solo existen tres: TRUE (cierto), FALSE (falso) y NULL(nulo). Solo pueden asignarse a variables booleanos. Se utilizan en las
expresiones lógicas y en estructuras IF y LOOP.

6. Definición de variables en PL/SQL

Se realiza en la primera parte del bloque (DECLARE).

Ampliación de Base de datos 3


Práctica 1:Introducción a PL/SQL

La sintaxis para la declaración de variables es la siguiente:

Nombre_var tipo_var [:= expresion] ;


Por ejemplo:

DECLARE

v_salary NUMBER(4);
v_name VARCHAR2(20) := ‘Antonio’;
v_second_name VARCHAR2(30):= ‘Manuel’;
v_hiredate DATE;
v_control BOOLEAN:= FALSE;
v_cont NUMBER := 0;

Aquellas variables que no tengan un valor por defecto en su declaración, recibirán el valor NULL.
Podemos definir, además de un valor por defecto, variables que sean constantes. En este caso, la inicialización es obligatoria
cuando una constante es definida:

Nombre_var CONSTANT tipo_var := expresion ;

Con un programa PL/SQL, lo que normalmente haremos será recorrer y tratar los datos almacenados en las tablas y vistas. Es por
ello que en ciertas ocasiones puede sernos útil el poder declarar una variable con el mismo tipo exactamente que el campo de una
tabla. Para ello se utiliza el Operador %TYPE:

Nombre_var nom_tabla.nom_campo%TYPE [:= expresion] ;

Es decir, con solo indicar la tabla y el campo la variable heredará su tipo.

Por ejemplo:

DECLARE

v_comision emp.comm%TYPE:=0;

En este ejemplo la variable v_comisión tendrá el mismo tipo que el campo comm de la tabla emp y será la variable apropiada para
recoger los valores de esa columna en el código.

Vamos a ver a continuación el tipo de dato compuesto más utilizado, el array o RECORD. Definimos un tipo que representa a un
registro formado por varios campos, cada uno de ellos con un tipo determinado. La sintaxis para su definición es la siguiente:

TYPE nom_tipo IS RECORD (

Nombre_var1 tipo_var [:= expresion] ;


Nombre_var2 tipo_var [:= expresion] ;
Nombre_var3 tipo_var [:= expresion] ;
…….);

Por ejemplo:

Ampliación de Base de datos 4


Práctica 1:Introducción a PL/SQL

DECLARE

TYPE t_emp IS RECORD (

my_empno emp.empno%TYPE;
my_ename emp.ename%TYPE;
my_job emp.job%TYPE;
my_salary emp.sal%TYPE;
fire_off BOOLEAN;
);

v_my_employee t_emp;

Para acceder a los distintos campos del registro:

t_emp.my_empno
t_emp.my_job etc.……….

Es decir, en una de estas variables así definidas podemos almacenar un registro entero, o parte de él, de una tabla.

Otra forma de crear un tipo similar, es decir, de contar con una especie de registro, es utilizando %ROWTYPE. Tiene la misma
funcionalidad que %TYPE pero esta vez haciendo referencia a una fila entera de una tabla:

Nombre_var nom_tabla%ROWTYPE;

Por ejemplo:

DECLARE

t_emp emp%ROWTYPE;

Finalmente, veamos la importancia del literal NULL en PL/SQL. Una instrucción NULL; significa ninguna acción y se utiliza en
algunas ocasiones. Las variables no inicializadas toman el valor inicial NULL. Podemos declarar una variable como NOT NULL, por
ejemplo:

Nombre_var tipo_var NOT NULL := expresion ;

En estos casos, la variable no puede tener nunca un valor nulo, lo que nos obliga a darle un valor inicial en el momento de su
declaración.

7. Conversión de tipos

Dentro de una misma familia de tipos de datos, las conversiones se pueden llevar a cabo siempre que se sigan unas determinadas
reglas. Por ejemplo, un literal CHAR(10) no podrá convertirse nunca a VARCHAR2(1). Lo mismo pasa en las conversiones entre
NUMBER(3,2) y NUMBER(3). Si se producen violaciones de las restricciones, PL/SLQ no dará error de compilación pero es posible
que si lo de en tiempo de ejecución.

 Conversiones explícitas de datos

Existen funciones que pueden convertir tipos de datos entre si. A continuación se muestran las más usadas:

TO_CHAR(arg): convierte un número o fecha en una cadena de tipo VARCHAR2

TO_DATE(arg): convierte una cadena al tipo fecha

Ampliación de Base de datos 5


Práctica 1:Introducción a PL/SQL

TO_NUMBER(arg): convierte una cadena al tipo numérico

 Conversiones implícitas de datos

PL/SQL realizará conversiones automáticas de tipos siempre que sean posibles. Las más comunes son: entre caracteres y números
y entre caracteres y fechas.

8. Visibilidad de las variables

Una variable es visible únicamente en el bloque en el que ha sido definida. Es posible anidar bloques entre si, tal y como muestra el
siguiente ejemplo:

DECLARE
Num NUMBER;
BEGIN
….
DECLARE
Cadena VARCHAR2(19);
BEGIN

END;

END;

La variable Cadena únicamente será visible en el bloque interior, mientras que Num será visible en todo el programa.

9. Usando sentencias SQL dentro de un bloque PL/SQL

Una de las características más atractivas del lenguaje PL/SQL es la posibilidad de poder utilizar comandos SQL dentro del código.
Las únicas instrucciones SQL permitidas en un programa PL/SQL son las del lenguaje de manipulación de datos y las de control de
transacciones. Es decir:

DML: SELECT, INSERT, UPDATE, DELETE.


Control transacciones: COMMIT, ROLLBACK, SAVEPOINT.

No obstante, existe una técnica que permite que se ejecuten todas las instrucciones SQL válidas, incluidas las de definición de
datos: SQL dinámico. El SQL dinámico permite crear dinámicamente instrucciones SQL en tiempo de ejecución para después
analizarlas y ejecutarlas.

En cuanto a las instrucciones DML, la única dificultad o diferencia la encontramos en la sentencia SELECT, ya que es necesario
utilizar la cláusula INTO para volcar el resultado de la consulta sobre una o varias variables. Además, estas sentencias SELECT-
INTO tienen la restricción de que han de devolver únicamente un solo registro. Si devolviera más de una fila, PL/SQL devolvería el
siguiente mensaje de error:

ORA-1427: Single-row query returns more than a row

Veamos un ejemplo de sentencia SELECT-INTO:

DECLARE

my_emp emp%ROWTYPE;
BEGIN

SELECT *
INTO my_emp
FROM emp
WHERE ename=’BLAKE’;
END;

Ampliación de Base de datos 6


Práctica 1:Introducción a PL/SQL

/
En una cláusula WHERE, podemos utilizar tanto literales como variables declaradas dentro de un bloque PL/SQL. Pero para ello
hay que cumplir dos restricciones:

a) La variable ha de ser del tipo adecuado: en un WHERE no podemos igualar una variable NUMBER con un campo de tipo DATE.
b) La variable nunca puede tener el nombre de un atributo de tabla. ¿Por qué motivo? Veamos un ejemplo:

DECLARE
Department CHAR(3);
BEGIN
Department := 'CS';
DELETE FROM classes
WHERE department = Department;
COMMIT;
END;
/
La intención de este bloque anónimo es borrar todos los registros de la tabla CLASSE que pertenezcan al departamento ‘CS’.
Cuando PL/SQL examina una expresión de tipo EXPR1 = EXPR2, lo primero que hace es comprobar si alguna de esas expresiones
se corresponden con columnas de la tabla con la que se está operando. Como en PL/SQL no se diferencia entre mayúsculas y
minúsculas, department y Department son asociadas a la columna de la tabla CLASSES. El efecto es que se borrarán todos los
registros de las tablas.

10. Entrada y Salida en PL/SQL

Existen funciones que nos pueden ayudar a depurar programas y a interactuar con el usuario mostrando datos por pantalla y
pidiendo datos al usuario.

10.1 Salida de datos

Para mostrar una cadena por pantalla podemos utilizar:

DBMS_OUTPUT.PUT_LINE(<cadena de caracteres> or <number>);

El Operador || se utiliza para concatenar. Si queremos que los mensajes aparezcan por pantallas tenemos que activar la opción
SERVEROUTPUT, al comienzo de nuestro script (para SQLPlus*. En TOAD no es necesario):

SET ServerOutput ON;

Por ejemplo:

SET ServerOutput ON;


DECLARE
num NUMBER :=100;
BEGIN
DBMS_OUTPUT.PUT_LINE('Valor de num: '||num);
END;
/

10.2 Entrada de datos

Cuando trabajamos pidiendo datos al usuario es habitual especificar la opción SET VERIFY OFF para evitar que el sistema nos
muestre el valor que tenía la variable antes y que nos confirme el nuevo valor que toma (solo para SQLPlus*).

Para pedir datos al usuario se utiliza una variable de substitución, dentro del código fuente del bloque PL/SQL, si esta variable no
está inicializada, se le pedirá el valor al usuario:

Por ejemplo:

SET ServerOutput ON;

Ampliación de Base de datos 7


Práctica 1:Introducción a PL/SQL

SET VERIFY OFF;


DECLARE
num NUMBER :=&v;
BEGIN
DBMS_OUTPUT.PUT_LINE('Valor de v: '||num);
END;
/

Bibliografía

Oracle 9i: Programación PL/SQL. OSBORNE MC GRAW-HILL. 2002

Experimentos

E1. Entrar en la aplicación TOAD y conectaros con vuestro usuario a la instancia Oracle instalada. A continuación, abrir un editor en
modo SQL.

E2. Lance en su esquema los siguientes scripts: Crear_modelo_scott.sql, Crear_modelo_student.sql y CreaEsquemaAcademia.sql

E3. Escriba el código PL/SQL que aparece como ejemplo de usar sentencias SQL (página 6) y ejecútelo ¿Qué ocurre?

E4. Ejecute el ejemplo de Salida de datos que aparece en la parte teórica.

E5. Ejecute el ejemplo de Entrada de datos y compruebe como TOAD le pide el valor de entrada.

E6. Para cada uno de los bloques PL/SQL anteriores, pásalos a un script Oracle (con extensión .sql) y ejecútelos en el SQL*Plus de
Oracle. Recuerde que para ejecutar un fichero en dicho entorno se utiliza la siguiente sintaxis:

SQL> @ruta_y_nombre_del_fichero;

Problemas

P1. Reescriba el programa del experimento 3 para que muestre por pantalla el registro obtenido con la sentencia SELECT,
siguiendo además el siguiente formato:

RESULTADO CONSULTA
====================
NUMERO EMPLEADO: <número del empleado>
NOMBRE DEL EMPLEADO: <nombre del empleado >
OFICIO: <oficio>
FECHA ALTA: <fecha alta>
SALARIO: <salario>

P2. Cree un bloque anónimo en PL/SQL para, en primer lugar, obtener todos los datos del empleado con nombre FORD. En
segundo lugar, se debe borrar de la tabla EMP dicho empleado. Se ha de añadir un nuevo empleado, con los mismos datos de
FORD a excepción de esta información nueva:

ename: UPO
job: STUDENT
sal: se pide al usuario

Dicha información se insertará mediante variables creadas por el programador.


Finalmente, actualice la tabla EMP sumándole 1000 euros al nuevo empleado. Acompañe a todo el proceso con mensajes en
pantalla que nos indiquen las acciones realizadas.
Compruebe que el programa ha tenido éxito.

P3. Otro ejemplo sencillo de bloque anónimo. Inserte 2 cadenas en la tabla TEMP_TABLE y muéstrelas posteriormente por pantalla.
Debe rellenar todos los campos de la tabla en cuestión. Al finalizar, anule los cambios realizados en la tabla.

Ampliación de Base de datos 8


Práctica 1:Introducción a PL/SQL

P4. Veamos la diferencia de gestión entre el tipo BINARY_INTEGER y el tipo PLS_INTEGER. Haremos dos bloques anónimos. En
el primero declararemos una variable de tipo BINARY_INTEGER y le daremos como valor inicial el mayor valor que puede albergar.
En el cuerpo del bloque le sumaremos y restaremos el valor 1 en la misma línea. Haga lo mismo con otro bloque anónimo y el tipo
PLS_INTEGER. Explique la diferencia de comportamiento de los dos programas.

P5. Bloques anidados. Implemente un bloque anónimo en el que se recoja en una variable el nombre del estudiante con ID=10000.
Posteriormente, en un bloque anidado, se utilizará ese valor para añadir un registro a la tabla LOG_TABLE, con el mensaje
“ALUMNO CON ID =1000 ES NOMBREALUMNO”. Además, se recogerá en una variable el número de registros existentes en dicha
tabla. Por último, en el bloque más exterior, se utilizará ese número de registros para imprimir un mensaje por pantalla. ¿Ofrece
algún tipo de problema la programación solicitada?

P6. Ejecute este programa y comprenda el porqué de los errores que se producen:

DECLARE
TYPE t_Rec1Type IS RECORD (
Field1 NUMBER,
Field2 VARCHAR2(5));
TYPE t_Rec2Type IS RECORD (
Field1 NUMBER,
Field2 VARCHAR2(5));
v_Rec1 t_Rec1Type;
v_Rec2 t_Rec2Type;
BEGIN
v_Rec1 := v_Rec2;

v_Rec1.Field1 := v_Rec2.Field1;
v_Rec2.Field2 := v_Rec2.Field2;
END;

Ampliación de problemas

AP1 Labor de investigación: busque, lea y comprenda el motivo de porqué las instrucciones DDL no pueden ser usadas
directamente dentro de un bloque PL/SQL.

Ampliación de Base de datos 9

Vous aimerez peut-être aussi