Está en la página 1de 77

Unidad 16 Declarar variables

Objetivo: El alumno será capaz de reconocer un bloque


PL-SQL, describir el significado de variables, distinguir
comandos PL-SQL y PL-SQL, declarar variables, ejecutar
bloques PL-SQL.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Programación en PL-SQL
Introducción a PL-SQL
SQL es un lenguaje de comandos con todas las estructuras de control típicas, no un
lenguaje de programación. Así, SQL sólo contempla instrucciones, más o menos simples,
pero no tiene ningún tipo de instrucciones de control de flujo o de otro tipo propias de los
lenguajes de programación 3GL.
Para subsanar esta carencia, Oracle definió un lenguaje de programación de tercera
generación, que admitiera sentencias SQL. Este lenguaje se llama PL-SQL (Programming
Language/SQL)
La idea básica sobre la que se sustenta PL-SQL es aplicar las estructuras típicas de un
lenguaje de programación (bifurcaciones, bucles, funciones....) a las sentencias SQL típicas.
PL-SQL incorpora muchas de las características avanzadas hechas en los lenguajes de
programación diseñados durante 1970 y 1980. Permite la manipulación de datos y
ejecución de comandos de SQL, que se incluyan dentro del bloque, haciendo de PL-SQL
una lenguaje de gran alcance de tipo transaccional.
PL-SQL ofrece características modernas de la tecnología como encapsulación de datos,
manejo de excepciones, ocultamiento de la información. etc.
¿Que es PL-SQL?
PL-SQL (Procedural Languaje/SQL) es una extensión de SQL, que agrega ciertas
instrucciones propias de lenguajes procedimentales, obteniéndose como resultado un
lenguaje estructural más poderoso que SQL. Los tipos de instrucciones que agrega de los
lenguajes procedimentales son:
o Variables y tipos (predefinidos y definidos por el usuario)
o Estructuras de control (bucles y condiciones IF- THEN - ELSE)
o Procedimientos y funciones
o Tipos de objetos y métodos
La unidad de programación utilizada por PL-SQL es el bloque. Todos los programas de PL-
SQL están conformados por bloques. Típicamente, cada bloque lleva a cabo una acción
lógica en el programa.
Creación de programas PL-SQL
Podemos crear programas de PL-SQL con cualquier editor y ejecutarlos desde el prompt de
SQL con START o @. Los ficheros creados serán de texto y tendrán la extensión SQL.
Para que un fichero se ejecute correctamente debe tener en su última línea el símbolo /.
Beneficios de PL-SQL
Integración
PL-SQL desempeña un papel central en el servidor Oracle (a través de los procedimientos,
de las funciones almacenadas, de los disparadores de la base de datos, y de los paquetes
almacenados) y en las herramientas de desarrollo del servidor de Oracle (con disparadores
de Oracle Developer).
Oracle Developer hace uso de las librerías compartidas que ejecutan código (los
procedimientos y las funciones) y que se pueden alcanzar localmente o remotamente.
Oracle Developer esta compuesto por formularios, reportes y gráficos de Oracle. Los tipos
de datos de SQL se pueden también utilizar en PL-SQL. Combinados con el acceso directo
que SQL proporciona, estos tipos de datos compartidos integran PL-SQL con el diccionario
de datos del servidor Oracle. PL-SQL tiende un puente entre el acceso conveniente a la
tecnología de la base de datos y la necesidad de capacidades de programación procesales.
PL-SQL en las herramientas de Oracle
Muchas herramientas de Oracle, incluyendo Oracle Developer, tienen su propio motor de
PL-SQL, que es independiente del motor presente en el servidor Oracle. El motor filtra las
declaraciones del SQL y las envía individualmente al ejecutor de procesos que se encuentra
en el servidor Oracle para que ejecute dichas declaraciones. El resto de la declaración, la
procesa en el ejecutor de procesos, que está en el motor de PL-SQL.
El ejecutor de procesos de PL-SQL procesa los datos que son locales en la aplicación (que
están dentro del ambiente del cliente, es decir, en la base de datos). Esto reduce el trabajo
enviado al servidor Oracle y el número de cursores que la memoria requiere.
Funcionamiento mejorado
PL-SQL puede mejorar el funcionamiento de una aplicación. Las ventajas diferencian
dependiendo del ambiente en donde se realiza la ejecución.
PL-SQL se puede utilizar para agrupar declaraciones SQL juntas dentro de un solo bloque y
enviar el bloque entero al servidor en una sola llamada, de tal manera que se reduzca el
tráfico de una red. Sin PL-SQL, las declaraciones del SQL serían enviadas al servidor
Oracle y el rendimiento estaría por encima del adecuado. En un ambiente de red, y los
gastos pueden llegar a ser significativos.
Si el uso de SQL es intensivo, se pueden utilizar bloques y subprogramas de PL-SQL para
agrupar declaraciones del SQL antes de enviarlas al servidor Oracle para su ejecución. PL-
SQL puede también cooperar con las herramientas de desarrollo del servidor Oracle tales
como formularios e informes de Oracle Developer. (Ver fig. 5.1)

SQ L
SQ L
A p lic a c ió n SQ L
O tro s D B M S
SQ L

SQ L
IF ...T H E N
SQ L O r a c le c o n
A p lic a c ió n ELSE
SQ L P L /S Q L
E N D IF ;
SQ L

Los procedimientos y las funciones declaradas como parte de una aplicación de desarrollo
son distintos de los almacenados en la base de datos, aunque su estructura general es igual.
Los subprogramas almacenados son objetos de la base de datos y se almacenan en el
diccionario de datos. Pueden ser utilizados por cualquier número de aplicaciones,
incluyendo aplicaciones de desarrollo.
Características de PL-SQL
La unidad básica en PL-SQL es el bloque. Todos los programas de PL-SQL están
compuestos por bloques que pueden contener otros sub-bloques y así sucesivamente. Cada
bloque lleva a cabo una acción lógica en el programa.
La estructura del bloque de PL-SQL
Un bloque de PL-SQL consta de tres secciones: declarativa (opcional), ejecutable
(requerido), y manejo de excepciones (opcional). Solamente se requieren las palabras
claves BEGIN y END. Se pueden declarar variables locales específicamente en el bloque
en el cual se van a utilizar. Las condiciones de error (conocidas como excepciones) se
pueden manejar específicamente en el bloque al cual se aplican. Se pueden almacenar y
cambiar valores dentro de un bloque de PL-SQL declarando y refiriéndose a variables y a
otros identificadores.
La estructura del bloque quedaría de la siguiente manera:

D ECLARE - O p c io n a l

. . .
B E G IN - O b lig a t o r io
. . .
E X C E P T IO N - O p c io n a l

. . .
END; - O b lig a to r io

Estructura de un bloque
DECLARE
// Sección declarativa: variables, constantes, cursores, manejo
// de excepciones, y sub-programas de uso local
BEGIN
//Sección ejecutable: las instrucciones de PL-SQL, y de SQL
// aparecen aquí. Es la única sección obligatoria en el bloque.
EXCEPTION
//Sección de manejo de excepciones. Las rutinas de manejo de
// errores aparecen aquí.
END;

Las instrucciones de SQL permitidas en un bloque PL-SQL son INSERT, UPDATE, DELETE
y SELECT, además de algunas instrucciones para manipulación de datos, e instrucciones
para control de transacciones. Las instrucciones de SQL como DROP, CREATE o ALTER
no son permitidas.
Secciones del bloque:
Sección Descripción Inclusión
Declarativa Contiene todas las variables, constantes, cursores, y excepciones Opcional
definidas por el usuario
Ejecutable Contiene declaraciones de SQL para manipular datos en la base de Obligatorio
datos y las declaraciones de PL-SQL para manipular datos en el
bloque
Manejo de Especifica las acciones a realizarse cuando los errores y las Opcional
excepciones condiciones anormales se presentan en la sección ejecutable

Ejecutando declaraciones y bloques PL-SQL para SQL


Se usa un punto y coma (;) al final de una declaración de SQL o una declaración de control
de PL-SQL.
Se usa una diagonal (/) para ejecutar el bloque de PL-SQL en el buffer de SQL. Cuando el
bloque se ejecuta con éxito, sin manejo de errores o sin compilar errores, la salida del
mensaje debe ser la siguiente:
PL-SQL procedure succesfully completed.

Se usa un punto para cerrar el buffer de SQL. Un bloque de PL-SQL se trata como
declaraciones continuas en el buffer, y los puntos y comas dentro del bloque no cierran ni
ejecutan el buffer.
En PL-SQL, un error es conocido también como excepción. Las palabras claves
DECLARE, BEGIN, y EXCEPTION no van seguidas por puntos y comas. Sin embargo,
END y el resto de las declaraciones de PL-SQL requieren un punto y coma para terminar la
declaración. Se pueden hacer declaraciones juntas en una misma línea, pero este método no
se recomienda para la claridad del programa o para corregirlo.
Tipos de bloques
Cada unidad de PL-SQL abarca uno o más bloques. Estos bloques pueden ser separados o
jerarquizados dentro de otros.
Las unidades básicas (los procedimientos, las funciones, también conocidas como
subprogramas, y los bloques anónimos) que aparecen en la parte de arriba de un programa
de PL-SQL son bloques, que pueden contener cualquier número de sub-bloques
jerarquizados. Por lo tanto, un bloque puede representar una parte pequeña de otro bloque,
que a su vez puede formar parte de la unidad entera del código.
Los bloques se pueden clasificar en los siguientes:
o Anónimos
o Nombrados
o Procedimientos, paquetes y funciones
o Tipos de objetos y métodos
Bloques Anónimos
Se construyen normalmente de manera dinámica para un objetivo muy concreto y se
ejecutan, en general, una única vez.

Anónimo

[DECLARE]

[BEGIN]
declaraciones

[EXCEPTION]

END;
Bloques nombrados
Son similares a los bloques anónimos pero con una etiqueta que da nombre al bloque.
Podemos poner una etiqueta a un bloque anónimo para facilitar referirnos a él. Antes de la
palabra DECLARE se usan ángulos dobles << nombre del bloque >>. Es opcional, poner
el nombre también después de la palabra END nombre del bloque;
En bloques anidados puede ser muy útil para referirse a una variable en particular de ese
bloque, en caso de que existan varias con el mismo nombre: nombre_del_bloque.variable

Nombrado

<<nombre_bloque>>
[DECLARE]

[BEGIN]
declaraciones

[EXCEPTION]

END;

Procedimientos, paquetes y funciones


Son procedimientos (procedures), funciones (functions) o grupos de ellos, llamados
paquetes (packages).
 Se construyen para efectuar algún tipo de operación más o menos frecuente y se
almacenan para ejecutarlos cuantas veces se desee.
 Se ejecutan con una llamada al procedimiento, función o paquete.
Una función es similar a un procedimiento, a menos que ésa función deba volver un valor.

Paquete Procedimiento Función


CREATE PACKAGE
PROCEDURE name FUNCTION name
nombre AS
IS RETURN tip_dat
END [nombre]; IS
[BEGIN] [BEGIN]
declaraciones declaraciones
CREATE PACKAGE
BODY nombre AS
[EXCEPTION] [EXCEPTION]
[BEGIN]
END; END;
END[nombre];
Disparadores (triggers)
Son bloques nominados que se almacenan en la base de datos. Su ejecución está
condicionada a cierta condición, como por ejemplo usar una orden concreta de DML.

Trigger

TRIGGER name
[Cuando se dispara]
ON tabla
FOR EACH ROW

[BEGIN]
declaraciones

[EXCEPTION]

END;

Tipos de bloques

Tipos de bloques Descripción Disponibilidad


Bloque Anónimo Bloque de PL-SQL que está almacenado dentro Almacenado en
de una aplicación. ambientes de PL-SQL
Procedimiento almacenado Bloque de PL-SQL almacenado en el servidor de Servidor Oracle
o función Oracle que puede aceptar parámetros y se puede
invocar en varias ocasiones por su nombre.
Aplicación, procedimiento o Bloque de PL-SQL almacenado en una aplicación Componentes de Oracle
función de Oracle Developer o una librería compartida Developer (formas).
que puede aceptar parámetros y se puede invocar
en varias ocasiones por su nombre.
Paquete Módulo de PL-SQL que agrupa procedimientos, Servidor Oracle y
funciones, e identificadores relacionados. Componentes de Oracle
Developer (formas).
Trigger de la base de datos Bloque de PL-SQL que se asocia a una tabla de la Servidor Oracle
base de datos y se ejecuta automáticamente
cuando se cumple una instrucción de DML
Trigger de la aplicación Bloque de PL-SQL que se asocia a un Componentes de Oracle
acontecimiento de una aplicación y se ejecuta Developer (formas).
automáticamente
Descripción de los tipos de bloques

P r o c e d im ie n to
B lo q u e a n ó n im o a lm a c e n a d o /
DECLARE fu n c io n

. . .

BEGIN
A p lic a c io n ,
T rig g e r A p lic a c ió n . . . p ro c e d im ie n to /
fu n c io n

EXCEPTION
. . .

END;
T rig g e r B a s e d e P a q u e te /
d a to s fu n c io n

Variables y tipos de datos


Uso de variables
o Almacenamiento temporal de datos: Los datos se pueden almacenar
temporalmente en una o más variables para usarlos al validar la entrada de datos
para procesar más adelante en el flujo de datos.
o Manipulación de valores almacenados: Las variables se pueden utilizar para
realizar cálculos y otras manipulaciones de datos sin tener acceso a la base de datos.
o Reusabilidad: Una vez que ya fueron declaradas, las variables se puedan utilizar en
varias ocasiones en una aplicación simplemente refiriéndose a ellas en las
declaraciones, a través de su nombre.
o Facilidad del mantenimiento: Al usar %TYPE y %ROWTYPE, al declara las
variables, toman el mismo tipo que definen las columnas de la base de datos. Las
variables de PL-SQL o las variables del cursor declaradas previamente pueden
también utilizar los atributos de %TYPE y de %ROWTYPE como tipos de datos
especificados. Si una definición subyacente cambia, la declaración de la variable
cambia en el tiempo de ejecución. Esto proporciona independencia de datos, reduce
costos de mantenimiento, y permite que los programas se adapten mientras que la
base de datos cambia para resolver nuevas necesidades del negocio.
Manejando variables en PL-SQL
a) Declarar e inicializar las variables en la sección de declaración.
También, se pueden declarar variables en la parte declarativa de cualquier bloque
del subprograma, o del paquete de PL-SQL. Las declaraciones asignan espacio para
almacenar un valor, especifican su tipo de dato, y nombran la localización donde se
almacenara de modo que se pueda hacer referencia a ella. Además tenemos que
asignarle un valor a la variable, ya que si no le indicamos un valor está tendrá por
defecto el valor NULL.
Sintaxis:
Identificador: es el nombre de una variable escalar.
expresion: puede ser una variable, literal, o llamada a una función, pero no
puede tener el nombre de la columna de una base de datos.

identificador[CONSTANT] tipo_dato [NOT NULL]


[:= | DEFAULT expresion];

Para asignar los valores iniciales a una variable podemos usar el operador :=, o bien
podemos utilizar la palabra clave DEFAULT. Aunque también podemos especificar
el tipo de dato de una variable mediante el atributo %TYPE que hace referencia a
esta variable o a otra variable que ya esté asignada.

DECLARE
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL := 10;
v_location VARCHAR2(13) := 'Atlanta';
c_comm CONSTANT NUMBER := 1400;

b) Asignar valores a las variables


Si el valor de la variable existe se substituye por uno nuevo. Se debe declarar una
variable antes de referirse a ella, ya que no se puede hacer referencia a una variable
que no a sido declarada.
Para asignar o para reasignar un valor a una variable, se debe escribir una
declaración de asignación de PL-SQL. Se debe nombrar explícitamente la variable,
para recibir el nuevo valor a la izquierda del operador (de la asignación :=).

identificador := [expresion];

Para asignar valores definidos a una variable se hace de la siguiente manera:


v_hiredate := '31-DEC-98';
v_deptno := 10;
v_location := 'Atlanta';
c_comm := 1400;

Otra manera de asignar valores a las variables es seleccionar o traer valores de la


base de datos en ella.

SQL> SELECT sal * 1.10


INTO v_bonus
FROM emp
WHERE empno = 7369;

Después esa variable se puede utilizar (v_bonus) en otra operación, o bien, insertar
su valor en una tabla de la base de datos.
Para asignar un valor en una variable de la base de datos, se utiliza el SELECT o
FETCH en la declaración.
c) Pasar valores a subprogramas de PL-SQL con parámetros:
Hay tres modos para pasar parámetros:
o IN (default): el valor del parámetro real se pasa al procedimiento cuando éste
es llamado. Dentro del procedimiento el parámetro formal se considera
como de sólo lectura, y no puede ser modificado. Cuando termina el
procedimiento , y se devuelve el control al entorno que realizó la llamada, el
parámetro real no ha sufrido cambios.
o OUT: se ignora cualquier valor que tenga el parámetro real cuando se llama
al procedimiento. Dentro del procedimiento, el parámetro formal se
considera como de sólo escritura; no puede ser leído, sino que tan sólo
pueden asignársele valores. Cuando termina el procedimiento y se devuelve
el control, el contenido del parámetro formal se asigna al parámetro real.
o IN OUT: es la combinación de los dos anteriores, el valor del parámetro real
se pasa al procedimiento, dentro del procedimiento el parámetro formal
puede ser leído y modificado al devolver el control los contenidos del
parámetro formal se asignan al parámetro real.
d) Ver los resultados de un bloque PL-SQL con variables de salida
Se pueden utilizar variables de referencia para la entrada o la salida en la
declaración de la manipulación de datos de SQL.
Usando variables de SQL dentro de los bloques PL-SQL
PL-SQL no tiene capacidades de entrada-salida propias. Se debe confiar en el ambiente en
el cual PL-SQL se está ejecutando para pasar valores dentro y fuera de un bloque de PL-
SQL.
En el ambiente de SQL, SQL permite variables de substitución para que se almacenen y se
editen antes de ser ejecutadas. Las variables de substitución son las variables que se pueden
utilizar para pasar valores, números o caracteres, en un bloque de PL-SQL.
Se puede hacer referencia a ellas dentro de un bloque de PL-SQL con un signo "&"
precedente, de manera semejante mientras sé esta refiriendo a más variables de substitución
dentro de una declaración de SQL. Los valores de texto se substituyen en el bloque de PL-
SQL antes de que se ejecute el bloque de PL-SQL.
Tipos de variables
o TRUE representa un valor Booleano
o 25-OCT-99 representa un DATE
o El nombre de una ciudad representa un VARCHAR2
o El texto de un párrafo representa un LONG RAW
o Una fotografía representa un BLOB
o Un vídeo representa un BFILE
Declarando variables de PL-SQL.
Se necesitan declarar todos los identificadores de PL-SQL en la sección de declaración
antes de referirse a ellos en el bloque de PL-SQL. Existe la opción de asignar un valor
inicial, pero no es necesario asignar un valor a un variable para declararlo. Si se hace
referencia a otras variables en una declaración, se deben declarar por separado en una
declaración anterior.
Sintaxis:
Identificador: es el nombre de la variable.
CONSTANT: es el valor que tiene la variable, este valor no puede cambiar, las
constantes deben ser inizializadas.
Tipo_dato: es un escalar, compuesto, referencia, o tipo de dato LOB.
NOT NULL: es el valor que tienen la variable, cuando se trate de este tipo debe
inicializarse.
Expresión: es una expresión de PL-SQL que puede ser una literal, otra variable, o
una expresión que implica operadores y funciones.

identificador[CONSTANT] tipo_dato [NOT NULL]


[:= | DEFAULT expresion];
El atributo %TYPE
Cuando se declaran variables de PL-SQL para guardar valores en las columnas, se debe
asegurar que el tipo de dato y la precisión de las variables sean correctos. Si no lo son,
ocurrirá un error de PL-SQL durante la ejecución.
Para asegurar que el tipo de dato y la precisión de la variable son correctos, con el de las
columnas de las tablas en la base de datos se debe utilizar el %TYPE para declarar una
variable igual a la columna previamente declarada de la variable o de la base de datos. El
atributo %TYPE se utiliza muy a menudo cuando el valor almacenado en la variable será
derivado de una tabla del tipo de dato requerido en la declaración de la variable. Se prefija
con el nombre de la tabla y de la columna de la base de datos. Si se refiere a una variable
previamente declarada, se prefija el nombre de la variable.
PL-SQL determina el tipo de dato y el tamaño de la variable cuando se compila el bloque.
Ésta es una ventaja definida para escribir y mantener el código, porque no hay necesidad de
cambiar el tipo de dato en el bloque, este cambio solo se realiza a nivel de la base de datos.

ACCEPT p_empno PROMPT 'Número del empleado'


DECLARE
v_empno emp. Empno%TYPE := &p_empno;
v_sal emp.sal%TYPE;
v_comm emp.comm%TYPE;
BEGIN
.........
END;

Declarando variables con el atributo %TYPE


La declaración de una variable que es del mismo tipo que la columna de una tabla de la
base de datos, quedaría de la siguiente manera:

. . .
v_ename emp.ename%TYPE;
. . .

La declaración de una variable que es del mismo tipo que una variable declarada
anteriormente quedaría de la siguiente manera:

. . .
v_balance NUMBER(7,2);
v_min_balance v_balance%TYPE := 10;
. . .
Las columnas con valores NOT NULL no se les pueden declaran variables usando el
%TYPE. Por lo tanto, si se declara una variable usando él %TYPE para una columna de la
base de datos definida como NOT NULL, se puede asignar el valor NULL a la variable.
Declarando variables booleanas.
Con PL-SQL se pueden comparar variables de SQL y declaraciones procedimentales. Estas
comparaciones, son llamadas expresiones Booleanas, consisten en expresiones simples o
complejas separadas por operadores. En una declaración de SQL, se pueden utilizar
expresiones booleanas para especificar las filas en una tabla que son afectadas por la
declaración. En una declaración procedimental, las expresiones booleanas son la base para
el control condicional. La declaración y la inicialización de una variable booleana, quedaría
de la siguiente manera:

v_comm_sal BOOLEAN := (v_sal1 <v_sal2);


v_sal1 := 50000; v_sal2 := 60000;

La siguiente expresión es TRUE


v_sal1 < v_sal2

Variables de tipo Bind


Una variable de tipo bind es una variable que se declara en un ambiente anfitrión y después
se utiliza para pasar valores, números o caracteres, dentro o afuera de uno o más programas
de PL-SQL, que pueden ser utilizados como cualquier otra variable. Las variables pueden
ser declaradas o llamadas en el ambiente anfitrión, a menos que las declaraciones estén en
un procedimiento, una función, o un paquete.
Creando variables de tipo bind
Para declarar una variable de tipo bind en el ambiente de SQL, se utiliza el comando
VARIABLE. Por ejemplo:

VARIABLE return_code NUMBER


VARIABLE return_msg VARCHAR2(30)

Tanto SQL como SQL plus pueden hacer referencia a variables de tipo bind, y SQL plus
puede desplegar este valor.
Desplegando variables de tipo bind
Para desplegar el valor de una variable de tipo bind en un ambiente de SQL Plus, debe usar
el comando PRINT. Sin embargo, PRINT no se puede utilizar dentro de un bloque de PL-
SQL como un comando de SQL.
Para solucionar este problema, se puede declarar una variable en un ambiente anfitrión, y
hacer referencia a esta en un bloque de PL-SQL, y después desplegar su contenido en SQL
usando el comando PRINT.

Ejemplo del comando PRINT.


SQL> VARIABLE g_n NUMBER
SQL> PRINT g_n

Para hacer referencia a variables, se deben prefijar las referencias con dos puntos (:) para
distinguirlas de las variables declaradas en PL-SQL.

VARIABLE g_monthly_sal NUMBER


ACCEPT p_annual_sal PROMPT 'Dar el salario anual:'
DECLARE
v_sal NUMBER (9,2) := &p_annual_sal:
BEGIN
:g_monthly_sal := v_sal/12;
END;
/

PRINT g_monthly_sal

Otra opción es con el comando BMS_OUTPUT.PUT_LINE.DBMS_OUTPUT que es un


paquete provisto por Oracle y PUT_LINE que es un procedimiento dentro de ese paquete.
Dentro de un bloque de PL-SQL, hay que hacer referencia a DBMS_OUTPUT.PUT_LINE
y entre paréntesis, la información que se desea imprimir en la pantalla. El paquete primero
debe ser activado en la sesión de SQL. Para hacer esto, se debe ejecutar el comando de
SQL SET SERVEROUTPUT ON.
SET SERVEROUTPUT ON
ACCEPT p_annual_sal PROMPT 'Dar el salario anual:'

DECLARE
v_sal NUMBER (9,2) := &p_annual_sal:
BEGIN
v_sal := v_sal/12;
DBMS_OUTPUT.PUT_LINE ('El salario es:' ||
TO_CHAR(v_sal));
END;
/

Reglas para el nombre de los objetos


Dos objetos pueden tener el mismo nombre, a condición de que se definan en diferentes
bloques. Donde coexisten, sólo el objeto declarado en el bloque actual puede ser utilizado.
Una variable no puede tener el mismo nombre (identificador) que el de las columnas de la
tabla usadas en el bloque. Si las variables de PL-SQL se utilizan en declaraciones de SQL y
tienen el mismo nombre que una tabla, el servidor de Oracle asume que se está haciendo
referencia a la tabla.
DECLARE
empno NUMBER(4);
BEGIN
SELECT empno
INTO empno
FROM emp
WHERE ename='SMITH'
END;

Este código usa el mismo nombre para una tabla de la base de datos y una variable, por lo
que no es fácil de leer o de mantener.
Se recomienda usar v _ como prefijo para representar una variable y g _ para representar
una variable global para evitar conflictos con los objetos de la base de datos.
Los identificadores no deben ser más largos de 30 caracteres. El primer carácter debe ser
una letra, los caracteres restantes pueden ser letras, números, o símbolos especiales.
Tipos de datos
Todas las variables de PL-SQL tienen un tipo de dato, que especifica un formato de
almacenaje, y un rango válido de valores.
PL-SQL clasifica los tipos de datos en 4 categorías: Escalares, Compuesto, Referencia y
Objeto de LOB(large)
a) Escalares
Tienen un solo valor. Los principales son los que corresponden al tipo de
columnas de las tablas del Servidor Oracle. Permiten manipular datos
numéricos, alfanuméricos, fechas y booleanos.
Tipos de datos escalares:
o VARCHAR2(longitud máxima)
o NUMBER(precisión, escala)
o DATE
o CHAR(longitud máxima)
o LONG
o LONG RAW
o BOOLEAN
o BINARY_INTEGER
o PLS_INTEGER
El tipo VARCHAR2 es un tipo de dato carácter de hasta 32,767 bytes. Si se usa
un código distinto al código ASCII, el número total de caracteres puede ser
menor.
El tipo NUMBER este tipo de dato se almacena en formato decimal. Para
operaciones aritméticas deben traducirse a binario.
El tipo DATE es un tipo de dato para fecha y tiempo. DATE incluye valores de
tiempo en días y segundos desde la medianoche. Su rango esta entre 4712 B.C.
y 9999 A.D
El tipo CHAR es un tipo de dato carácter de hasta 32,767 bytes. Si no se
especifica una longitud máxima, la longitud por default es 1.
El tipo LONG es un tipo de dato carácter de hasta 32,767 bytes. La anchura
máxima para este en una columna de la base de datos es 2,147,483,647 bytes.
El tipo LONG RAW es un tipo de dato para datos binarios y cadenas de 32,760
bytes. LONG RAW no es interpretado por PL-SQL
El tipo BOOLEAN es un tipo de dato que almacena uno de tres posibles valores
usados para realizar cálculos lógicos: TRUE , FALSE, NULL
El tipo BINARY_INTEGER es un tipo de dato entero en binario
(complemento a 2) con un rango entre -2,147,483 y 2,147,483,647, ideal para
variables sobre las que se efectuarán operaciones.
El tipo PLS_INTEGER es similar a BINARY_INTEGER, pero más rápido en
las operaciones aritméticas y que genera un error si se produce un
desbordamiento (ORA-1426) al asignarlo a un NUMBER.
Declaración de Variables Escalares

v_job DATE;
Variable que almacena el nombre del trabajo de un empleado
v_count BINARY_INTEGER := 0;
Variable para contar las iteraciones de un ciclo,se inicializa a 0
v_total_sal NUMBER(9,2):= 0;
Variable para acumular el sueldo total para un departamento,se inicializa a 0
c_tax_rate CONSTANT NUMBER(3,2):= 8.25;
Es un tipo de variable constante, que nunca cambia a través del bloque PL/SQL
v_valid BOOLEAN NOT NULL := TRUE;
Bandera que indica si ciertos datos son válidos o inválidos, se inicializa
con TRUE

b) Compuestos
Permiten que los grupos de campos sean manipulados y definidos en los bloques
de PL-SQL.
Tipos de datos compuestos:
o TABLE
o RECORD
o NESTED TABLE
o VARRAY
El tipo de dato RECORD se utiliza para datos relacionados como una unidad
lógica.
El tipo de dato TABLE se utiliza para referirse y manipular datos como un
objeto completo.
c) Referencia
También conocido como punteros, señalan otros objetos de un programa. REF
CURSOR y REF <Tipo_objeto>
d) LOB
También conocidos como localizadores, especifican la localización de los
objetos grandes (imágenes gráficas, sonido) que se almacenan fuera de línea.
Con el tipo de datos LOB en Oracle8 se puede almacenar bloques de datos no
estructurados (como texto, imágenes gráficas, video clips, y audio) hasta un
tamaño de 4 gigabytes. Los tipos de dato LOB son eficientes, los datos se
accesan al azar, también se puede accesar a cierta parte de datos, y puede ser
atributo de un tipo de objeto.
Tipos de datos compuestos:
o CLOB
o BLOB
o BFILE
o NCLOB
El CLOB (objeto grande de tipo carácter) se utiliza para almacenar bloques
grandes de datos de tipo carácter (un byte) en la base de datos.
El BLOB (objeto grande de tipo binario) se utiliza para almacenar objetos
binarios grandes en la base de datos.
El BFILE (archivo binario) se utiliza para almacenar objetos binarios grandes
en archivos del sistema operativo fuera de la base de datos.
El NCLOB se utiliza para almacenar bloques grandes de (un byte) o datos fijos
de multibyte NCHAR en la base de datos.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Práctica 16: Declarar variables

1. Evaluate each of the following declarations. Determine which of them are not legal
and explain why.
a. DECLARE V_id NUMBER(4);
b. DECLARE v_x, v_y, v_z VARCHAR (10);
c. DECLARE v_birthdate DATE NOT NULL;
d. DECLARE v_in_stock BOOLEAN:=1;

2. In each of the following assignments, determine the datatype of the resulting


expression.

a. V_days_to_go:=v_due_date – Sysdate;
b. V_sender:=USER || ` : ´ || TO_CHAR(V_dept_no);

c. V_sum := $100,000 + $250,000;


d. V_flag:=TRUE;
e. V_n1:=V_n2 > (2* v_n3);
f. V_value:= Null;

3. Create an anonymous to output the phrase ”My PL-SQL Black Works” to the
screen.

G_MESSAGE
-------------------------------------
My PL-SQL Block Works

If you have time, complete the following exercise:

4. Create a block that declares two variables. Assign the value of these PL-
SQLvariables to SQL*Plus host variables to the screen. Execute your PL-SQL
Block. Save your PL-SQL Block to a file named p16q4.sql

V_CHAR Character (variable lenght)


V_NUM Number

Assign values to these variables as follows:

Variable Value
--------------------------------

V_CHAR The literal `24 is the answer´


V_NUM The first two characters from V_CHAR
G_CHAR
-------------------------------
42 is the answer

G_NUM
------------
42
Unidad 17 Escribir instrucciones ejecutables
Objetivo: El alumno será capaz de manejar reglas y
bloques anidados, ejecutar y probar bloques PL-SQL, uso
de código convencional.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Sintaxis y sugerencias de Bloques PL-SQL


a) Delimitadores
Los delimitadores son los símbolos simples o compuestos que tienen un
significado especial en PL-SQL.

Símbolo Mensaje Símbolo Mensaje


+ Suma <> Operador relacional
- Resta/negación != Operador relacional
* Multiplicación || Concatenación
/ División -- Comentarios
= Operador relacional /* Inicio de comentarios
@ Acceso remoto */ Fin de comentarios
; Terminación := Operador de asignación

b) Identificadores
Los identificadores se utilizan para nombrar los objetos y las unidades de un
programa de PL-SQL, que incluyen constantes, variables, excepciones, cursores,
variables de tipo cursor, subprogramas, y paquetes.
Los identificadores pueden contener hasta 30 caracteres, pero deben comenzar con
un carácter alfabético.
El nombre para los identificadores no debe ser el mismo que el de las columnas en
una tabla usada en el bloque. Si los identificadores de PL-SQL están en las
mismas declaraciones de SQL y tienen el mismo nombre que una columna,
entonces Oracle asume que está haciendo referencia a la columna.
Las palabras reservadas no se pueden utilizar como identificadores a menos que se
incluyan comillas(“SELECT”). Las palabras reservadas deberán escribirse en
mayúscula para promover legibilidad.
Un identificador es visible en el bloque en el cual se declara y en todos los
subbloques, procedimientos, y funciones jerarquizados. Si el bloque no encuentra
el identificador declarado localmente, busca hasta la sección declarativa de los
bloques que incluye (o padre). El bloque nunca busca abajo de los bloques
incluidos (o niño) o de lado de los bloques del hermano.
El alcance se aplica a todos los objetos declarados, incluyendo variables, a los
cursores, a las excepciones definidas por el usuario, y a las constantes.
Este es visible solo en las regiones en las que se pueda hacer referencia al
identificador.
c) Comentarios
Los comentarios pueden incluirse siempre que se desee y se clasifican en:
o Monolínea: empiezan con 2 guiones - - y terminan al final de línea.
o Multilínea: empiezan con /* y terminan con */ (como en el lenguaje C)
Hay que comentar el código para documentar cada fase y poder eliminar errores.
El código de PL-SQL se comenta con 2 guiones
- - si el comentario está en una sola línea, o entre
/* Comentario en
varias Lineas */ si el comentario ocupa varias líneas.
Los comentarios son informativos y no cumplen ninguna condición ni
comportamiento en base a los datos. Los comentarios bien colocados son valiosos
para la legibilidad del código y el mantenimiento del código en un futuro. PL-
SQL no es case sensitive por lo que no hay distinción entre nombres con
mayúsculas y minúsculas.
d) Literales
Una literal es un numérico explícito, un carácter, una secuencia, o un valor
booleano no representado por un identificador.
Los literales de carácter incluyen todos los caracteres imprimibles en PL-SQL:
letras, número, espacios, y símbolos especiales.
Las literales numéricas se pueden representar por un valor simple (-32.5) o por la
notación científica (2E5). Un bloque de PL-SQL se termina con una diagonal (/).
Los bloques jerarquizados y el alcance de las variables

. . .
x BINARY_INTEGER; Alcance de X
BEGIN
. . .
DECLARE
y NUMBER; Alcance de Y
BEGIN
. . .
END;
. . .
END;

En este bloque jerarquizado, la variable Y pueden referirse a la variable X. Sin embargo, la


variable X no puede referirse a la variable Y. Si la variable Y en el bloque jerarquizado
tiene el mismo nombre que la variable X en el bloque externo su valor es válido solamente
el tiempo que dure el bloque jerarquizado.
Operadores
El orden de las operaciones dentro de una expresión se hace en una orden particular
dependiendo de su precedencia.
Orden de las operaciones de mayor a menor:

Operador Operación
**,NOT Exponenciación, negación lógica
+,- identificador, negación
*,/ Multiplicación, división
+,-,|| Suma, resta, concatenación
=,!=,<,>,<=,>=,IS NULL, LIKE, BETWEEN, IN Comparación
AND Conjunción
OR Inclusión

No es necesario utilizar paréntesis con expresiones booleanas, pero esto facilita cuando se
lee el texto.
Código de escritura en mayúsculas o minúsculas para distinguir palabras claves de objetos
nombrados.

Categoría Regla Ejemplos


Estatutos SQL Mayúsculas SELECT,INSERT
Palabras reservadas de PL-SQL Mayúsculas DECLARE, BEGIN, IF
Tipos de datos Mayúsculas VARCHAR2, BOOLEAN
Identificadores y parámetros Minúsculas V_sal,cmp_cursor,g_sal,
p_empno
Tablas y columnas de la Base de datos Minúsculas Cmp, orderdate, deptno

Sistema de prefijos y de sufijos para distinguir identificadores de otros identificadores, de


objetos de la base de datos, y de otros objetos nombrados.

Identificador Regla Ejemplo


Variable v_name v_sal
Constante c_name c_company_namel
Cursor name_cursor emp_cursor
Excepción c_name e_too_many
Tipo de tabla name_table_type amount_table_type
Tabla name_table order_total_table
Tipo de registro name_record_type emp_record_type
Registro name_record customer_record
Variables de substitución de SQL p_name p_sal
Variables globales de SQL g_name g_year_sal

Comparando los tipos de declaración en SQL y PL-SQL


Un bloque en PL-SQL no es una unidad de transacción. Los commits, savepoints, y
rollbacks son bloques independientes, pero estos comandos se pueden publicar dentro de
un bloque.
PL-SQL no soporta el lenguaje de definición de datos (DDL), del tipo CREATE TABLE,
ALTER TABLE o DROP TABLE.
PL-SQL no soporta el lenguaje de control de datos (DCL), del tipo GRANT o REVOKE
Funciones de SQL en PL-SQL
Muchas de las funciones disponibles en SQL también son válidas en PL-SQL. Funciones
para números, para caracteres, para conversión de datos, para las fechas, Greatest, Least,
Miscelánea de funciones.

ERROR

v_total := SUM(number_table);

Funciones PL-SQL
PL-SQL proporcionan muchas funciones de gran alcance para ayudarnos a manipular datos.
Algunas funciones de PL-SQL son las siguientes:
Algunas funciones de PL-SQL son las siguientes:
o Funciones numéricas: ABS, CEIL, FLOOR, MOD, POWER, ROUND, SIGN,
SQRT, TRUNC.
o Funciones sobre cadena de caracteres: ASCII, CHR, INITCAP, INSTR,
LENGTH, LOWER, LPAD, LTRIM, REPLACE, RPAD, RTRIM, SOUNDEX,
SUBSTR, TRANSLATE, UPPER.
o Funciones de conversión de datos: TO CHAR, TO DATE, TO NUMBER.
o Funciones sobre fechas: ADD MONTS, LAST DAY, MONTHS BETWEEN,
NEW TIME, NEXT DAY, ROUND, SYSDATE, TRUNC.
o Funciones de control de errores: SQLCODE, SQLERRM
o Funciones varias: GREATEST, LEAST, NVL, USERENV, USER, UID.
Algunas funciones que no son válidas en PL-SQL son las siguientes:
o DECODE
o Grupo de funciones como:
AVG,MIN,MAX,COUNT,SUM,STDDEV,VARIANCE
Estas funciones se aplican a los grupos de filas en una tabla y por lo tanto están disponibles
solamente en SQL, y no en las declaraciones de un bloque en PL-SQL.

Convierte el nombre a minúsculas.

v_ename := LOWER(v_ename);
Funciones para la conversión de tipos de datos
PL-SQL procura convertir tipos de datos dinámicamente si se mezclan en una declaración.
Por ejemplo, si asigna un valor de tipo NUMBER a una variable de tipo CHAR, entonces
PL-SQL convierte dinámicamente el número en un carácter, para poderlo almacenar en la
variable de tipo CHAR.

DECLARE
V_char VARCHAR2(30);
V_num NUMBER(11,2);
BEGIN
V_char := '42 es la respuesta';
V_num := TO_NUMBER(SUBSTR(v_char,1,2));
IF mod(v_num, 2) = o THEN
INSERT INTO messages (results)
VALUES ('Número es …..')
ELSE
INSERT INTO messages (results)
VALUES ('Número es …..')
END IF;
END;

Dentro de una expresión, se debe garantizar que los tipos de datos sean iguales. Si los tipos
de datos están mezclados en una expresión, se debe utilizar la función apropiada para
convertir los datos.

- TO_CHAR
- TO_DATE
DECLARE
- TO_NUMBER v_date VARCHAR2(15);
BEGIN
SELECT TO_CHAR(hiredate,'MON,DD,YYYY')
INTO v_date
FROM emp
WHERE empno = 7893;
END;

Sintaxis:
TO_CHAR(valor, fmt)
TO_DATE(valor, fmt)
TO_NUMBER(valor, fmt)
donde:
valor: es un carácter, número o fecha
fmt: es el formato usado para realizar la conversión
v_date := 'January 13, 1998'; INCORRECTO

v_date := TO_DATE ('January 13, 1998',


'Month DD, YYYY');
CORRECTO

Para corregir el error, hay que convertir la cadena de caracteres a un tipo de dato fecha con
la función TO_DATE.
PL-SQL realiza la conversión si es posible, pero el éxito depende de las operaciones que
son realizadas. Es bueno realizar conversiones de tipos de datos, porque ayudan al
funcionamiento y siguen siendo válidas aun cuando exista un cambio en versiones del
programa.
Una de las ventajas que PL-SQL tiene sobre SQL es la capacidad de jerarquizar
declaraciones. Se pueden jerarquizar los bloques dondequiera que se permita una
declaración ejecutable. Por lo tanto, se puede analizar la parte ejecutable de un bloque en
bloques más pequeños. La sección de la excepción puede también contener bloques
jerarquizados. El alcance un objeto es la región del programa que puede referir al objeto.
Con esto se puede referir a la variable declarada dentro de la sección ejecutable.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Práctica 17: Escribir instrucciones ejecutables

This practice reinforces the basics of PL-SQL presented in the lesson, including the rules
for nesting PL-SQL blocks of code as well as how to execute and test their PL-SQL code.

Paper-Based Questions
Questions 1 and 2 are paper-based questions.

PL-SQL Block

DECLARE
v_weightNUMBER(3) := 600;
v_message VARCHAR2(255) := ‘Product 10012’;

BEGIN
/* SUB-BLOCK */
DECLARE
v_weight NUMBER(3) := 1;
v_message VARCHAR2(255) := ‘Product 11001’;
v_newlocn VARCHAR2(50) := ‘Europe’:

BEGIN
v_weight := v_weight +1;
v_new_locn := ‘Western ‘ || v_new_locn;
END;

v_weight := v_weight +1;


v_message := v_message || ‘is in stock’;
v_new_locn := ‘Western ‘ || v_new_locn;
END;

1. Evaluate the PL-SQL block above and determine the data type and value of each of
the following variables according to the rules of scooping.

a) The value of v_weight in the subblock is:


b) The value of V_NEW_LOCN in the subblock is:
c) The value of V_WEIGHT in the main block is:
d) The value of V_Message in the main block is:
e) The value of V_NEW_LOCN in the main block is:

scope example

DECLARE
v_costumer VARCHAR2(50) := ‘Womansport’;
v_credit_rating VARCHAR2(50) := ‘EXCELLENT’;
BEGIN
DECLARE
v_costumer NUMBER(7) := 201;
v_name VARCHAR2(25) := ‘Unisports’;
BEGIN

v_costumer v_name v_credit_rating

END;

v_costumer v_name v_credit_rating

END;

2. Suppose you embed a subblock within a block, as shown above. You declare two
variables, V_COSTUMER and V_CREDIT_RATING, in the main block. You also
declare two variables, V_CUSTOMER and V_NAME, in the subblock. Determine
the values and datatypes for each of the following cases.

a) The value of V_CUSTOMER in the subblock is:


b) The value of V_NAME in the subblock is:
c) The value of V_CREDIT_RATING in the main block is:
d) The value of V_CUSTOMER in the main block is:
e) The value of V_NAME in the main block is:
f) The value of V_CREDIT_RATING in the main block is:

3. Create and execute a PL-SQL block that accepts two numbers through SQL*Plus
substitution variable. The first number should be divided by the second number and
have the second number added to the result. The result should be stored in a PL-
SQL variable and printed on the screen, or result should be written to a SQL*Plus
variable and printed to the screen.

a. When a PL-SQL variable is used:

Please enter the first number: 2


Please enter the second number: 4

4.5

b. When a SQL*Plus variable is used:

Please enter the first number: 2


Please enter the second number: 4

PL-SQL procedure successfully completed.

G_RESULT
-----------------
4.5

4. Build a PL-SQL block that computes the total compensation for one year. The
annual salary and the annual bonus percentage are passed to the PL-SQL block
through SQL*Plus substitution variables, and the bonus needs to be converted from
a whole number to a decimal (for example, 15 to .15). If the salary is null, set it to
zero before computing the total compensation. Execute the PL-SQL block.
Reminder: Use the NVL function to handle null values.

Hint: To test NVL function, type NULL at the prompt; pressing [Return] results in
a missing expression error.

Please enter the salary amount: 5000


Please enter the bonus percentage: 10

PL-SQL procedure successfully completed.

G_TOTAL
--------------
55000
Unidad 18 Interactuar con el servidor de Oracle
Objetivo: El alumno será capaz de manejar tipos de datos,
escribir sentencias DML en bloques PL-SQL, controlar
transacciones en bloques PL-SQL.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Recuperando datos usando PL-SQL


Se usa el estatuto SELECT para recuperar datos de la base de datos.

SELECT lista_seleccionada
INTO {nombre_variable[,nombre_variable]
. . .
| nombre_registro}
FROM tabla
WHERE condicion;

Sintaxis:
lista_seleccionada: es una lista de una columna y puede incluir expresiones SQL,
funciones de fila o funciones de grupo.
nombre_variable: es la variable escalar para llevar el valor recuperado.
nombre_registro: es el registro de PL-SQL que lleva los valores recuperados.
tabla: especifica el nombre de la tabla de la base de datos.
condición: se compone de los nombres de la columna, expresiones, constantes, y
operadores de comparación, incluyendo variables de PL-SQL y constantes.
Cláusula INTO
La cláusula INTO es obligatoria y se encuentra entre las cláusulas SELECT y FROM.
Se utiliza para especificar los nombres de las variables que almacenaran los valores que se
obtengan de la cláusula SELECT. Se debe declarar una variable para cada objeto
seleccionado, y su orden debe corresponder al orden en el que van a ser seleccionados. Se
utiliza la cláusula INTO para variables de PL-SQL o variables del ambiente anfitrión.

DECLARE
v_depto NUMBER(2);
v_loc VARCHAR2(15);
BEGIN
SELECT deptno,loc
INTO v_deptno, v_loc
FROM dept
WHERE dname= 'SALES';
. . .
END;

Querys que regresan una y solo una fila


Las declaraciones SELECT dentro de un bloque de PL-SQL se encuentra en la
clasificación ANSI de SQL, la cual tiene un regla que indica: los querys deben regresar una
y solamente una fila. Más de una fila o ninguna fila genera un error.
PL-SQL se ocupa de estos errores usando excepciones estándares, que se puede declarar en
la sección de excepciones del bloque. Para este caso en particular se usan las excepciones
de NO_DATA_FOUND y de TOO_MANY_ROWS.
Para recuperar datos en PL-SQL hay que terminan cada declaración de SQL con un (;). La
cláusula INTO se requiere para la declaración de un SELECT en PL-SQL.
Está cláusula es opcional y se puede utilizar dicha cláusula para especificar variables de
entrada, constantes, literales, o expresiones de PL-SQL.
El número de variables de salida en la cláusula INTO debe ser el mismo que el de las
columnas de la base de datos en la cláusula SELECT. Hay que asegurarse de que estas
correspondan y que sus tipos de datos son compatibles.
Para asegurarse de que los tipos de datos de los identificadores son iguales a los tipos de
datos de las columnas, utilice el atributo %TYPE. Se pueden usar funciones de grupo,
como SUM, en una declaración de SQL, ya que las funciones del grupo se aplican a los
grupos de filas de una tabla.

DECLARE
v_sum_sal emp.sal%TYPE;
v_deptno NUMBER NOT NULL :=10;
BEGIN
SELECT SUM(sal) - función de grupo
INTO v_sum_sal
FROM emp
WHERE deptno=v_deptno;
END;

Las funciones de grupo no se pueden utilizar en PL-SQL. Se utilizan en la declaración de


SQL dentro de un bloque de PL-SQL.
Manipulando datos usando PL-SQL
Los datos se manipulan en la base de datos usando comandos de DML.
Los comandos de DML son:
o INSERT
o UPDATE
o DELETE
Se pueden publicar los comandos de DML, sin la restricción en PL-SQL. Incluyendo
declaraciones de COMMIT o ROLLBACK en PL-SQL.
o El comando INSERT agrega nuevas filas de datos a la tabla.
o El comando UPDATE modifica filas existentes en la tabla.
o El comando DELETE borra filas indeseadas de la tabla.
Insertando datos
Utilizando las funciones de SQL, como USER y SYSDATE.
Genera valores primarios usando secuencias de la base de datos.
Deriva valores en el bloque PL-SQL.
Agrega valores prefijados a la columna.

BEGIN
INSERT INTO emp(empno,ename,job,deptno)
VALUES(empno_sequence.NEXTVAL,'HARDING','CLERK',10)
END;
No hay posibilidad de ambigüedad con los identificadores y los nombres de la columna en
la declaración de INSERT. Cualquier identificador en la cláusula del INSERT debe ser un
nombre de la columna de la base de datos.
Modificando y borrando datos
Puede existir ambigüedad en la cláusula SET en la declaración de la cláusula UPDATE
porque aunque el identificador a la izquierda del operador de asignación es siempre una
columna de la base de datos, el identificador a la derecha puede ser una columna de la base
de datos o una variable de PL-SQL.
La cláusula WHERE se utiliza para determinar que filas serán afectadas. Si no se modifica
ninguna fila, no ocurre ningún error, semejante a la declaración SELECT en PL-SQL.

DECLARE
v_sal_increase emp.sal%TYPE := 2000;
BEGIN
UPDATE emp
SET sal = sal + v_sal_increase
WHERE job = 'ANALYST';
END;

DECLARE
v_deptno emp.deptno%TYPE := 10
BEGIN
DELETE FROM emp
WHERE deptno = v_deptno
END;

Al asignar un valor a una variable en PL-SQL siempre se usa := y al asignar un valor a una
columna en SQL siempre se usa =. El nombre de la columna y el nombre del identificador
son idénticos en la cláusula WHERE, el servidor Oracle busca primero el nombre en la base
de datos.
Para evitar la ambigüedad en la cláusula WHERE se usan ciertas reglas para distinguir los
nombres de las columnas de la base de datos del nombre de las variables de PL-SQL. Las
columnas y los identificadores de la base de datos deben tener nombres distintos.
Los errores de sintaxis pueden presentarse porque PL-SQL comprueba en la base de datos
primero para saber si hay una columna en la tabla.
ERROR

DECLARE
Ordedate ord.orderdate%TYPE;
Shipdate ord.shipdate%TYPE;
Ordid ord.ordid%TYPE := 601;
BEGIN
SELECT orderdate, shipdate
INTO orderdate, shipdate
FROM ord
WHERE ordid = ordid;
END;

PL-SQL comprueba si el identificador es una columna de la base de datos; si no, asume


que se trata de un identificador de PL-SQL.
No hay posibilidad de la ambigüedad en la cláusula SELECT porque cualquier
identificador en la cláusula SELECT debe ser un nombre de la columna de la base de datos.
No hay posibilidad de la ambigüedad en la cláusula INTO porque los identificadores en la
cláusula INTO deben ser variables de PL-SQL. Solamente en la cláusula WHERE existe la
posibilidad de confusión.
Control de transacciones
Las transacciones lógicas se pueden controlar con la declaración en SQL del COMMIT y
del ROLLBACK, por lo que se pueden realizar cambios permanentes a algunos grupos de
la de base de datos o bien también se pueden deshacer otros.
En el servidor Oracle, las transacciones de DML comienzan en el primer comando seguido
de un COMMIT o ROLLBACK y terminan en el siguiente COMMIT o ROLLBACK
ejecutado exitosamente. Estas acciones pueden ocurrir dentro de un bloque de PL-SQL o
como resultado de acontecimientos en el ambiente del anfitrión. Para marcar un punto
intermedio en el tratamiento transaccional, se utiliza SAVEPOINT.

Sintaxis:

COMMIT;

SAVEPOINT nombre del savepoint;

ROLLBACK;

Los comandos para el control de la transacción son válidos dentro de PL-SQL, aunque el
ambiente anfitrión puede poner una cierta restricción en su uso.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Práctica 18: Interactuar con el servidor de Oracle

1. Create a PL-SQL block that selects the maximum deparment number in the DEPT
table and stores it in a SQL*Plus variable. Print the results to the screen. Save your
PL-SQL block to a file named p18ql.sql.

G_MAX_DEPTNO
-----------------------
40

2. Modify the PL-SQL block you created in exercise l to insert a new department into
the DEPT table. Save your PL-SQL block yo a file named p18q2.sql.

a. Reather than printing the department number retrieved from exercisi l. Add
l0 to it and use it as the department number for the new department.

b. Use a SQL*Plus substitution variable for the department name.

c. Leave the location null for now.

d. Execute the PL-SQL block.

Please enter the department name: EDUCATION


PL-SQL procedure successfully completed.

e. Display the new department that you created.

DEPTNO DNAME LOC


---------- ---------------------- ---------
50 EDUCATION

3. Create a PL-SQL block that updates the location for an existing department. Save
your PL-SQL block to a file named p18q3.sql.

a. Use a SQL*Plus substitution variable for the department number.

b. Use a SQL*Plus substitution variable for the department location.

c. Test the PL-SQL block.

Please enter the department number: 50


Please enter the department location: HOUSTON
PL-SQL procedure successfully completed.

d. Display the department number, department name, and location for the
update department.

DEPTNO DNAME LOC


---------- ---------------------- ---------
50 EDUCATION HOUSTON

e. Display the department that you updated.

4. Create a PL-SQL block that deletes the department created in exercise 2. Save your
PL-SQL block to a file named p18q4.sql.

a. Use a SQL*Plus substitution variable for the department number.

b. Print to the screen the number of rows affected.

c. Test the PL-SQL block.

Please enter the department number: 50


PL-SQL procedure successfully completed.

G_RESULT
-----------------------------------
1 row (s) deleted.

d. What happens if you enter a department number that does not exist?

Please enter the department number: 99


PL-SQL procedure successfully completed.

G_RESULT
-----------------------------------
0 row (s) deleted.

e. Confirm that department has been delected.

no rows selected
Unidad 19 Escribir estructuras de control
Objetivo: El alumno será capaz de manejar estructuras de
control: condiciones y ciclos bloques PL-SQL, uso de
tablas lógicas y definición del flojo de datos en ciclos
anidados.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Estructuras de control
Se puede cambiar el flujo lógico de declaraciones dentro del bloque de PL-SQL con un
número de estructuras del control.
Existen dos tipos de estructuras del control en PL-SQL:
o Constructores condicionales (IF)
o Estructuras de control (LOOP)
Existen tres formas de declarar constructores condicionales:
o IF – THEN – END – IF
o IF – THEN – ELSE – END – IF
o IF – THEN – ELSEIF – END – IF
Cláusula IF
La estructura para la cláusula IF en PL-SQL es similar a la estructura de una cláusula IF en
otro lenguaje procedural. Esta cláusula permite que PL-SQL realice las acciones selectivas
basadas en condiciones.

IF condicion THEN
declaraciones;
[ELSEIF condicion THEN
declaraciones;]
[ELSE
declaraciones;]
END IF

Sintaxis:
Condición: es una variable o una expresión booleana (TRUE, FALSE, o NULL)
(se asocia a una secuencia de declaraciones, se ejecuta solamente sí la expresión es
TRUE)
THEN: es una cláusula que asocia la expresión booleana que la precede con la
secuencia de declaraciones que la sigue.
Declaraciones: puede ser la declaración de una o más declaraciones de PL-SQL o
SQL.
ELSIF: es una palabra clave que introduce una expresión booleana (si la primera
condición es FALSE o NULL entonces la palabra clave de ELSIF introduce
condiciones adicionales.)
ELSE: es una palabra clave se ejecuta si el control la alcanza, y realiza la secuencia
de declaraciones que la siguen.
Cláusula IF simple
...
IF v_ename = ‘MILLER’ THEN
v_job := ‘SALESMAN’
v_deptno := 35;
v_new_comm := sal * 0.20;
END IF;
...

En el ejemplo PL-SQL realiza 3 acciones solo si la condición es TRUE. Si la condición es


FALSE o NULL, PL-SQL no hace caso de ellas. Se pueden realizar acciones basadas en
condiciones que son satisfechas.
Al escribir el código, hay que recordar el deletreo de las palabras claves:
ELSIF es una palabra.
END IF son dos palabras.
Si la condición booleana que controla es TRUE, la secuencia asociada de declaraciones se
ejecuta; si la condición booleana que controla es FALSE o NULL, la secuencia asociada de
declaraciones no se ejecuta. Se permite cualquier número de cláusulas ELSIF. Puede
haber una cláusula ELSE.
Cláusula IF – THEN – ELSE
Si la condición es FALSA o NULL, se puede usar la cláusula ELSE para realizar otras
acciones.

IF - THEN - ELSE

TRUE FALSE
Condicion IF

acciones acciones
THEN ELSE

Cláusula IF – THEN – ELSE


...
IF condicion1 THEN
declaracion1;
ELSIF condicion2 THEN
declaración2;
ELSEIF
declaración3;
END IF;
...
Cualquier acción para el resultado de la primera declaración IF puede incluir mas
declaraciones IF antes de realizar acciones específicas. Las cláusulas THEN y ELSE
pueden incluir declaraciones IF. Cada declaración de un IF debe terminar con un END IF.
Cláusula IF – THEN – ELSIF
Es posible utilizar la cláusula ELSIF en vez de declarar un IF. El código es más fácil de leer
y de entender, y la lógica se identifica claramente. Si la acción en la cláusula ELSE consiste
puramente por otra declaración IF, es más conveniente utilizar la cláusula ELSIF.
IF - THEN - ELSEIF
TRUE
Condicion IF
FALSE

acciones TRUE
Condicion
THEN ELSIF FALSE

acciones Condicion
THEN ELSE

Cláusula IF – THEN – ELSEIF


...
IF condicion1 THEN
declaracion1;
ELSIF condicion2 THEN
declaración2;
ELSEIF
declaración3;
END IF;
...
Condiciones lógicas
Se puede construir una condición booleana simple para combinar números, caracteres, o
expresiones de fecha con el operador de comparación.
Expresiones y comparaciones con NULL
La condición IS NULL se evalúa como TRUE solo si la variable es NULL.
Cualquier expresión que contiene un valor nulo se evalúa como NULL, con la excepción de
una expresión concatenada, que trata el valor nulo como una cadena vacía.
Condiciones booleanas con operadores lógicos
Se puede construir una condición boleana compleja combinando condiciones booleanas
simples con el operador lógico AND, OR y NOT.

AND TRUE FALSE NULL OR TRUE FALSE NULL NOT

TRUE TRUE FALSE NULL TRUE TRUE TRUE TRUE TRUE FALSE

FALSE FALSE FALSE FALSE FALSE TRUE FALSE NULL FALSE TRUE

NULL NULL FALSE NULL NULL TRUE NULL NULL NULL NULL

Tablas lógicas
FALSE toma precedencia sobre una condición AND.
TRUE toma precedencia en una condición OR.
AND regresa solo TRUE si ambos operadores son TRUE.
OR regresa FALSE solo si ambos operadores son FALSE.
NULL y TRUE siempre se evalúan como NULL porque no son conocidos si el segundo
operando se evalúa como TRUE o NOT.
La negación de NULL (NOT NULL) toma un valor nulo porque los valores nulos son
indeterminados.
Control Iterativo: Estatutos LOOP
PL-SQL proporcionan un número de facilidades para estructurar ciclos que permitan repetir
una declaración o una secuencia para múltiples tiempos.
Las construcciones de colocación son el segundo tipo de estructura del control:
LOOP básico para proporcionar acciones repetitivas sin condiciones
FOR ciclos para proporcionar el control iterativo de las acciones basadas en un contador
WHILE ciclos para proporcionar el control iterativo de las acciones basadas en una
condición
EXIT para terminar ciclos
LOOP básico
La forma más simple es la declaración de un LOOP básico, que incluye una secuencia de
declaraciones entre las palabras claves LOOP y END LOOP. El flujo de la ejecución se
termina cuando llega a una declaración END LOOP, y regresa el control a la declaración
correspondiente que se refiera a este LOOP. Un loop básico permite que este sea ejecutado
por lo menos una vez. Sin la declaración de EXIT, el loop sería infinito.
La declaración EXIT
Se puede terminar un loop usando la declaración EXIT. El control pasa a la siguiente
declaración después de la declaración END LOOP. Se puede publicar EXIT como
cualquier otra acción dentro de una declaración IF o como declaración independiente dentro
del loop. La declaración EXIT se debe poner dentro de un loop. En el último caso, se puede
unir una cláusula WHEN para permitir la terminación condicional del loop. Cuando la
declaración EXIT es encontrada, la condición en la cláusula WHEN es evaluada. Si la
condición es TRUE, el loop se termina y pasa el control a la siguiente declaración después
del loop. Un loop básico puede contener múltiples declaraciones EXIT.
LOOP -- delimitador
declaraciones; -- declaraciones
. . .
EXIT [WHEN condicion]; -- EXIT declaracion
END LOOP -- delimitador

donde:
condicion es una variable booleana o
expresion (TRUE, FALSE,NULL)

FOR LOOP
FOR este loop tienen la misma estructura general que el loop básico. Además, tienen un
orden de control antes de la palabra clave del ciclo para determinar el número de
iteraciones que debe realizar en PL-SQL.
FOR contador in [REVERSE]
limite_inferior . . limite_superior LOOP
declaracion1;
declaracion2;
. . .
END LOOP;

Sintaxis:
contador: es un número entero implícito declarado que se incrementa o decrementa
automáticamente (decrementa si se utiliza la palabra clave REVERSE) por 1 en cada
iteración del loop hasta el límite superior o inferior que se indique.
REVERSE: causa opuestamente al decremento por cada iteración del límite superior o
inferior.
limite_inferior: especifica el límite inferior para el rango de valores del contador
limite _superior: especifica el límite superior para la el rango valores del contador
Si no se declara el contador, este es declarado implícitamente como un entero. La secuencia
de declaraciones se ejecuta cada vez que se incrementa el contador, según lo determinado
por los dos límites. El límite más bajo y el límite superior del rango de valores estos pueden
ser literales, variables, o expresiones pero deben evaluar números enteros. Si el límite más
bajo del rango del loop evalúa a un número entero más grande que el límite superior, la
secuencia de declaraciones no será ejecutada.
Los límites más bajos y superiores de una declaración del LOOP no necesitan ser
numéricos. Pueden ser expresiones que convierten los valores a números.
WHILE LOOP
Se puede usar el WHILE loop para repetir una declaración hasta que la condición es TRUE.
La condición se evalúa en el comienzo de cada iteración. El loop termina cuando la
condición es FALSE. Si la condición es FALSE en el comienzo del loop, entonces no se
realiza ninguna otra iteración.
WHILE condicion LOOP
declaracion1;
declaracion2;
. . .
END LOOP;

Sintaxis:
condicion: es una variable o una expresión booleana (TRUE, FALSE, o NULL).
declaracion: puede ser uno o más declaraciones PL-SQL o SQL.
Si las variables implicadas en las condiciones no cambian durante el cuerpo del loop,
entonces la condición siguen siendo TRUE y el loop no termina. Si la condición es NULL,
el loop sobrepasado y pasa el control a la siguiente declaración.
Loop y etiquetas jerarquizadas
Se pueden jerarquizar loops para múltiples niveles. Se puede jerarquizar FOR, WHILE y
loops básicos dentro de unos y otros. La terminación de un loop jerarquizado no se termina
el loop a menos que existiera una excepción. Sin embargo, se pueden etiquetar los loops
salir del loop con la declaración de EXIT. Los nombres de etiqueta siguen las mismas
reglas que los identificadores. Una etiqueta se pone antes de una declaración, en la misma
línea o en una línea separada.
Para etiquetar los loops hay que poner la etiqueta antes de la palabra LOOP dentro de los
delimitadores de la etiqueta (<<etiqueta>>).
Si se etiqueta el loop, el nombre de la etiqueta puede incluido después de la declaración del
END LOOP.
. . .
BEGIN
<<Outer_loop>>
LOOP
v_counter := v_counter+1;
EXIT WHEN v_counter>10;
<<Inner_loop>>
LOOP
. . .
EXIT Outer_loop WHEN total_done = 'YES';
-- Nivel para ambos loops
EXIT WHEN inner_done = 'YES';
-- Nivel solo para inner loop
. . .
END LOOP inner_loop;
. . .
END LOOP outer_loop;
END;

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Unidad 19: Escribir estructuras de control

1. Run the script lab19_1.sql to create the MESSAGES table: Write a PL-SQL block
to insert numbers into the MESSAGES table.

a. Insert the numbers 1 to 10, excluding 6 and 8.

b. Commit before the end of the block.

c. Select from the MESSAGES table to verify that your PL-SQL block
worked.

RESULTS
-------------
1
2
3
4
5
6
7
8
9
10

2. Create a PL-SQL block that computes the commission amount for a given employee
based on the employee’s salary.

a. Run the script lab19_2.sql to insert a new employee into the EMP table.
Note: The employee will have a NULL salary.

b. Accept the employee number as user input with a SQL*Plus substitution


variable.

c. If the employee’s salary is less than $1,000, set the commission amount for
the employee to 10 % of the salary.

d. If the employee’s salary is between $1,000 and $1,500, set the commission
amount for the employee to 15 % of the salary.

e. If the employee’s salary exceeds $1,500, set the commission amount for the
employee to 20 % of the salary.
f. If the employee’s salary is NULL, set the commission amount for the
employee to 0.

g. Commit.

h. Test the PL-SQL block for each case using the following test cases, and
check each updated commission.

Employee Number Salary Resulting Commission


7369 800 80
7934 1300 195
7499 1600 320
8000 NULL 0

EMPNO ENAME SAL COMM


---------- ---------- ----- ----------
8000 DOE 0
ALLEN 1600 320
7934 MILLER 1300 195
7369 SMITH 800 80

If you have time, complete the following exercises:

3. Modify the p19q4.sql file to insert the text “Number is odd” or “Number is even,”
depending on whether the value is odd or even, into the MESSAGES table. Query
the MESSAGES table to determine if your PL-SQL block worked.

RESULTS
-----------------
Number is even

4. Add a new column called STARS, of VARCHAR2 and length 50, to the EMP table
for storing asterisk (*).

5. Create a PL-SQL block that rewards an employee by appending an asterisk in the


STARS column for every $100 of the employee´s salary. Save your PL-SQL block
to a file called p19q5.sql.

a. Accept the employee ID as user input with a SQL*Plus substitution variable.

b. Initialize a variable that will contain a string of asterisks.

c. Append an asterisk to the string for every $100 of the salary amount. For
example, if the employee has a salary amount of $800, the string of asterisks
should contain eight asterisks. If the employee has a salary amount of $1250,
the string of asterisks should contain 13 asterisks.

d. Update the STARS column for the employee with the string of asterisks
e. Commit.

f. Test the block for employees who have no salary and for an employee who
has a salary.

Please enter the employee number: 7934


PL-SQL procedure successfully completed.

Please enter the employee number: 8000


PL-SQL procedure successfully completed.

EMPNO SAL STARS


---------- -------- -----------
8000
7934 1300 *********
Unidad 20 Trabajando con datos compuestos
Objetivo: El alumno será capaz de crear usuarios, definir
registros PL-SQL, crear registros con el atributo
%ROWTYPE, crear tablas PL-SQL, crear tablas de
registros PL-SQL y describir la diferencia entre registros,
tablas y tablas de registros.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Registros y tablas.
Como las variables escalares, las variables compuestas tienen un tipo de datos también.
Los tipos de datos compuestos (también conocidos como colecciones) son RECORD,
TABLE, NESTED TABLE y VARRAY. Se utiliza el tipo de dato RECORD para los datos
relacionados pero datos diferentes como una unidad lógica. Se usa el tipo de dato TABLE
para referirse y manipular datos obtenidos.
Un registro es un grupo de de datos relacionados almacenados en campos, cada uno con un
nombre y tipo de dato propio.
Una tabla contiene a una columna y una llave primaria para accesar a sus filas. Una vez
definidas las filas, tablas y registros pueden ser reutilizados.
Registros en PL-SQL
Un registro es un grupo de datos relacionados almacenados en campos, cada uno con un
nombre y tipo de dato propio.
Por ejemplo, supóngase que se tienen diversas clases de datos sobre un empleado, tal como
nombre, sueldo, fecha, etcétera. Estos datos están lógicamente relacionados.
Un expediente que contiene los campos tales como el nombre, el sueldo, y la fecha de un
empleado le deja tratar los datos como unidad lógica. Cuándo usted declara un tipo de
registro para estos campos, este puede ser manipulado como unidad.
1. Cada expediente definido puede tener tantos campos como sean necesarios.
2. Los expedientes se pueden asignar valores iniciales y se pueden definir como NOT
NULL.
3. Los campos sin valores iniciales se inicializan con NULL.
4. La palabra clave DEFAULT puede también ser utilizada al definir campos.
5. Se pueden definir tipos RECORD y declarar registros definidos por el usuario en la
parte declarativa de cualquier bloque, subprograma, o paquete.
6. Se puede declarar y referirse a expedientes jerarquizados. Un expediente puede ser
el componente de otro expediente.
Definir y declarar registros en PL-SQL
Para crear un registro, se define un tipo RECORD y después se declaran registros de ese
tipo.
TYPE nombre_registro IS RECORD
(campo_declarado[, campo_declarado]..);
identificador nombre_registro

donde:
campo_declarado {tipo_campo | variable%TYPE
| tabla.columna%TYPE | tabla%ROWTYPE}
[[NOT NULL] { := | DEFAULT} expresion]

Sintaxis:
registro: es el nombre del tipo RECORD(este identificador se utiliza para declarar
registros).
campo: es el nombre de un campo dentro del registro.
tipo-campo: es el tipo de dato de un campo (representa cualquier tipo de dato de
PL-SQL excepto REF CURSOR. Se puede utilizar el atributo %TYPE y el atributo
%ROWTYPE.).
expresión: es el tipo de dato de un campo o un valor inicial.
El NOT NULL asigna valores nulos a estos campos. Hay que asegurarse de
inicializar los campos NOT NULL.
Creando registros en PL-SQL
Cada campo tiene un nombre único y un tipo de dato específico. No hay tipos de datos
predefinidos para los registros en PL-SQL, solo hay para las variables escalares. Por lo
tanto, primero se debe crear el tipo de dato y en seguida declarar un identificador usando
ese tipo de dato.

DECLARE
TYPE emp_record_type IS RECORD
(empno NUMBER(4) NOT NULL := 100;
ename emp.ename%TYPE,
job emp.job%TYPE);
emp_record emp_record_type;
. . .

Referenciando e inicializando registros


Los campos en un registro son accesados por su nombre. Para referenciar o inicializar un
campo individual, debe utilizar la notación del punto y la sintaxis siguiente:

record_name.field_name

En un bloque o subprograma usar registros definidos por el usuario, debe estar inicializado
cuando se entra al bloque o subprograma y deja de existir cuando se sale del bloque o
subprograma.
Asignar valores a los registros
Se puede asignar una lista de valores comunes a un registro usando la declaración
SELECT o FETCH. Hay que asegurarse de que los nombres de la columna aparezcan en el
misma orden que los campos en el registro. Se puede también asignar un registro a otro si
tienen el mismo tipo de dato. Un registro definido por el usuario y el registro %ROWTYPE
nunca tienen el mismo tipo de dato.
Declarando registros con el atributo %ROWTYPE
Para declarar un registro basado en una colección de columnas de una tabla de la base de
datos o vista, se debe utilizar el atributo %ROWTYPE. Los campos en el registro toman
sus nombres y tipos de datos de las columnas de la tabla o vista.
El registro puede también almacenar una fila entera datos traídos de un cursor o variable de
tipo cursor.
Sintaxis:

DECLARE identificador reference%ROWTYPE


.......

Sintaxis:
identificador: es el nombre elegido por el registro como un todo.
referencia: es el nombre de la tabla, vista, cursor, o la variable de tipo cursor en la
cual se base el registro (hay que asegurarse de que esta referencia sea válida cuando
se declara el registro es decir, la tabla o la vista deben existir.) .
Para referirse a un campo individual, se debe utilizar la notación del punto y la siguiente
sintaxis:
record_name.field_name

Tablas en PL-SQL
Los objetos de tipo TABLE se llaman las tablas de PL-SQL. Se modelan como (pero no
iguales que) tablas de la base de datos. Las tablas de PL-SQL utilizan una llave primaria
para determinar como será el acceso a sus filas.
Una tabla en PL-SQL es :
o Similar a un arreglo
o Debe de contener los siguientes elementos:
o Una llave primaria del tipo de dato BINARY_INTEGER que pone un
índice a la tabla de PL-SQL
o Una columna de un tipo de dato escalar o registro, que almacene los
elementos de la tabla de PL-SQL
o Puede aumentar dinámicamente porque es libre.
Creando una tabla de PL-SQL
Existen dos pasos implicados al crear una tabla de PL-SQL.
1. Declare un tipo de dato TABLE.
2. Declare una variable de ese tipo de dato.
3.
TYPE nombre_tipo IS TABLE OF
{tipo_columna | variable%TYPE
| tabla.columna%TYPE} [NOT NULL]
[INDEX BT BINARY_INTEGER];
identificador nombre_tipo;

Sintaxis:
nombre_tipo: es el nombre del tipo de dato TABLE(es un tipo específico usado en
declaraciones subsecuentes por las tablas de PL-SQL.).
tipo-columna: es cualquier tipo de dato(no compuesto) escalar tal como
VARCHAR2, DATE, o NUMBER (se puede utilizar el atributo %TYPE para
proporcionar el tipo de dato de la columna.).
identificador: es el nombre del identificador que representa una tabla entera de PL-
SQL.
No hay ningún tipo de dato predefinido para las tablas de PL-SQL, solo existe para las
variables escalares. Por lo tanto primero se debe crear un tipo de dato y en seguida declarar
un identificador usando ese tipo de dato.
Referirse a una tabla de PL-SQL

Sintaxis:

pl/sql_table_name (primary_key_value)

Sintaxis:
valor-primary_key: pertenece al tipo de dato BINARY_INTEGER
Con esta declaración nos referimos a la tercera fila a una tabla de PL-SQL
ename_table (3)....
El rango de magnitud para un BINARY_INTEGER es 2147483647... 2147483647, así que
el valor de la llave primaria puede ser negativo. El valor de un índice no necesita empezar
con 1.
La declaración table.EXIST(i) regresa TRUE devuelve por lo menos una fila con el indice
(i) Utilice la declaración de EXISTS para prevenir un error que se levante en referencia a
un elemento de tabla no-existente.
Un método de la tabla de PL-SQL es un procedimiento o una función incorporado que
funciona encendido las tablas y se llama usando la notación del punto. Los métodos
conocidos con un asterisco abajo están disponibles para las tablas de la versión 8 de PL-
SQL solamente.

Sintaxis:

table_name.method_name (parameters)

Algunos métodos para las tablas en PL-SQL son :


o EXISTS
o COUNT
o FIRST y LAST
o PRIOR
o NEXT
o EXTEND
o TRIM
o DELETE
Estructura de una tabla de PL-SQL
Como el tamaño de una tabla en una base de datos, el tamaño de una tabla en PL-SQL es
libre. Es decir, el número de filas en una tabla de PL-SQL puede aumentar dinámicamente,
la tabla de PL-SQL crece mientras que se agregan nuevas filas.
Las tablas de PL-SQL pueden tener una columna y una llave primaria, ninguna de estás
puede ser llamada. La columna puede pertenecer a cualquier tipo de dato escalar o registro,
pero la llave primaria debe pertenecer al tipo de dato BINARY_INTEGER. No se puede
inicializar una tabla de PL-SQL en su declaración.
Tabla de registros de PL-SQL
En ocasiones es necesario obtener información acerca de todos los campos de una tabla de
la base de datos, la tabla de registros aumenta grandemente la funcionalidad de las tablas de
PL-SQL.
Refiriéndose a una tabla de registros, se puede referir campos en el registro dept_table
porque cada elemento de esta tabla es un registro.

DECLARE
TYPE e_table_type IS TABLE OF emp.ename%TYPE
INDEX BY BINARY_INTEGER
e_tab e_table_type;
BEGIN
e_tab(1) := 'SMITH';
UPDATE emp
SET sal = 1.1 * sal
WHERE ename = e_tab(1);
COMMIT;
END;

Se puede utilizar el atributo %ROWTYPE para declarar un registro que represente una fila
de una tabla de la base de datos. La diferencia entre el atributo %ROWTYPE y el
RECORD, es que RECORD permite que se especifique los tipos de datos de los campos en
el registro o que declaren los campos sus el propios tipos de datos.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Unidad 21 Cursores explícitos
Objetivo: El alumno será capaz de distinguir entre un
cursor implícito y un curso explícito, uso de variables PL-
SQL y escribir cursores con el ciclo FOR.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Cursor de SQL
Siempre que se publique una declaración de SQL, el servidor Oracle abre un área de
memoria en la cual se analiza y se ejecuta el comando. Esta área se llama cursor. PL-SQL
crea un cursor implícito, que tiene el identificador del SQL. PL-SQL maneja este cursor
automáticamente. El programador puede declarar y nombrar un cursor explícito.
Hay cuatro cualidades disponibles en PL-SQL que se pueda aplicar a los cursores.
Atributos del cursor de SQL
Los atributos del cursor de SQL permiten que se evalúe lo que sucedió cuando el cursor
implícito fue utilizado por última vez.
Estos atributos se utilizan en declaraciones de PL-SQL tales como funciones. Pero no
pueden ser utilizados en declaraciones del SQL.
Los atributos que se pueden utilizar son, SQL%ROWCOUNT, SQL%FOUND, SQL
%NOTFOUND, y SQL%ISOPEN en la sección de la excepción de un bloque para
recopilar la información sobre la ejecución de una declaración de manipulación de datos.
PL-SQL no considera una declaración de DML que no afecte ninguna fila por haber
fallado, semejante en la declaración SELECT, que regrese una excepción.

SQL% ROWCOUNT Número de renglones afectados por la mas reciente declaración de SQL
SQL%FOUND Atributo booleano que devuelve un TRUE si la mas reciente
declaración de SQL afecto uno o más filas
SQL%NOTFOUND Atributo booleano que devuelve un TRUE si la mas reciente
declaración de SQL no afecto ninguna fila
SQL%ISOPEN Siempre se evalúa FALSE porque PL-SQL cierra los cursores
implícitos inmediatamente después de que fueron ejecutados

Cursores implícitos y explícitos


El servidor Oracle utiliza áreas de trabajo llamadas áreas privadas de SQL para ejecutar una
declaración de SQL y para almacenar el proceso de la información. Se pueden utilizar
cursores de PL-SQL para nombrar un área privada del SQL y para tener acceso a su
información almacenada. El cursor dirige todas las fases del proceso.

Tipo de cursor Descripción


Implícito Los cursores implícitos son declarados por PL-SQL para las declaraciones de DML y
declaraciones de tipo SELECT, incluyendo querys que devuelven solamente una fila.
Explícito Para querys que devuelven más de una fila. Los cursores explícitos son declarados y
nombrados por el programador y manipulados con la declaración específica en las
acciones ejecutables del bloque.

Cursores implícitos
El servidor Oracle abre un cursor implícito para procesar cada declaración del SQL no
asociada a un cursor explícitamente declarado. PL-SQL permite que la declaración de SQL
haga referencia al cursor implícito más reciente como el cursor del SQL. No se pueden
utilizar las declaraciones OPEN, FETCH y CLOSE para controlar los cursores del SQL,
pero se pueden utilizar cualidades del cursor para conseguir la información sobre la
declaración más recientemente ejecutada de SQL.
Cursores explícitos
Se usan cursores explícitos para procesos para procesar individualmente cada fila que
devuelve una declaración SELECT para múltiples filas.
El sistema devuelve filas por un query de múltiples filas a lo que se conoce como el sistema
activo. Su tamaño es el número de las filas que devuelve de acuerdo a un criterio de
búsqueda.
Un programa de PL-SQL abre un cursor, para devolver filas procesadas por un query, y
después cierra el cursor. El cursor marca la posición actual en el sistema activo.
Funciones explícitas del cursor:
o Puede procesar más de allá de la primera fila devuelta por un query, fila por fila
o No perder de vista qué fila se está procesando actualmente
o Permitir que el programador los controle manualmente en el bloque de PL-SQL
Los cursores se controlan usando cuatro comandos:
o Declare el cursor por su nombre y defina la estructura del query al que se refiere
o Abra el cursor. La declaración OPEN ejecuta los querys y cualquier variable de tipo
bind a la que se refiera. Las filas identificadas por el query se llaman sistema activo
y están disponibles para ser mostradas
o Mostrar los datos del cursor
o Cerrar el cursor. La declaración CLOSE lanza el sistema activo de filas. Ahora es
posible abrir de nuevo el cursor para establecer un sistema activo nuevo
Se usan las declaraciones de OPEN, FETCH y CLOSE para controlar un cursor. La
declaración CLOSE ejecuta el query asociada al cursor, identifica el sistema activo, y
coloca el cursor (indicador) antes de la primera fila. La declaración FETCH recupera la fila
actual y avanza el cursor a la fila siguiente. Cuando se ha procesado la fila pasada, la
declaración CLOSE inhabilita el cursor.

CURSORES EXPLICITOS

DECLARE OPEN FETCH EMPTY? CLOSE

Declaración de un cursor explícito


Se usa la declaración CURSOR para declarar un cursor explícito. Se puede hacer referencia
a variables dentro del query, pero deben ser declararlas antes de la declaración del
CURSOR.

CURSOR nombre_cursor IS
declaracion_select;
Sintaxis:
nombre_cursor: es un identificador de PL-SQL
declaracion_select: es una declaración SELECT sin una cláusula INTO

DECLARE
CURSOR emp_cursor IS
SELECT empno, ename
FROM emp;

CURSOR dept_cursor IS
SELECT *
FROM dept
WHERE deptno = 10;
BEGIN
........

No incluya la cláusula INTO en la declaración del cursor porque aparece más adelante en la
declaración del FETCH.
Declaración OPEN
Abra el cursor para ejecutar el query y para identificar el sistema activo, que esta
constituido por todas las filas que son devueltos de acuerdo a los criterios de la búsqueda
del query. El cursor ahora señala a la primera fila en el sistema activo.

OPEN nombre_cursor;

Sintaxis:
cursor: es el nombre del cursor previamente declarado
OPEN es una declaración ejecutable que realiza las siguientes operaciones:
o Asigna dinámicamente la memoria para un área del contexto que contenga
eventualmente la información del proceso actual
o Analiza la declaración SELECT
o Variables de entrada de tipo bind: es el valor de las variables de entrada
obteniendo sus direcciones de memoria
o Identifica el sistema activo: que es el sistema de filas que satisfacen los
criterios de la búsqueda. Las filas en el sistema activo no se recuperan en
variables cuando se ejecuta la declaración OPEN. La declaración FETCH
recupera las filas
o Coloca el indicador antes de la primera fila en el sistema activo
Si el query no devuelve ninguna fila cuando se abre el cursor, PL-SQL no genera una
excepción(error). Sin embargo, se puede probar el estado del cursor después de que
devuelve valores. Para cursores declarados usando la cláusula FOR UPDATE, la
declaración de OPEN también bloquea esas filas.
Declaración FETCH
La declaración FETCH recupera las filas en el sistema activo una a la vez. Después de
recuperar cada una, el cursor avanza a la fila siguiente en el sistema activo.

OPEN nombre_cursor INTO [variable1,variable2, . . . ]


| nombre_registro];

Sintaxis:
cursor: es el nombre del cursor previamente declarado
variable: es una variable de salida para almacenar los resultados
registro: es el nombre del registro en el cual se almacenan los datos recuperados
(la variable de tipo registro se puede declarar usando el atributo %ROWTYPE.)
Se recomienda Incluir el mismo número de variables en la cláusula INTO para la
declaración FETCH como columnas en la declaración SELECT, y hay que asegurarse de
que los tipos de datos son compatibles.
Verificar que la posición de las variables correspondan a las posiciones de las columnas.
Definir un registro para el cursor y referirse al registro in la cláusula FETCH INTO
Verificar que el cursor contiene filas. Si no devuelve ningún valor, no hay filas a la
izquierda en el sistema activo y no se registra ningún error.
La declaración FETCH realiza las siguientes operaciones:
o Avanza el puntero a la fila siguiente en el sistema activo
o Lee los datos para la fila actual en las variables de salida PL-SQL
Se utiliza la declaración FETCH para recuperar los valores actuales de la fila en variables
de salida. Después de devolver los filas, se pueden manipular las variables por otras
declaraciones. Para cada valor de la columna devuelto por el query se asocia al cursor, debe
haber una variable correspondiente en en la lista INTO. También, sus tipos de datos deben
ser compatibles.
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
CURSOR emp_cursor IS
SELECT empno, ename
FROM emp;
BEGIN
OPEN emp_cursor;
FOR i IN 1..10 LOOP
FETCH emp_cursor INTO v_empno, v_ename
……..
END LOOP;
END;

Declaración CLOSE
La declaración CLOSE inhabilita el cursor, y el sistema activo llega a ser indefinido. Hay
que cerrar el curso después de terminar el proceso de la declaración SELECT. Este paso
permite que el cursor sea abierto de nuevo, si es requerido. Por lo tanto, se puede establecer
un sistema activo varias veces.

CLOSE nombre_cursor;

Sintaxis:
nombre_cursor: es el nombre del cursor previamente declarado.
No procure traer datos de un cursor una vez que haya estado cerrado, o se generara la
excepción INVALID_CURSOR.
Aunque es posible terminar el bloque de PL-SQL sin cerrar los cursores, se deben cerrar,
ya que cualquier cursor que se declare explícitamente si este se cierra puede liberar
recursos. Hay un límite máximo para el número de cursores abiertos por el usuario, que es
determinado por el parámetro OPEN_CURSORS en la base de datos, 50 es el valor por
default.
Atributo de los cursores explícitos
Así como en los cursores implícitos, existen cuatro atributos para obtener la información de
un cursor.
Cuando se añadan nombre a las variables del cursor, esto atributos devuelven información
útil sobre la ejecución de una declaración de manipulación de datos.
No se puede hacer referencia a los atributos del cursor directamente en una declaración del
SQL.
......
FOR i IN 1..10 LOOP
FETCH emp_cursor INTO
v_empno, v_ename;
…….
END LOOP;
CLOSE emp_cursor;
END;

Controlando múltiples valores


Para procesar varias filas de un cursor explícito, se define típicamente un loop para
recuperar cada fila a través de cada iteración. Todas las filas en el sistema activo se
procesan eventual, y un fracaso hace que el atributo %NOTFOUND sea TRUE. Hay que
usar los atributos de los cursores explícitos para que cada recuperación sea exitosa antes de
que se haga cualquier otra referencia al cursor. Si se omite un criterio de la salida, se genera
un loop infinito.
Atributos de los cursores explícitos:
o Se pueden recuperar filas solamente cuando el cursor este abierto. Hay que usar el
atributo %ISOPEN del cursor para determinar si el cursor está abierto, si es
necesario.
o Recuperar filas con un loop. Hay que usar los atributos del cursor para determinar
cuando salir del loop
o Hay que usar el atributo %ROWCOUNT del cursor para recuperar un número
exacto de filas, para recuperar las filas como un numero FOR lopp, o para traer las
filas en un loop simple y para determinar cuando salir del loop
Hay que usar el atributo %ROWCOUNT del cursor para recuperar un número exacto de
filas, para recuperar las filas como un numero FOR lopp, o para traer las filas en un loop
simple y para determinar cuando salir del loop.
El %ISOPEN regresa el estado del cursor: TRUE indica si esta abierto y FALSE si no lo
está. No es necesario examinar el atributo %ISOPEN.
Cursores y registros
Se pueden definir registros para utilizar la estructura de columnas en una tabla. Se puede
también definir un registro basado en una lista seleccionada de columnas en un cursor
explícito. Esto es conveniente para procesar las filas del sistema activo porque se puede
recuperar en el registro. Por lo tanto, los valores de la fila se cargan directamente en los
campos correspondientes del registro.
Cursores FOR Loops
El cursor FOR Loop procesa filas en un cursor explícito. Esto es un atajo porque se abre el
cursor, las filas se recuperan una vez para cada iteración en el loop, y el cursor está cerrado
automáticamente cuando se han procesado todas las filas. El mismo loop se termina
automáticamente al final de la iteración donde la fila ultima fila fue recuperada.
FOR nombre_registro IN nombre_cursor LOOP
declaracion1;
declaracion2;
. . .
END LOOP;

Sintaxis:
nombre_registro: es el nombre del registro implícito declarado.
nombre_cursor: es un identificador de PL-SQL para el cursor previamente
declarado.
1. Se recomienda que no declare registro que controlen el loop. Este control solo
está en el loop.
2. Pruebe los atributos del cursor durante el loop, si se requiere.
3. Mandar parámetros a un cursor, si se requiere, en paréntesis después del nombre
del cursor en la declaración FOR.
4. No utilice un cursor FOR Loop cuando las operaciones del cursor se deben
manejar manualmente.

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor IS
SELECT ename,deptno
FROM emp;
BEGIN
FOR emp_record IN emp_cursor LOOP
IF emp_record.deptno = 30 THEN
DBMS_OUTPUT.PUT_LINE ('Employee'||emp_record.ename||'works in the Sales Dept,');
END IF;
END LOOP;
END;
/

Se puede definir un query al inicio del mismo loop. La expresión del query es llamada
subdeclaración SELECT, y el cursor es interno para el FOR Loop. Porque el cursor no se
declara con un nombre, no se pueden probar sus atributos.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Práctica 21: Cursores explícitos.

1. Run the script lab21_1.sql to create a new table for storing employees and their
salaries.

SQL> CREATE TABLE top_dogs


2 (name VARCHAR2(25),
3 salary NUMBER(ll,2);

2. Create a PL-SQL block that determines the top employees with respect to salaries.

a. Accept a number n as user input with a SQL*Plus substitution parameter.

b. In a loop, get the last names and salaries of the top n people with respect to
salary in the EMP table.

c. Assume that no two employees have the same salary.

d. Test a variety of special case, such as n = 0 or where n is greater than the


number of employees in the EMP table. Empty the TOP_DOGS table after each
test.

Please enter the number of top money makers: 5

NAME SALARY
----------------- ------------
KING 5000
FORD 3000
SCOTT 3000
JONES 2975
BLAKE 2850

3. Consider the case where several employees have the same salary. If one person is
listed, then all people who have the same salary should also be listed.

a. For example is the user enters a value of 2 for n, then


King, Fors, and Scott should be displayed. (These employees are tired for
second highest salary).

b. If the user enters a value of 3, then King, Ford, Scott,


and Jones should be displayed.
c. Delete all rows from TOP_DOGS and test the
practice.

Please enter the number of top money makers: 2

NAME SALARY
----------------- ------------
KING 5000
FORD 3000
SCOTT 3000

Please enter the number of top money makers: 3

NAME SALARY
----------------- ------------
KING 5000
FORD 3000
SCOTT 3000
JONES 2975
Unidad 22 Conceptos avanzados de
cursores explícitos
Objetivo: El alumno será capaz de escribir cursores con
paso de parámetros, determinar cuando utilizar la cláusula
WHERE CURRENT OF y escribir cursores con sub-
consultas..

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Cursores con parámetros


Los parámetros permiten que se puedan pasar valores a un cursor cuando se abre y ser
utilizados en el query cuando se ejecuta. Esto significa que puede abrirse y cierrarse un
cursor explícito varias veces en un bloque, volviendo un diferente sistema activo en cada
ocasión.
Cada parámetro formal en la declaración del cursor debe tener un parámetro real
correspondiente en la declaración OPEN. Los tipos de datos del parámetro son iguales que
para las variables escalares, pero no se les da un tamaño. Los nombres
del parámetro se usan para hacer referencias en la expresión del query del cursor.
CURSOR nombre_cursor
[(nombre_parametro tipo_dato, . . .)]
IS
declaracion_select;

Sintaxis:
nombre_cursor: es un identificador de PL-SQL para el cursor previamente
declarado.
nombre_parametro: es el nombre de un parámetro .
tipo_dato: es un tipo de dato escalar para el parámetro .
declaracion_select: es una declaración SELECT fuera de la cláusula INTO.
Cuando se abre el cursor, se pasan valores a cada uno de los parámetros. Se pueden pasar
valores PL-SQL o las variables del anfitrión así como literales.

DECLARE
CURSOR emp_cursor(p_deptno NUMBER, p_job VARCHAR2) IS
SELECT empno, ename
FROM emp
WHERE deptno = v_deptno AND job = v_job;
BEGIN
OPEN emp_cursor(10,'CLERK');
.......

La notación del parámetro no ofrece mayor funcionalidad; permite simplemente que se


especifiquen valores de la entrada fácilmente y claramente. Esto es particularmente útil
cuando el mismo cursor se refiere en varias ocasiones.
Los tipos de datos de los parámetros son iguales que los de las variables escalares, pero no
se les da un tamaño. Los nombres del parámetro se usan para hacer referencia al query del
cursor.
Cláusula FOR UPDATE
Si se desean bloquear filas antes de que se ejecute una actualización o borrado de filas. Hay
que Agregar la cláusula FOR UPDATE en el query del cursor para bloquear las filas
afectadas cuando se abre el cursor. Porque el servidor de Oracle bloquea estás al terminar la
transacción, no es necesario confirmar la transacción para un cursor explícito si usa la
cláusula FOR UPDATE.
SELECT ...
FROM
FOR UPDATE [OF columna_referenciada][NOWAIT;]

Sintaxis:
columna_referenciada: es una columna en la tabla en la cual se realiza el query
(Se puede usar una lista de columnas)
NOWAIT: devuelve un error de Oracle si las filas son bloqueadas por otra sesión
La cláusula FOR UPDATE es ignorada en una declaración select, incluso después del
ORDER BY, si existe alguna.
Cuando existen querys para múltiples tablas, se puede utilizar la cláusula FOR UPDATE
para bloquear filas de tablas particulares. Las filas en una tabla se bloquean solamente si la
cláusula FOR UPDATE hace referencia a una columna de esa tabla.

DECLARE
CURSOR emp_cursor IS
SELECT empno, ename, sal
FROM emp
WHERE deptno = 30
FOR UPDATE OF sal NOWAIT

Si el servidor Oracle no puede bloquear filas se necesita un SELECT FOR UPDATE, que
espera indefinidamente. Se puede utilizar la cláusula de NOWAIT con la declaración de
SELECT FOR UPDATE. Por lo tanto, se puede revisar, abrir el cursor n veces antes de
terminar el bloque de PL-SQL.
Si se tiene una tabla grande, se puede alcanzar un funcionamiento mejor usando la
declaración de LOCK TABLE, para bloquear todas las filas de la tabla. Sin embargo, al
usar LOCK TABLE, no se puede utilizar la cláusula WHERE CURRENT y debe utilizar la
notación WHERE columna = identificador. No es obligatorio que para la cláusula FOR
UPDATE se refiera a una columna, pero se recomienda para un mejor mantenimiento y
legibilidad.
Cláusula WHERE CURRENT OF
Cuando nos referimos a la fila actual de un cursor explícito, hay que utilizar la cláusula
WHERE CURRENT OF . Esto permite que se apliquen actualizaciones y cancelaciones a
la fila que es tratada actualmente, sin la necesidad de referirse explícitamente a ROWID.
Se debe incluir la cláusula FOR UPDATE en el query del cursor de modo que las filas sean
bloqueadas en OPEN.

WHERE CURRENT OF cursor;


Sintaxis:
cursor: es el nombre de un cursor declarado (el cursor debe ser declarado con la
cláusula FOR UPDATE)
DECLARE
CURSOR sal_cursor IS
SELECT sal
FROM emp
WHERE deptno = 30
FOR UPDATE OF sal NOWAIT;
BEGIN
FOR emp_record IN sal_cursor LOOP
UPDATE emp
SET sal = emp_record.sal * 1.10
WHERE CURRENT OF sal_cursor;
END LOOP;
COMMIT;
END;

Se pueden actualizar las filas basadas en criterios de un cursor. Además, se puede escribir
la declaración de DELETE o UPDATE para contener la cláusula WHERE CURRENT OF
cursor_name para referirse a la última fila procesada por la declaración del FETCH.
Cuando se utiliza esta cláusula, el cursor al que se hace referencia debe existir y debe
contener la cláusula FOR UPDATE en el query del cursor; si no es así , se generara un
error. Esta cláusula permite que se apliquen actualizaciones y cancelaciones a la fila
actualmente tratada sin la necesidad de referirse explícitamente a la pseudo-columna de
ROWTD.
Cursores con Subqueries
Un subquery es una query (incluido generalmente entre paréntesis) que aparece dentro de
otra declaración de la manipulación de datos del SQL. Cuando está evaluado el subquery
proporciona un valor o un sistema de valores a la declaración.
DECLARE
CURSOR my_cursor IS
SELECT t1.deptno, ti.dname, t2.STAFFl
FROM dept t1, (SELECT deptno, count(*) STAFF)
FROM emp
GROUP BY deptno) t2
WHERE t1.deptno = t2.deptno AND t2.STAFF>5

Los Subqueries se utiliza a menudo en la cláusula WHERE de una declaración select. Estos
también se pueden utilizar en la cláusula FROM, Creando una fuente de datos temporal
para es query. Un subquery o un subquerv correlacionado pueden ser utilizados.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Práctica 22: Conceptos avanzados de cursores explícitos

Utilice un cursor para obtener el número y nombre del departamento de la tabla dept. Lleve
el número de departamento a otro cursos para obtener de la tabla emp los detalles de
nombre del empleado, trabajo, fecha de contratación y salario de todos los empleados que
trabajan en ese departamento.

Department Number : 10 Department Name : ACCONTING

NAME JOB HIREDATE SALARY


----------- ---------- --------- ------
KING PRESIDENT 17-NOV-81 5000
CLARK MANAGER 09-JUN-81 2450
MILLER CLERK 23-JAN-82 1300

Department Number : 20 Department Name : RESEARCH

NAME JOB HIREDATE SALARY


----------- ---------- --------- ------
JONES MANAGER 02-APR-81 2975
FORD ANALYST 03-DEC-81 3000
SMITH CLERK 17-DEC-80 800
SCOTT ANALYST 09-DEC-82 3000
ADAMS CLERK 12-JAN-83 1100

Department Number : 30 Department Name : SALES

NAME JOB HIREDATE SALARY


----------- ---------- --------- ------
BLAKE MANAGER 01-MAY-81 2850
MARTIN SALESMAN 28-SEP-81 1250
ALLEN SALESMAN 20-FEB-81 1250
TURNER SALESMAN 08-SEP-81 1500
JAMES CLERK 03-DEC-81 950
WARD SALESMAN 22-FEB-81 1250

Department Number : 40 Department Name : OPERATIONS

Modifica p19q5.sql de manera que incorpore la funcionalidad de FOR UPDATE y


WHERE CURRENT OF en el procesamiento de cursores.

EMPNO SAL STARS


---------- ---------- ----------------------------------
8000
7900 950 **********
7844 1500 ***************
Unidad 23 Manejo de excepciones
Objetivo: El alumno será capaz de definir excepciones PL-
SQL, listar y utilizar los diferentes tipos de manejo de
excepciones, atrapar en forma anticipada los errores
generados por el servidor Oracle, describir el efecto de
propagación en excepciones anidadas y personalizar
mensajes de excepciones PL-SQL.

Sugerencias didácticas
Mostrar al alumno programas completos desarrollados en SQL de menor a mayor grado de
dificultad y con base en cada una de las instrucciones que los componen, enseñar la sintaxis
del lenguaje y la finalidad de cada una de ellas.
Solicitar que corrobore la validez del mismo, ejecutándolo en la computadora.
Solicitarle la elaboración de programas similares, agregándoles algunas variantes.
Solicitarle al alumno propuestas de problemas a resolver y que sean significativas para él.
Sugerencias de evaluación
El docente deberá considerar la evaluación, no solo como un medio de medir el
aprendizaje, sino como un indicador para enriquecer el proceso enseñanza-aprendizaje,
además de los exámenes tradicionales se recomienda se tome en cuenta: participación en
clases, elaboración de prácticas en el laboratorio y proyectos.

Excepciones en PL-SQL
Una excepción es un identificador en PL-SQL, que se genera durante la ejecución de un
bloque cuando termina de realizar sus acciones. Un bloque termina siempre cuando PL-
SQL genera una excepción pero se pueden tratar las excepciones para realizar acciones
finales.
Métodos para general una excepción
Un error en Oracle ocurre y la excepción asociada se genera automáticamente.
Por ejemplo, si ocurre el error Ora-01403 cuando no se recupera ninguna fila de la base de
datos en una declaración SELECT, entonces PL-SQL genera la excepción
NO_DATA_FOUND
Si se genera una excepción explícitamente publicando la declaración RAISE dentro del
bloque. La excepción puede ser generada por cualquier usuario definido o predefinido.
Atrapar una excepción
Si la excepción se genera en la sección ejecutable del bloque, se generan una serie de
excepciones más a partir de la primera excepción generada en el bloque. Si PL-SQL maneja
con éxito la excepción, la excepción no generara mas excepciones dentro del bloque o el
ambiente que incluye.
Tipos de excepción
Existen 3 tipos de excepciones:

Excepciones Descripción Direcciones para dirigir


Error predefinido por el Uno de aproximadamente 20 No declara y no permite que el servidor
servidor Oracle errores que ocurren lo más a Oracle los genere implícitamente
menudo posible en PL-SQL
Error no predefinido por el Cualquier otro error estándar del Declara dentro de la sección declarativa
servidor Oracle servidor Oracle y permite que el servidor del oráculo los
genere implícitamente
Errores definidos por el Se declara dentro de la sección
usuario declarativa y se genera explícitamente

Algunas herramientas de uso para el cliente en PL-SQL, tal como FORMS de Oracle
Developer, tienen sus propias excepciones.
Se puede atrapar cualquier error incluyendo una rutina correspondiente dentro de la sección
de la dirección de excepción del bloque de PL-SQL. Cada uno en la cláusula WHEN, que
especifica una excepción, seguido por una secuencia de declaraciones que se ejecutarán
cuando se genere esa excepción.

EXCEPTION
WHEN excepcion1 [OR excepcion2 . . .] THEN
declaracion;
declaracio2;
. . .
[WHEN excepcion3 [OR excepcion4 . . .] THEN
declaracion;
declaracio2;
. . .]
[WHEN OTHERS THEN
declaracion;
declaracio2;
. . .]

Sintaxis:
excepción: es el nombre estándar de una excepción predefinida o el nombre de una
excepción definida por el usuario declarada dentro de una sección declarativa.
declaracion: una o más declaraciones PL-SQL.
OTHERS: es una excepción opcional que atrapa excepciones sin especificar.
Excepciones WHEN OTHERS
La excepción atrapa solamente las excepciones especificadas; ninguna otra excepción es
atrapada a menos que se utilice la tratante de excepción OTHERS. Esto atrapa cualquier
excepción que no había sido manejada. Por esta razón, OTHERS es el tratante de las
excepción que no fueron definidas.
Algunas herramientas de Oracle tienen sus propias excepciones predefinidas que se pueden
levantar para causar acontecimientos en el uso. OTHERS también atrapa estas excepciones.
Excepciones predefinidas
Nombre de la Excepción Error en el Descripción
servidor Oracle
ACCESS_INTO_NULL ORA-06530 Procuró asigna valores a los atributos de los
objetos no inicializados

COLLECT1ON_IS_NULL ORA-06531 Procuró aplicar otros métodos de colección con


EXISTS

CURSOR_ALREADY_OPEN ORA-06511 Procuró abrir un cursor que ya se abrío

DUP_VAL_ON_INDEX ORA-00001 Procuró inserta un valor duplicado

INVALID_CURSOR ORA-01001 Ocurrió una operación ilegal del cursor

INVALID_NUMBER ORA-01722 Falló la conversión de la cadena de caracteres en


número

LOGIN_DEFINED ORA-01017 Entrar a Oracle con un nombre de usuario y


contraseña no validos

NO_DATA_FOUND ORA-01403 El SELECT no regreso datos

NOT_LOGGED_ON ORA-01012 El programa de PL-SQL publica una llamada a la


base de datos cuando Oracle esta conectado

PROGRAM_ERROR ORA-06501 PL-SQL tiene un problema interno

ROWTYPE_MISMATCH ORA-06504 La variable cursor del ambiente anfitrión y la


variable cursor de PL-SQL en una asignación
tienen tipos de datos incompatibles
STORAGE_ERROR ORA-116500 PL-SQL se salió del rango de memoria o la
memoria es corrupta
SUBSCRIPT_BEYOND_COUNT ORA-06533 Se refirió a una tabla jerarquizada o a un elemento
varray usando un número de índice más grande
que el número de elementos en la colección
SUBSCRIPT_OUTS1DE_LIMIT ORA-06532 Se refirió a una tabla jerarquizada o a un elemento
varray usando un número de índice más grande
que está fuera de rango (- 1)
TIMEOUT_ON_RESOURCE ORA-00051 La temporización ocurrió mientras que Oracle está
esperando un recurso

TOO_MANY_ROWS ORA-01422 SELECT regreso mas de un valor

VALUE_ERROR ORA-06502 Ocurrio un error Aritmético, conversión,


truncamiento, o error de constraint.

ZERO_DIVIDE ORA-01476 Error al dividir entre cero.

Excepciones predefinidas
Atrapando errores No-Predefinidos del servidor Oracle
Se puede atrapa un error no-predefinido del servidor Oracle declarándolo primero, o usando
el comando OTHERS. La excepción declarada se levanta de forma implícita. En PL-SQL,
el pragma EXCEPTION_INIT dice al recopilador que debe asociar un nombre de
excepción a un número de error de Oracle. Nota: El PRAGMA (también llamado
pseudoinstrucion) es la palabra clave que significa que la declaración es un directorio del
recopilador que no se procesa cuando en el bloque de PL-SQL se ejecuta algo, ordena al
recopilador de PL-SQL interpretar todas las ocurrencias del nombre de la excepción dentro
del bloque con el número asociado de error de servidor Oracle.
Para atrapar los errores no-predefinidos, realizar las siguientes acciones:
1. Declare el nombre para la excepción dentro de la sección declarativa.
exception EXCEPCION;
Donde excepción: es el nombre de la excepción.
2. Asocie la excepción declarada al número estándar del error del servidor Oracle
usando la declaración del PRAGMA EXCEPTION_INIT.
PRAGMA EXCEPTION_INIT(excepción, numero de error);
Donde excepción: es la excepción previamente declarada y numero de error: es un
número estándar del error del servidor Oracle
3. Refiérase a la excepción declarada dentro de la rutina de excepción – dirección
correspondiente.
PRAGMA EXCEPTION_INIT(excepción, numero de error);
Donde excepción: es la excepción previamente declarada y numero de error: es un
número estándar del error del servidor Oracle
Ejemplo: Si hay empleados en un departamento, imprima un mensaje al usuario que el
departamento no puede ser quitado. La interceptación del error funciona cuando ocurre una
excepción que se puede identificar en el código de error asociado o mensaje de error
usando dos funciones. De acuerdo con los valores el código o mensaje, usted puede decidir
qué acción subsiguiente basó tomar en el error. SQLCODE devuelve el número del error
del oráculo para las excepciones internas. Usted puede pasar un número del error a
SQLERRM, que entonces vuelve el mensaje asociado al número del error.

Función Descripción

SQLCODE Devuelve el valor numérico para el código de


error (se puede asignar variable NÚMERO)

SQLERRM Devuelve los datos de carácter que contienen el


mensaje asociado al número del error

Valor SQLCODE Descripción


O No se genera excepción
1 Excepción definida por el usuario
+100 Excepción NO_DATA_FOUND
Número negativor Otro número de error del servidor Oracle

Para atrapar los errores definidos por el usuario se deben realizar las siguientes acciones:
1. Declare el nombre para la excepción definida por el usuario dentro de la sección
declarativa.
EXCEPCIÓN excepción;
Donde excepcion: es el nombre del uso de la excepción
2. Declare RAISE dentro de la sección ejecutable.
RAISE excepcion;
Donde excepcion: es la referencia previamente declarada de la excepción
3. La excepción debe ser declarada dentro de la rutina correspondiente de la dirección
de excepción.
Utilice la declaración RAISE por sí mismo dentro de un tratante de la excepción para
levantar la misma excepción de nuevo al ambiente que llama.
Propagando excepciones en vez de atrapar una excepción dentro de PL-SQL
Propague la excepción que llama el ambiente para manejarlo. Cada ambiente que llama
tiene su propia manera de exhibir errores que tienen acceso.
Propagar una excepción en un Subblock cuando un subblock maneja una excepción,
termina normalmente, y las condiciones del control en el bloque se incluye inmediatamente
después de la declaración END.
Sin embargo, si PL-SQL levanta una excepción y el bloque actual no tiene nada más
práctico para esa excepción que incluir las propagaciones de la excepción hasta que
encuentre una más práctica.
Una ventaja de este comportamiento es que se pueden incluir las declaraciones que
requieren su propia gestión de error exclusiva en su propio bloque, mientras que deja una
dirección de excepción más general a la que incluye.
Uso del procedimiento RAISE_APPLICATION_ERROR
El procedimiento de RAISE_APPLICATION_ERROR sirve para comunicar una excepción
predefinida recíprocamente volviendo un código de error y un mensaje de error anormales.
Con RAISE_APPLICATION_ERROR, se pueden divulgar errores y evitar devolver
excepciones sin texto.
Sintaxis:
numero-error: el usuario especificó el número para la excepción entre 20000 y
-20999.
mensaje: es el mensaje especificado por el usuario para la excepción. Es una cadena
de caracteres hasta 2,048 octetos de largo.
TRUE|FALSE: es un parámetro boleano opcional (si es TRUE el error es apilado
con los errores anteriores. Si es FALSE se hace lo contrario, El error substituye
todos los errores anteriores.)
PAQUETES PL-SQL
Las funciones y procedimientos son objetos importantes de PL-SQL porque permiten
agrupar los estatutos PL-SQL que son necesarios para el funcionamiento de la aplicación.
Vendría a ser algo similar a lo que son las clases en JAVA. Estructuralmente un paquete
está dividido en dos partes:
 El cuerpo del paquete: contiene información privada que no puede ser vista por las
rutinas externas al paquete.
 La especificación del paquete: guarda los datos, funciones y procedimientos que
serán accesibles por todas las otras rutinas que usarán el paquete.
Los paquetes encapsulan en un objeto los elementos y las operaciones o métodos que los
manipulan. Cuando declaramos los cursores en paquetes lo que haremos será declarar en el
cuerpo la definición del cursor y su sentencia SELECT y en la especificación pondríamos
algo como:
CURSOR c_movie_rentals(movieID MOVIE.ID%TYPE)
RETURN rental.DAILY_RATE%TYPE;

/*en el cuerpo tendríamos algo así como:*/

CURSOR c_movie_rentals(movieID MOVIE.ID%TYPE) IS


SELECT customer_id, rent_dt, return_dt
FROM rental
WHERE movie_id=movieID;

FORMULARIOS CON PL-SQL


Los formularios de Oracle utilizan tanto variable locales como variables globales. Las
locales sólo son accesibles desde dentro del bloque PL-SQL desde donde se habían
generado, las globales son accesibles desde cualquier objeto, trigger, función y
procedimiento en el módulo que se está ejecutando. El nombre de las variables globales
siempre será GLOBAL.nombreVariable.
Tenemos que tener en cuenta una característica muy importante dentro de las variables que
son el tipo de datos que las van a definir. Este tipo de datos puede venir dado por los
objetos que formarán parte de los formularios como pueden ser WINDOW, ITEM y
BLOQUES.

Bibliografía
Manual de introducción a SQL y PL-SQL Oracle, ORACLE UNIVERSITY.
Práctica 23: Manejo de excepciones

1. Write PL-SQL block to select the name of the employee with a given salary value.

a. If the salary entered returns more than one row, handle the exception with an
appropriate exception handler and insert into the MESSAGES table the message
“more than one employee with a salary of <salary>”.

b. If the salary entered does not return any rows, handle the exception with an
appropriate exception handler and insert into the MESSAGES table the message
“No employee with a salary of <salary>”.

c. If the salary entered returns only one row, insert into the MESSAGES table
the employee’s name and the salary amount.

d. Handle any other exception with an appropriate exception handler and insert
into the MESSAGES table the message “Some other error occurred.”

e. Test the block for a variety of test cases.

RESULTS
---------------------------------------------------
SMITH - 800
More than one employee with a salary of 3000
No employee with a salary of 6000

2. Modify p18q3.sql to add and exception handler.

a. Write an exception handler for the error to pass a message to the user that the
specified department does not exist.

b. Execute the PL-SQL Block by entering department that does not exist.

Please enter the department number: 50


Please enter the department location: HOUSTON
PL-SQL procedure successfully completed.

G_MESSAGE
---------------------------------------------------
Department 50 is an invalid department
3. Write a PL-SQL block that prints the number of employyes who make pul or minus
$100 of the salary value entered.

a. If there is no employee within that salary range ,print a message to the user
indicating that is the case. Use an exception for this case.

b. If there are one or more employees within that range, the message should
indicate how many employees are in that salary range.

c. Handle any other exception with an appropiate exception handler. The


message should indicate that some other error ocurred.

Please enter the salary: 800


PL-SQL procedure successfully completed.

G_MESSAGE
-------------------------------------------------------------
There is/are 1 employee (s) with a salary between 700 and 900

Please enter the salary: 3000


PL-SQL procedure successfully completed.

G_MESSAGE
-------------------------------------------------------------
There is/are 3 employee (s) with a salary between 2900 and
3100

Please enter the salary: 6000


PL-SQL procedure successfully completed.

G_MESSAGE
-------------------------------------------------------------
There is no employee salary between 5900 and 6100

También podría gustarte