0% encontró este documento útil (0 votos)
80 vistas81 páginas

PLSQL Diplomado

Este documento introduce PL/SQL, incluyendo una descripción general del lenguaje, su arquitectura y bloques anónimos. Explica que PL/SQL agrega elementos de procedimiento al lenguaje SQL y es un lenguaje de programación de base de datos integrado y de alto rendimiento. Además, describe cómo crear y ejecutar bloques anónimos PL/SQL utilizando herramientas como SQL*Plus y Oracle SQL Developer.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
80 vistas81 páginas

PLSQL Diplomado

Este documento introduce PL/SQL, incluyendo una descripción general del lenguaje, su arquitectura y bloques anónimos. Explica que PL/SQL agrega elementos de procedimiento al lenguaje SQL y es un lenguaje de programación de base de datos integrado y de alto rendimiento. Además, describe cómo crear y ejecutar bloques anónimos PL/SQL utilizando herramientas como SQL*Plus y Oracle SQL Developer.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 81

Sección 1.

Introducción a PL / SQL
• ¿Qué es PL / SQL ? Introducción al lenguaje de programación PL / SQL y su
arquitectura.
• Bloque anónimo : explica los bloques anónimos PL / SQL y le muestra cómo
ejecutar un bloque anónimo en las herramientas SQL * Plus y Oracle SQL
Developer.
• Tipos de datos : le brindan una breve descripción general de los tipos de datos PL /
SQL, incluidos números, booleanos, caracteres y fecha y hora.
• Variables : le presenta las variables PL / SQL y le muestra cómo manipular las
variables en los programas de manera eficiente.
• Comentarios : utilice comentarios de una o varias líneas para documentar su
código y hacerlo más legible y fácil de mantener.
• Constantes : aprenda a declarar constantes que contienen valores que permanecen
sin cambios durante la ejecución del programa.

¿Qué es PL / SQL?

Introducción a PL / SQL
PL / SQL son las siglas de "Extensiones de lenguaje de procedimiento al lenguaje
de consulta estructurado". SQL es un lenguaje popular para consultar y actualizar
datos en los sistemas de administración de bases de datos relacionales
(RDBMS). PL / SQL agrega muchas construcciones de procedimientos al lenguaje
SQL para superar algunas limitaciones de SQL. Además, PL / SQL proporciona una
solución de lenguaje de programación más completa para crear aplicaciones de
misión crítica en bases de datos Oracle.

PL / SQL es un lenguaje altamente estructurado y legible. Sus construcciones


expresan claramente la intención del código. Además, PL / SQL es un lenguaje
sencillo de aprender.

PL / SQL es un lenguaje estándar y portátil para el desarrollo de bases de datos


Oracle. Si desarrolla un programa que se ejecuta en una base de datos Oracle,
puede moverlo rápidamente a otra base de datos Oracle compatible sin ningún
cambio.
PL / SQL es un lenguaje integrado. PL / SQL solo se puede ejecutar en una base de
datos Oracle. No fue diseñado para usarse como un lenguaje independiente como
Java, C # y C ++. En otras palabras, no puede desarrollar un programa PL / SQL que
se ejecute en un sistema que no tenga una base de datos Oracle.

PL / SQL es un lenguaje de base de datos de alto rendimiento y altamente


integrado. Además de PL / SQL, puede utilizar otros lenguajes de programación
como Java, C # y C ++. Sin embargo, es más fácil escribir código eficiente en PL /
SQL que otros lenguajes de programación cuando se trata de interactuar con
Oracle Database.

Arquitectura PL / SQL
La siguiente imagen ilustra la arquitectura PL / SQL:

El motor PL / SQL se encarga de compilar el código PL / SQL en código de bytes y


ejecuta el código ejecutable. El motor PL / SQL solo se puede instalar en un
servidor de base de datos Oracle o una herramienta de desarrollo de aplicaciones
como Oracle Forms.

Una vez que envía un bloque PL / SQL al servidor de la base de datos Oracle, el
motor PL / SQL colabora con el motor SQL para compilar y ejecutar el código.

El motor PL / SQL ejecuta los elementos de procedimiento mientras que el motor


SQL procesa las sentencias SQL.
Ahora debería tener un conocimiento básico del lenguaje de programación PL /
SQL y su arquitectura. Creemos el primer bloque anónimo PL / SQL en
funcionamiento .

Bloque anónimo PL / SQL

Descripción general del bloque anónimo PL / SQL


PL / SQL es un lenguaje estructurado en bloques cuyo código está organizado en
bloques. Un bloque PL / SQL consta de tres secciones: declaración, ejecutable y
secciones de manejo de excepciones. En un bloque, la sección ejecutable es
obligatoria mientras que las secciones de declaración y manejo de excepciones son
opcionales.

Un bloque PL / SQL tiene un nombre. Funciones o procedimientos es un ejemplo


de un bloque con nombre. Un bloque con nombre se almacena en el servidor de la
base de datos Oracle y se puede reutilizar más tarde.

Un bloque sin nombre es un bloque anónimo. Un bloque anónimo no se guarda en


el servidor de la base de datos Oracle, por lo que es solo para un uso único. Sin
embargo, los bloques anónimos PL / SQL pueden resultar útiles para realizar
pruebas.

La siguiente imagen ilustra la estructura de un bloque PL / SQL:

1) Sección de declaración
Un bloque PL / SQL tiene una sección de declaración donde declara variables ,
asigna memoria para cursores y define tipos de datos.

2) Sección ejecutable

Un bloque PL / SQL tiene una sección ejecutable. Una sección ejecutable comienza
con la palabra clave BEGINy termina con la palabra clave END. La sección ejecutable
debe tener al menos una declaración ejecutable, incluso si es NULL declaración que
no hace nada.

3) Sección de manejo de excepciones

Un bloque PL / SQL tiene una sección de manejo de excepciones que comienza con
la palabra clave EXCEPTION. La sección de manejo de excepciones es donde detecta
y maneja las excepciones generadas por el código en la sección de ejecución.

Tenga en cuenta que un bloque en sí mismo es una declaración ejecutable, por lo


tanto, puede anidar un bloque dentro de otros bloques.

Ejemplo de bloque anónimo PL / SQL


El siguiente ejemplo muestra un bloque anónimo PL / SQL simple con una sección
ejecutable.

Set serveroutput on;


BEGIN
DBMS_OUTPUT.put_line ('Hello World!');
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La sección ejecutable llama al DMBS_OUTPUT.PUT_LINE procedimiento para mostrar


el "Hello World"mensaje en la pantalla.

Ejecute un bloque anónimo PL / SQL usando SQL * Plus


Una vez que tenga el código de un bloque anónimo, puede ejecutarlo usando SQL
* Plus, que es una interfaz de línea de comandos para ejecutar sentencias SQL y
bloques PL / SQL proporcionados por Oracle Database.

La siguiente imagen ilustra cómo ejecutar un bloque PL / SQL usando SQL * Plus:
Primero, conéctese al servidor de la base de datos Oracle utilizando un nombre de
usuario y una contraseña.

En segundo lugar, active la salida del servidor mediante el SET SERVEROUTPUT ON


comando para que el DBMS_OUTPUT.PUT_LINE procedimiento muestre texto en la
pantalla.

En tercer lugar, escriba el código del bloque e introduzca una barra inclinada ( /)
para indicarle a SQL * Plus que ejecute el bloque. Una vez que escriba la barra
diagonal (/), SQL * Plus ejecutará el bloque y mostrará el Hello Worldmensaje en la
pantalla como se muestra en las ilustraciones.

Tenga en cuenta que debe ejecutar el SET SERVEROUTPUT ON comando en cada sesión
que se conecte a la base de datos de Oracle para mostrar el mensaje mediante
el DBMS_OUTPUT.PUT_LINE procedimiento.

Para ejecutar el bloque que ha ingresado nuevamente, use el /comando en lugar


de escribir todo desde cero:

Si desea editar el bloque de código, use el edit comando. SQL * Plus escribirá el
bloque de código en un archivo y lo abrirá en un editor de texto como se muestra
en la siguiente imagen:
Puede cambiar el contenido del archivo de la siguiente manera:

begin
dbms_output.put_line('Hello There');
end;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Y guarde y cierre el archivo. El contenido del archivo se escribirá en el búfer y se


volverá a compilar.

Después de eso, puede ejecutar el bloque de código nuevamente, usará el nuevo


código:

Ejecute un bloque anónimo PL / SQL usando SQL


Developer
Primero, conéctese al servidor de la base de datos Oracle mediante Oracle SQL
Developer.

En segundo lugar, cree un nuevo archivo SQL llamado anonymous-block.sql residente


en el C:\plsql directorio que almacenará el código PL / SQL.
En tercer lugar, ingrese el código PL / SQL y ejecútelo haciendo clic en
el botón Ejecutar o presionando el atajo de teclado Ctrl-Enter .
Más ejemplos de bloques anónimos PL / SQL
En este ejemplo, primero declaramos una variable l_message que contiene el mensaje
de saludo. Y luego, en la sección de ejecución, usamos el DBMS_OUTPUT.PUTLINE
procedimiento para mostrar el contenido de esta variable en lugar de usar una
cadena literal.

DECLARE
l_message VARCHAR2( 255 ) := 'Hello World!';
BEGIN
DBMS_OUTPUT.PUT_LINE( l_message );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

¡Hola Mundo!

El siguiente ejemplo de bloque anónimo agrega una sección de manejo de


excepciones que detecta la ZERO_DIVIDE excepción generada en la sección
ejecutable y muestra un mensaje de error.

DECLARE
v_result NUMBER;
BEGIN
v_result := 1 / 0;
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE( SQLERRM );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El mensaje de error es:

ORA-01476: el divisor es igual a cero

Ahora, debe saber cómo crear bloques anónimos PL / SQL y ejecutarlos utilizando
las herramientas SQL * Plus y Oracle SQL Developer.
Tipos de datos PL / SQL

Introducción a los tipos de datos PL / SQL


Cada valor en PL / SQL, como una constante , variable y parámetro, tiene un tipo
de datos que determina el formato de almacenamiento, los valores válidos y las
operaciones permitidas.

PL / SQL tiene dos tipos de tipos de datos: escalares y compuestos. Los tipos
escalares son tipos que almacenan valores únicos como número , booleano,
carácter y fecha y hora, mientras que los tipos compuestos son tipos que
almacenan múltiples valores, por ejemplo, registro y colección.

Este tutorial explica los tipos de datos escalares que almacenan valores sin
componentes internos.

PL / SQL divide los tipos de datos escalares en cuatro familias:

• Número
• Booleano
• Personaje
• Fecha y hora

Un tipo de datos escalares puede tener subtipos. Un subtipo es un tipo de datos


que es un subconjunto de otro tipo de datos, que es su tipo base. Un subtipo
define además un tipo base al restringir el valor o tamaño del tipo de datos base.

Tenga en cuenta que los tipos de datos escalares PL / SQL incluyen tipos de datos
SQL y su propio tipo de datos, como booleano.

Tipos de datos numéricos


Los tipos de datos numéricos representan números reales, enteros y números de
coma flotante. Se almacenan como NUMBER tipos de almacenamiento de punto
flotante IEEE ( BINARY_FLOATy BINARY_DOUBLE) y PLS_INTEGER.

Los tipos de datos NUMBER, BINARY_FLOAT y BINARY_DOUBLE son tipos de datos SQL.

El PLS_INTEGER tipo de datos es específico de PL / SQL. Representa números enteros


de 32 bits con signo que van de -2,147,483,648a 2,147,483,647.
Debido a que el PLS_INTEGER tipo de datos usa aritmética de hardware, son más
rápidos que las NUMBER operaciones, que usan aritmética de software.

Además, los PLS_INTEGER valores requieren menos almacenamiento que NUMBER. Por
lo tanto, siempre debe usar PLS_INTEGER valores para todos los cálculos en su rango
para aumentar la eficiencia de los programas.

El PLS_INTEGER tipo de datos tiene los siguientes subtipos predefinidos:

Subtipos PLS_INTEGER Descripción

NATURAL Representa PLS_INTEGER valores no negativos

NATURALN Representa PLS_INTEGER valores no negativos con restricción NOT


NULL

POSITIVE Representa PLS_INTEGER valores positivos

POSITIVEN Representa un PLS_INTEGER valor positivo con la restricción NOT


NULL

SIGNTYPE Representa tres valores -1, 0 o 1, que son útiles para la programación
lógica de tres estados.

SIMPLE_INTEGER Representa PLS_INTEGER valores con restricción NOT NULL .

Tenga en cuenta que los tipos de datos PLS_INTEGER y BINARY_INTEGER son idénticos.

Tipo de datos booleanos


El BOOLEAN tipo de datos tiene tres valores de datos: VERDADERO, FALSO y
NULO. Los valores booleanos se utilizan normalmente en la estructura del flujo de
control, como IF-THEN , CASE y sentencias de bucle como LOOP , FOR
LOOP y WHILE LOOP .

SQL no tiene el BOOLEAN tipo de datos, por lo tanto, no puede:

• Asignar un BOOLEAN valor a una columna de la tabla.


• Seleccione el valor de una columna de la tabla en una BOOLEAN variable.
• Utilice un BOOLEAN valor en una función SQL.
• Utilice una BOOLEAN expresión en una declaración SQL.
• Utilice un BOOLEAN valor en los subprogramas DBMS_OUTPUT.PUTLINE
y DBMS_OUTPUT.PUT.

Tipos de datos de caracteres


Los tipos de datos de caracteres representan texto alfanumérico. PL / SQL utiliza los
tipos de datos SQL de caracteres tales como CHAR, VARCHAR2, LONG, RAW, LONG
RAW, ROWID, y UROWID.

• CHAR(n) es un tipo de carácter de longitud fija cuya longitud es de 1 a 32,767


bytes.
• VARCHAR2(n) tiene datos de caracteres de longitud variable de 1 a 32,767 bytes.

Tipos de datos de fecha y hora


Los tipos de datos de fecha y hora representan fechas, marcas de tiempo con o sin
zona horaria e intervalos. PL / SQL de fecha y hora tipos de datos
son DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME
ZONE, INTERVAL YEAR TO MONTH, y INTERVAL DAY TO SECOND.

Sinónimos de tipo de datos


Los tipos de datos tienen sinónimos de compatibilidad con fuentes de datos que
no son de Oracle, como IBM Db2, SQL Server. Y no es una buena práctica utilizar
sinónimos de tipo de datos a menos que esté accediendo a una base de datos que
no sea de Oracle.

Tipo de datos Sinónimos

NÚMERO DEC, DECIMAL, DOBLE PRECISIÓN, FLOAT, INTEGER, INT, NUMERIC, REAL, SMALLINT

CARBONIZARSE CADENA DE CARACTERES

VARCHAR2 VARCHAR

Ahora, debería tener una descripción completa de los tipos de datos PL / SQL para
manipular datos en el programa PL / SQL.
En PL / SQL, una variable se denomina ubicación de almacenamiento que almacena
un valor de un tipo de datos en particular . El valor de la variable cambia a través
del programa. Antes de usar una variable, debe declararla en la sección de
declaración de un bloque .

Variables PL / SQL

Declaración de variables
La sintaxis de una declaración de variable es la siguiente:

variable_name datatype [NOT NULL] [:= initial_value];


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis:

• Primero, especifique el nombre de la variable. El nombre de la variable debe ser lo


más descriptivo posible, por ejemplo, l_total_sales, l_credit_limit, y l_sales_revenue.
• En segundo lugar, elija un tipo de datos apropiado para la variable, según el tipo
de valor que desee almacenar, por ejemplo, número, carácter, booleano y fecha y
hora.

Por convención, los nombres de las variables locales deben comenzar con l_y los
nombres de las variables globales deben tener el prefijo g_.

El siguiente ejemplo declara tres variables l_total_sales, l_credit_limity l_contact_name:

DECLARE
l_total_sales NUMBER(15,2);
l_credit_limit NUMBER (10,0);
l_contact_name VARCHAR2(255);
BEGIN
NULL;
END;

Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )


Valores predeterminados

PL / SQL le permite establecer un valor predeterminado para una variable en el


momento de la declaración. Para asignar un valor predeterminado a una variable,
utilice el operador de asignación ( :=) o la DEFAULT palabra clave.

El siguiente ejemplo declara una variable nombrada l_product_name con un valor


inicial 'Laptop':

DECLARE
l_product_name VARCHAR2( 100 ) := 'Laptop';
BEGIN
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Es equivalente al siguiente bloque:

DECLARE
l_product_name VARCHAR2(100) DEFAULT 'Laptop';
BEGIN
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, en lugar de usar el operador de asignación :=, usamos


la DEFAULTpalabra clave para inicializar una variable.

Restricción NOT NULL

Si impone la NOT NULL restricción a un valor, la variable no puede aceptar un valor


NULO. Además, una variable declarada con el NOT NULL debe inicializarse con un
valor no nulo. Tenga en cuenta que PL / SQL trata una cadena de longitud cero
como un valor NULO.

El siguiente ejemplo declara primero una variable nombrada l_shipping_status con


la NOT NULL restricción. Luego, asigna a la variable una cadena de longitud cero.

DECLARE
l_shipping_status VARCHAR2( 25 ) NOT NULL := 'Shipped';
BEGIN
l_shipping_status := '';
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

PL / SQL emitió el siguiente error:

ORA-06502: PL/SQL: numeric or value error


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Debido a que la variable l_shipping_status declarada con la NOT NULL restricción, no


podía aceptar un valor NULL o una cadena de longitud cero en este caso.

Asignaciones variables
Para asignar un valor a una variable, utilice el operador de asignación (: =), por
ejemplo:

DECLARE
l_customer_group VARCHAR2(100) := 'Silver';
BEGIN
l_customer_group := 'Gold';
DBMS_OUTPUT.PUT_LINE(l_customer_group);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Puede asignar un valor de una variable a otra como se muestra en el siguiente


ejemplo:

DECLARE
l_business_parter VARCHAR2(100) := 'Distributor';
l_lead_for VARCHAR2(100);
BEGIN
l_lead_for := l_business_parter;
DBMS_OUTPUT.PUT_LINE(l_lead_for);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Declaraciones ancladas
Normalmente, declaras una variable y seleccionas un valor de una columna de la
tabla para esta variable. Si el tipo de datos de la columna de la tabla cambia, debe
ajustar el programa para que funcione con el nuevo tipo.

PL / SQL le permite declarar una variable cuyo tipo de datos se ancla a una
columna de tabla u otra variable. Considere el siguiente ejemplo:

DECLARE
l_customer_name customers.name%TYPE;
l_credit_limit customers.credit_limit%TYPE;
BEGIN
SELECT
name, credit_limit
INTO
l_customer_name, l_credit_limit
FROM
customers
WHERE
customer_id = 38;

DBMS_OUTPUT.PUT_LINE(l_customer_name || ':' || l_credit_limit );


END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo:

• Primero, declare dos variables l_customer_name y l_credit_limit cuyo tipo de datos se


ancle a las columnas name y credit_limit respectivamente, en la sección de
declaración del bloque.
• En segundo lugar, consulte el nombre del cliente y el límite de crédito de la
identificación del cliente 38y asigne estos valores de columna a
las variables l_customer_name y l_credit_limit en el bloque de ejecución.
• En tercer lugar, muestre el nombre del cliente y el límite de crédito.

PL / SQL devolvió la siguiente salida:

Kraft Heinz:500
Este ejemplo ilustra cómo declarar variables que se anclan a otra variable:

DECLARE
l_credit_limit customers.credit_limit%TYPE;
l_average_credit l_credit_limit%TYPE;
l_max_credit l_credit_limit%TYPE;
l_min_credit l_credit_limit%TYPE;
BEGIN
-- get credit limits
SELECT
MIN(credit_limit),
MAX(credit_limit),
AVG(credit_limit)
INTO
l_min_credit,
l_max_credit,
l_average_credit
FROM customers;

SELECT
credit_limit
INTO
l_credit_limit
FROM
customers
WHERE
customer_id = 100;

-- show the credits


dbms_output.put_line('Min Credit: ' || l_min_credit);
dbms_output.put_line('Max Credit: ' || l_max_credit);
dbms_output.put_line('Avg Credit: ' || l_average_credit);

-- show customer credit


dbms_output.put_line('Customer Credit: ' || l_credit_limit);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:


Min Credit: 100
Max Credit: 5000
Avg Credit: 1894.67
Customer Credit: 1894.67
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Ahora, debe saber cómo usar variables PL / SQL en su bloque y manipularlas de


manera eficiente.

Comentarios PL / SQL

Introducción a los comentarios de PL / SQL


Los comentarios PL / SQL le permiten describir el propósito de una línea o un
bloque de código PL / SQL.

Al compilar el código PL / SQL, el precompilador de Oracle ignora los


comentarios. Sin embargo, siempre debe utilizar comentarios para que su código
sea más legible y para ayudarlo a usted y a otros desarrolladores a comprenderlo
mejor en el futuro.

PL / SQL tiene dos estilos de comentarios: comentarios de una línea y comentarios


de varias líneas.

Comentarios de una sola línea


Un comentario de una sola línea comienza con un guión doble ( --) que puede
aparecer en cualquier lugar de una línea y se extiende hasta el final de la línea.

Por ejemplo, el siguiente comentario de una sola línea explica el significado de


la co_vat_rate constante:

-- valued added tax 10%


DECLARE co_vat_rate CONSTANT NUMBER := 0.1;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

A veces, mientras prueba un programa, puede usar un comentario de una sola


línea para deshabilitar una línea de código. A continuación, se ilustra cómo
comentar una línea de código:

-- UPDATE products SET list_price = 0 WHERE product_id = l_id;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Si desea comentar solo una poción de una línea, también puede usar el comentario
de una sola línea. El siguiente ejemplo muestra cómo comentar la WHERE cláusula
de la UPDATE declaración. Todo el código que sigue al guión doble --al resto de la
línea se tratará como un comentario:

UPDATE products SET list_price = 0; -- WHERE product_id = l_id;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Tenga en cuenta que agregamos el punto y coma ( ;) antes del ( --) para que la
declaración sea válida.

Comentarios de varias líneas


Un comentario de varias líneas comienza con una barra-asterisco ( /*) y termina
con un asterisco-barra ( */) y puede abarcar varias líneas:

/*
This is a multi-line comment
that can span multiple lines
*/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Tenga en cuenta que es posible utilizar un comentario de varias líneas como un


comentario de una sola línea:

/* A multi-line comment can be used as a single-line comment */


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

A menudo usamos un comentario de varias líneas para describir el propósito de un


bloque de código como el siguiente ejemplo:

/*
This code allow users to enter the customer id and
return the corresponding customer name and credit limit
*/
DECLARE
l_customer_name customers.name%TYPE;
l_credit_limit customers.credit_limit%TYPE;
BEGIN
...
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Para la mantenibilidad, no es una buena práctica mezclar comentarios de la


siguiente manera:

BEGIN
-- single-line comment /* another comment */
NULL;
/*
multi-line comment
-- that has another single-line comment
*/
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En su lugar, utilice lo siguiente:

BEGIN
-- single-line comment, another comment
NULL;
/*
multi-line comment
that has another single-line comment
*/
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Notas de uso de comentarios de PL / SQL


PL / SQL no le permite anidar un comentario de varias líneas dentro de otro
comentario de varias líneas. El siguiente bloque de código no es válido:

BEGIN
/*
a multi-line comment
/*
a nested multi-line comment
*/
*/ -- -> error
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Para un bloque PL / SQL que se procesará dinámicamente, no puede utilizar


comentarios de una sola línea. Porque el precompilador de Oracle ignorará los
caracteres de final de línea que hacen que los comentarios de una sola línea se
extiendan hasta el final del bloque. En este caso, puede utilizar comentarios de
varias líneas en su lugar.

En este tutorial, ha aprendido sobre los comentarios PL / SQL, incluidos los


comentarios de una sola línea y de varias líneas que le permiten documentar el
propósito de su código.

Constantes PL / SQL

Introducción a las constantes PL / SQL


A diferencia de una variable , una constante tiene un valor que no cambia durante
la ejecución del programa.

Las constantes hacen que su código sea más legible. Considere la siguiente línea
de código que calcula el precio de lista a partir del precio.

l_list_price := l_price + l_price * 0.1;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Al mirar esto, no sabemos qué 0.1significa. Puede ser cualquier cosa. Por supuesto,
puede utilizar un comentario para explicar el significado de 0.1:

-- price with value-added tax (VAT) 10%


l_list_price := l_price + l_price * 0.1;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Sin embargo, es incluso mejor si usa una constante como esta:

l_list_price := l_price + l_price * co_vat;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este código, co_vat es la constante que almacena el IVA del 10%.


Para declarar una constante, especifique el nombre, la CONSTANT palabra clave, el
tipo de datos y el valor predeterminado. Lo siguiente ilustra la sintaxis de declarar
una constante:

constant_name CONSTANT datatype [NOT NULL] := expression


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis:

nombre_constante

es el nombre de la constante que está declarando.

tipo de datos

especifique el tipo de valor que mantendrá la constante.

NO NULO

imponer opcionalmente una NOT NULL restricción a la constante. Esto evita que la
constante almacene NULL o una cadena vacía.

expresión

use una expresión como valor inicial de la constante. El tipo de valor de retorno de
la expresión debe ser compatible con el tipo de datos de la constante.

Ejemplos de constantes PL / SQL


El siguiente ejemplo declara dos constantes co_payment_term y co_payment_status:

DECLARE
co_payment_term CONSTANT NUMBER := 45; -- days
co_payment_status CONSTANT BOOLEAN := FALSE;
BEGIN
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Si intenta cambiar co_payment_term en la sección de ejecución, PL / SQL emitirá un


error, por ejemplo:
DECLARE
co_payment_term CONSTANT NUMBER := 45; -- days
co_payment_status CONSTANT BOOLEAN := FALSE;
BEGIN
co_payment_term := 30; -- error
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el mensaje de error:

PLS-00363: expression 'CO_PAYMENT_TERM' cannot be used as an


assignment target
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

A continuación, se muestra cómo declarar una constante cuyo valor se deriva de


una expresión:

DECLARE
co_pi CONSTANT REAL := 3.14159;
co_radius CONSTANT REAL := 10;
co_area CONSTANT REAL := (co_pi * co_radius**2);
BEGIN
DBMS_OUTPUT.PUT_LINE(co_area);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, la co_area constante recibe el valor de una expresión que involucra
otras dos constantes.

Sección 2. Control condicional


• Sentencias IF : presenta varias sentencias IF para ejecutar u omitir una secuencia de
sentencias en función de una condición.
• Sentencias CASE : aprenda a elegir una secuencia de sentencias entre muchas
secuencias posibles para ejecutar.
• GOTO : explica la instrucción GOTO y muestra cómo usarla para transferir el control
a un bloque o instrucción etiquetados.
• Declaración NULL : muestra cómo usar la declaración NULL para hacer el código
más claro.
Declaración PL / SQL IF

La instrucción IF le permite ejecutar u omitir una secuencia de instrucciones, según


una condición. La IF declaración tiene tres formas:

- IF THEN
- IF THEN ELSE
-IF THEN ELSIF

PL / SQL IF THEN sentencia


A continuación, se ilustra la estructura de la IF THEN declaración:

IF condition THEN
statements;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La condición es una expresión booleana que siempre se evalúa como VERDADERO,


FALSO o NULO.

Si la condición se evalúa como VERDADERA, statements después de la THEN


ejecución. De lo contrario, la IF declaración no hace nada.

PL / SQL IF THEN ejemplo de declaración

En el siguiente ejemplo, las declaraciones entre THEN y END IF se ejecutan porque


los ingresos por ventas son superiores a 100.000.

DECLARE n_sales NUMBER := 2000000;


BEGIN
IF n_sales > 100000 THEN
DBMS_OUTPUT.PUT_LINE( 'Sales revenue is greater than 100K ' );
END IF;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Consejo n. ° 1: evite las declaraciones IF torpes

Considere el siguiente ejemplo:


DECLARE
b_profitable BOOLEAN;
n_sales NUMBER;
n_costs NUMBER;
BEGIN
b_profitable := false;
IF n_sales > n_costs THEN
b_profitable := true;
END IF;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, el IF estado de cuenta determina si los ingresos por ventas son
más altos que el costo y actualiza la b_profitable variable en consecuencia.

Esta IF declaración se denomina declaración torpe IF porque puede asignar el


resultado de una expresión booleana directamente a una variable booleana de la
siguiente manera:

b_profitable := n_sales > n_costs;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Consejo n. ° 2: evite evaluar variables booleanas

Una variable booleana es siempre VERDADERO, FALSO o NULO. Por lo tanto, la


siguiente comparación es innecesaria:

IF b_profitable = TRUE THEN


DBMS_OUTPUT.PUT_LINE( 'This sales deal is profitable' );
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En su lugar, use:

IF b_profitable THEN
DBMS_OUTPUT.PUT_LINE( 'This sales deal is profitable' );
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Declaración PL / SQL IF THEN ELSE
La IF THEN ELSE declaración tiene la siguiente estructura:

IF condition THEN
statements;
ELSE
else_statements;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Ejemplo de declaración IF THEN ELSE

El siguiente ejemplo establece la comisión de ventas en un 10% si los ingresos por


ventas son superiores a 200.000. De lo contrario, la comisión de ventas se establece
en un 5%.

DECLARE
n_sales NUMBER := 300000;
n_commission NUMBER( 10, 2 ) := 0;
BEGIN
IF n_sales > 200000 THEN
n_commission := n_sales * 0.1;
ELSE
n_commission := n_sales * 0.05;
END IF;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

PL / SQL IF THEN declaración ELSIF


A continuación, se ilustra la estructura de la IF THEN ELSIF declaración:

IF condition_1 THEN
statements_1
ELSIF condition_2 THEN
statements_2
[ ELSIF condition_3 THEN
statements_3
]
...
[ ELSE
else_statements
]
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta estructura, la condición entre IFy THEN, que es la primera condición, siempre
se evalúa. Cada otra condición entre ELSEIFy THENse evalúa solo si la condición
anterior es FALSA. Por ejemplo, condition_2se evalúa solo si condition_1es
falso, condition_3solo se evalúa si condition_2es falso, y así sucesivamente.

Si una condición es verdadera, no se evalúan otras condiciones posteriores. Si


ninguna condición es verdadera, se ejecuta else_statementsentre ELSEy ENDIF. En caso
de que omita la ELSEcláusula y ninguna condición sea VERDADERA, entonces IF
THEN ELSIFno hace nada

IF THEN Ejemplo de instrucción ELSIF

El siguiente ejemplo utiliza el IF THEN ELSIF estado de cuenta para establecer la


comisión de ventas en función de los ingresos por ventas.

DECLARE
n_sales NUMBER := 300000;
n_commission NUMBER( 10, 2 ) := 0;
BEGIN
IF n_sales > 200000 THEN
n_commission := n_sales * 0.1;
ELSIF n_sales <= 200000 AND n_sales > 100000 THEN
n_commission := n_sales * 0.05;
ELSIF n_sales <= 100000 AND n_sales > 50000 THEN
n_commission := n_sales * 0.03;
ELSE
n_commission := n_sales * 0.02;
END IF;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Instrucción IF anidada
Puede anidar una IF declaración dentro de otra IF declaración como se muestra a
continuación:

IF condition_1 THEN
IF condition_2 THEN
nested_if_statements;
END IF;
ELSE
else_statements;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Sin embargo, si tiene demasiados niveles de anidación, el código será difícil de leer
y mantener, por lo que debe evitar anidar las IF declaraciones.

Declaración PL / SQL CASE

La CASE declaración elige una secuencia de declaraciones para ejecutar entre


muchas secuencias posibles.

La CASE declaración tiene dos tipos: CASE declaración simple y CASE


declaración buscada . Ambos tipos de CASE declaraciones admiten una ELSE
cláusula opcional .

Declaración simple
Una CASE declaración simple evalúa una sola expresión y compara el resultado con
algunos valores.

La CASE declaración simple tiene la siguiente estructura:

CASE selector
WHEN selector_value_1 THEN
statements_1
WHEN selector_value_1 THEN
statement_2
...
ELSE
else_statements
END CASE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Examinemos la sintaxis de la CASE declaración simple en detalle:

1) selector

El selector es una expresión que se evalúa una vez. El resultado del selector se utiliza
para seleccionar una de las varias alternativas, por ejemplo, selector_value_1
y selector_value_2.

2) when selector_value then statements

Los valores de selector, es decir, selector_value_1, selector_value_2, etc., son evaluados de


forma secuencial. Si el resultado de un valor de selector es igual al resultado
de selector, entonces la secuencia asociada de declaraciones se ejecuta y la CASE
declaración finaliza. Además, los valores de selector posteriores no se evalúan.

3) ELSE else_statements

Si ningún valor en las WHERE cláusulas coincide con el resultado del selector en
la CASE cláusula, se ELSE ejecuta la secuencia de declaraciones en la cláusula.

Debido a que la ELSE cláusula es opcional, puede omitirla. Sin embargo, si lo hace,
PL / SQL utilizará implícitamente lo siguiente:

ELSE
RAISE CASE_NOT_FOUND;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En otras palabras, PL / SQL genera un CASE_NOT_FOUND error si no especifica una ELSE


cláusula y el resultado de la CASE expresión no coincide con ningún valor en
las WHEN cláusulas.

Tenga en cuenta que este comportamiento de la CASE declaración es diferente de


la IF THEN declaración . Cuando la IF THEN declaración no tiene una ELSE cláusula y la
condición no se cumple, PL / SQL no hace nada en lugar de generar un error.

Ejemplo de declaración simple

El siguiente ejemplo compara un solo valor ( c_grade) con muchos valores posibles
'A', 'B', 'C', 'D' y 'F':
DECLARE
c_grade CHAR( 1 );
c_rank VARCHAR2( 20 );
BEGIN
c_grade := 'B';
CASE c_grade
WHEN 'A' THEN
c_rank := 'Excellent' ;
WHEN 'B' THEN
c_rank := 'Very Good' ;
WHEN 'C' THEN
c_rank := 'Good' ;
WHEN 'D' THEN
c_rank := 'Fair' ;
WHEN 'F' THEN
c_rank := 'Poor' ;
ELSE
c_rank := 'No such grade' ;
END CASE;
DBMS_OUTPUT.PUT_LINE( c_rank );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Declaración de búsqueda
La CASE declaración buscada evalúa múltiples expresiones booleanas y ejecuta la
secuencia de declaraciones asociadas con la primera condición que evalúa TRUE.

La CASE declaración buscada tiene la siguiente estructura:

CASE
WHEN condition_1 THEN statements_1
WHEN condition_2 THEN statements_2
...
WHEN condition_n THEN statements_n
[ ELSE
else_statements ]
END CASE;]
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
La CASE declaración buscada sigue las siguientes reglas:

• Las condiciones de las WHEN cláusulas de se evalúan en orden, de arriba a abajo.


• Se WHEN ejecuta la secuencia de declaraciones asociadas con la cláusula cuya
condición se evalúa como VERDADERA. Si más de una condición se evalúa como
VERDADERA, solo se ejecuta la primera.
• Si ninguna condición se evalúa como VERDADERA, se ejecuta else_statements en
la ELSE cláusula. Si omite la ELSE cláusula y ninguna expresión es VERDADERA, se
genera una CASE_NOT_FOUND excepción .

Ejemplo de declaración de búsqueda

El siguiente ejemplo ilustra cómo utilizar el CASE extracto buscado para calcular la
comisión de ventas en función de los ingresos por ventas.

DECLARE
n_sales NUMBER;
n_commission NUMBER;
BEGIN
n_sales := 150000;
CASE
WHEN n_sales > 200000 THEN
n_commission := 0.2;
WHEN n_sales >= 100000 AND n_sales < 200000 THEN
n_commission := 0.15;
WHEN n_sales >= 50000 AND n_sales < 100000 THEN
n_commission := 0.1;
WHEN n_sales > 30000 THEN
n_commission := 0.05;
ELSE
n_commission := 0;
END CASE;

DBMS_OUTPUT.PUT_LINE( 'Commission is ' || n_commission * 100 ||


'%'
);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
En este ejemplo, los ingresos por ventas se establecieron en 150.000. La primera
expresión evaluada como FALSA:

n_sales > 200000


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Pero la segunda expresión se evalúa como VERDADERA y la comisión de venta se


estableció en 15%:

n_commission := 0.15;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

PL / SQL deja de evaluar la condición subsiguiente una vez que encuentra la


primera condición que se evalúa como VERDADERA. Por lo tanto, en este ejemplo,
PL / SQL nunca evaluará las dos últimas condiciones de
la CASEdeclaración. La ELSEcláusula de declaración tampoco se ejecutará nunca.

Declaración simple CASE o buscada CASE

Como regla general, use una CASE declaración de búsqueda cuando desee ejecutar
una secuencia de declaraciones basada en los resultados de múltiples expresiones
booleanas y use una CASE declaración simple cuando desee ejecutar una secuencia
de declaraciones basada en el resultado de una sola expresión.

CASE Declaración PL / SQL frente a CASE expresión


PL / SQL también tiene una CASE expresión similar a la CASE declaración.

Una CASE expresión evalúa una lista de condiciones y devuelve una de las múltiples
expresiones de resultado posibles.

El resultado de una CASE expresión es un valor único, mientras que el resultado de


una CASE declaración es la ejecución de una secuencia de declaraciones.

Declaración PL / SQL GOTO

Introducción a la GOTO declaración PL / SQL


La GOTO declaración le permite transferir el control a un bloque o declaración
etiquetados. A continuación, se ilustra la sintaxis de la GOTO declaración:

GOTO label_name;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El label_name es el nombre de una etiqueta que identifica la definición del


objetivo. En el programa, rodee el nombre de la etiqueta con corchetes angulares
dobles como se muestra a continuación:

<<label_name>>;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Cuando PL / SQL encuentra una GOTO declaración, transfiere el control a la primera


declaración ejecutable después de la etiqueta.

GOTO Ejemplo de declaración PL / SQL


BEGIN
GOTO second_message;

<<first_message>>
DBMS_OUTPUT.PUT_LINE( 'Hello' );
GOTO the_end;

<<second_message>>
DBMS_OUTPUT.PUT_LINE( 'PL/SQL GOTO Demo' );
GOTO first_message;

<<the_end>>
DBMS_OUTPUT.PUT_LINE( 'and good bye...' );

END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La salida es:

PL/SQL GOTO Demo


Hello
and good Bye...
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

A continuación, se explica la secuencia del bloque en detalle:

• Primero, GOTO second_messagese encuentra la instrucción, por lo tanto, el


control se pasa a la instrucción después de la second_messageetiqueta.
• En segundo lugar, GOTO first_messagese encuentra el, por lo que el control se
transfiere a la declaración después de la first_messageetiqueta.
• En tercer lugar, GOTO the_endse alcanza, por lo tanto, el control se pasa a la
declaración después de la the_endetiqueta.

La siguiente imagen ilustra la secuencia:

Restricciones de la declaración PL / SQL GOTO


La GOTO declaración está sujeta a las siguientes restricciones.

En primer lugar, no se puede utilizar una GOTO declaración de control de


transferencia en una IF, CASEo LOOP declaración, lo mismo para sub-bloque.

El siguiente ejemplo intenta transferir el control a una IF declaración mediante


una GOTO declaración:

DECLARE
n_sales NUMBER;
n_tax NUMBER;
BEGIN
GOTO inside_if_statement;
IF n_sales > 0 THEN
<<inside_if_statement>>
n_tax := n_sales * 0.1;
END IF;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Oracle emitió el siguiente error:

PLS-00375: illegal GOTO statement; this GOTO cannot branch to


label 'INSIDE_IF_STATEMENT'
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En segundo lugar, no se puede utilizar una GOTO declaración de control de


transferencia de una cláusula a otra en el IF comunicado por ejemplo, de IF la
cláusula de ELSIF o ELSE cláusula, o de una WHEN cláusula a otra en el CASE
comunicado.

El siguiente ejemplo intenta transferir el control a una cláusula en la IF declaración:

DECLARE
n_sales NUMBER;
n_commission NUMBER;
BEGIN
n_sales := 120000;
IF n_sales > 100000 THEN
n_commission := 0.2;
GOTO zero_commission;
elsif n_sales > 50000 THEN
n_commission := 0.15;
elsif n_sales > 20000 THEN
n_commission := 0.1;
ELSE
<<zero_commission>>
n_commission := 0;
END IF;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Oracle emitió el siguiente error.

PLS-00375: illegal GOTO statement; this GOTO cannot branch to


label 'ZERO_COMMISSION'
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En tercer lugar, no se puede utilizar una GOTO declaración para transferir el control
de un subprograma a un controlador de excepciones .
Cuarto, no puede usar una GOTO declaración para transferir el control de un
manejador de excepciones al bloque actual.

Declaración PL / SQL NULL

Introducción a la NULL declaración PL / SQL


La NULL declaración PL / SQL tiene el siguiente formato:

NULL;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La NULL declaración es una NULL palabra clave seguida de un punto y coma


( ;). La NULL declaración no hace nada excepto que pasa el control a la siguiente
declaración.

La NULL declaración es útil para:

• Mejorar la legibilidad del código


• Proporcionar un objetivo para una GOTO declaración
• Crear marcadores de posición para subprogramas

Mejorando la legibilidad del código


El siguiente código envía un correo electrónico a los empleados cuyos cargos
son Sales Representative.

IF job_title = 'Sales Representative' THEN


send_email;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

¿Qué debería hacer el programa por los empleados cuyo puesto de trabajo no lo
es Sales Representative? Puede suponer que no debería hacer nada. Debido a que esta
lógica no se menciona explícitamente en el código, es posible que se pregunte si
pasa por alto algo más.

Para que quede más claro, puede agregar un comentario. Por ejemplo:

-- Send email to only Sales Representative,


-- for other employees, do nothing
IF job_title = 'Sales Representative' THEN
send_email;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

O puede agregar una ELSE cláusula que consista en una NULL declaración para
indicar claramente que no es necesario que otros empleados tomen medidas.

IF job_title = 'Sales Representative' THEN


send_email;
ELSE
NULL;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Del mismo modo, puede utilizar una NULL declaración en la ELSE cláusula de
una CASE declaración simple como se muestra en el siguiente ejemplo:

DECLARE
n_credit_status VARCHAR2( 50 );
BEGIN
n_credit_status := 'GOOD';

CASE n_credit_status
WHEN 'BLOCK' THEN
request_for_aproval;
WHEN 'WARNING' THEN
send_email_to_accountant;
ELSE
NULL;
END CASE;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, si el estado del crédito no está bloqueado o advirtiendo, el


programa no hace nada.

Proporcionar un objetivo para una GOTO declaración


Cuando utilice una GOTO declaración, debe especificar una etiqueta seguida de al
menos una declaración ejecutable.
El siguiente ejemplo usa una GOTO instrucción para moverse rápidamente al final
del programa si no se requiere ningún procesamiento adicional:

DECLARE
b_status BOOLEAN
BEGIN
IF b_status THEN
GOTO end_of_program;
END IF;
-- further processing here
-- ...
<<end_of_program>>
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Tenga en cuenta que se producirá un error si no tiene la NULL declaración después


de la end_of_program etiqueta.

Crear marcadores de posición para subprogramas


El siguiente ejemplo crea un procedimiento llamado request_for_approvalque aún no
tiene el código en el cuerpo. PL / SQL requiere al menos una declaración ejecutable
en el cuerpo del procedimiento para compilar con éxito, por lo tanto, agregamos
una NULL declaración al cuerpo como marcador de posición. Posteriormente podrás
completar el código real.

CREATE PROCEDURE request_for_aproval(


customer_id NUMBER
)
AS
BEGIN
NULL;
END;

Sección 3. Procesamiento iterativo con bucles


• Sentencia LOOP básica : muestra cómo utilizar la sentencia LOOP básica para
ejecutar una secuencia de código varias veces.
• Sentencia FOR LOOP numérica : aprenda a ejecutar una secuencia de sentencias
un número fijo de veces.
• Ciclo WHILE : ejecuta una secuencia de declaraciones siempre que una condición
especificada sea VERDADERA.
• CONTINUE : use la instrucción CONTINUE para omitir la iteración actual del ciclo y
continuar inmediatamente la siguiente iteración.

BUCLE PL / SQL

LOOP Sintaxis PL / SQL


La LOOP declaración PL / SQL tiene la siguiente estructura:

<<label>> LOOP
statements;
END LOOP loop_label;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Esta estructura es la más básica de todas las construcciones de bucle, incluidas FOR
LOOP y WHILE LOOP. Esta LOOPdeclaración básica consta de una LOOPpalabra clave, un
cuerpo de código ejecutable y las END LOOPpalabras clave.

La LOOP declaración ejecuta las declaraciones en su cuerpo y devuelve el control al


principio del ciclo. Normalmente, el cuerpo del bucle contiene al menos
una declaración EXITo EXIT WHEN para terminar el bucle. De lo contrario, el bucle se
convierte en un bucle infinito.

La LOOP declaración puede tener una etiqueta opcional que aparece al principio y al
final de la declaración.

Es una buena práctica utilizar la LOOP declaración cuando:

• Quieres ejecutar el cuerpo del bucle al menos una vez.


• No está seguro de la cantidad de veces que desea que se ejecute el ciclo.

EXIT declaración
La EXIT declaración le permite salir incondicionalmente de la iteración actual de un
bucle.
LOOP
EXIT;
END LOOP;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Normalmente, usa la EXIT declaración con una IF declaración para terminar un ciclo
cuando una condición es verdadera:

LOOP
IF condition THEN
EXIT;
END IF;
END LOOP;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El siguiente ejemplo ilustra cómo usar la LOOP instrucción para ejecutar una
secuencia de código y una EXIT instrucción para terminar el ciclo.

DECLARE
l_counter NUMBER := 0;
BEGIN
LOOP
l_counter := l_counter + 1;
IF l_counter > 3 THEN
EXIT;
END IF;
dbms_output.put_line( 'Inside loop: ' || l_counter ) ;
END LOOP;
-- control resumes here after EXIT
dbms_output.put_line( 'After loop: ' || l_counter );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

Inside loop: 1
Inside loop: 2
Inside loop: 3
After loop: 4
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

A continuación, se explica la lógica del código:

• Primero, declare e inicialice una variable l_counter a cero.


• En segundo lugar, aumente l_counteren uno dentro del bucle y salga del
bucle si l_counteres mayor que tres. Si l_counteres menor o igual a tres, muestre
el l_countervalor. Debido a que el valor inicial de l_counteres cero, el código en
el cuerpo del bucle se ejecuta tres veces antes de que finalice.
• En tercer lugar, muestre el valor de l_counterdespués del ciclo.

EXIT WHEN declaración


La EXIT WHENdeclaración tiene la siguiente sintaxis:

EXIT WHEN condition;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La EXIT WHEN declaración sale de la iteración actual de un bucle cuando la condición


en la WHENcláusula es TRUE. Básicamente, la EXIT WHEN declaración es una
combinación de EXIT una IF THEN declaración y una declaración.

Cada vez que el control llega a la EXIT WHEN sentencia, se evalúa la condición. Si la
condición se evalúa a TRUE, entonces el ciclo termina. De lo contrario, la EXIT WHEN
cláusula no hace nada. Dentro del cuerpo del bucle, debe realizar la
condición TRUEen algún momento para evitar un bucle infinito.

El siguiente ejemplo usa la EXIT WHEN declaración para terminar un bucle.

DECLARE
l_counter NUMBER := 0;
BEGIN
LOOP
l_counter := l_counter + 1;
EXIT WHEN l_counter > 3;
dbms_output.put_line( 'Inside loop: ' || l_counter ) ;
END LOOP;

-- control resumes here after EXIT


dbms_output.put_line( 'After loop: ' || l_counter );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Observe que este ejemplo es lógicamente equivalente al ejemplo que usa la EXIT
declaración anterior.
Bucles anidados
Es posible anidar una LOOP declaración dentro de otra LOOP declaración como se
muestra en el siguiente ejemplo:

DECLARE
l_i NUMBER := 0;
l_j NUMBER := 0;
BEGIN
<<outer_loop>>
LOOP
l_i := l_i + 1;
EXIT outer_loop WHEN l_i > 2;
dbms_output.put_line('Outer counter ' || l_i);
-- reset inner counter
l_j := 0;
<<inner_loop>> LOOP
l_j := l_j + 1;
EXIT inner_loop WHEN l_j > 3;
dbms_output.put_line(' Inner counter ' || l_j);
END LOOP inner_loop;
END LOOP outer_loop;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

Outer counter 1
Inner counter 1
Inner counter 2
Inner counter 3
Outer counter 2
Inner counter 1
Inner counter 2
Inner counter 3
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
PL / SQL PARA BUCLE

Introducción a la FOR LOOP declaración PL / SQL


PL / SQL FOR LOOP ejecuta una secuencia de declaraciones un número específico de
veces. La FOR LOOP declaración PL / SQL tiene la siguiente estructura:

FOR index IN lower_bound .. upper_bound


LOOP
statements;
END LOOP;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El index es una variable implícita. Es local a la FOR LOOP declaración. En otras palabras,
no puede hacer referencia a él fuera del bucle.

Dentro del bucle, puede hacer referencia index pero no puede cambiar su valor. Una
vez FOR LOOP que se ejecuta la instrucción, se index vuelve indefinido.

Ambos lower_boundy upper_bound son números o expresiones que se evalúan como


números. Los lower_boundy upper_boundse evalúan una vez cuando FOR
LOOPcomienza la instrucción. Sus valores se almacenan
como PLS_INTEGERvalores temporales. Los resultados de lower_boundy upper_boundse
redondean al número entero más cercano si es necesario.

Si modifica los valores de lower_bound o upper_bounddentro del bucle, el cambio no


tendrá ningún efecto porque se evalúan una sola vez antes de que comience la
primera iteración del bucle.

Normalmente, lower_bound es menor que upper_bound. En este caso, index se establece


en lower_bound, la statementsejecución y el control regresa a la parte superior del
bucle, donde index se compara con upper_bound. Si index es menor
que upper_bound, index se incrementa en uno, la statements ejecución y el control
vuelven nuevamente a la parte superior del ciclo. Cuando index es mayor
que upper_bound, el bucle termina y el control se transfiere a la instrucción después
de la FOR LOOP instrucción.
Si lower_boundes igual a upper_bound, se statements ejecuta solo una
vez. Cuando lower_boundes mayor que upper_bound, statementsno se ejecuta en
absoluto.

FOR LOOP Ejemplos de PL / SQL


Tomemos algunos ejemplos del uso de la FOR LOOP declaración para comprender
cómo funciona.

A) FOR LOOP Ejemplo simple de PL / SQL

En este ejemplo, el bucle index es l_counter, lower_bound es uno y upper_bound es


cinco. El ciclo muestra una lista de números enteros del 1 al 5.

BEGIN
FOR l_counter IN 1..5
LOOP
DBMS_OUTPUT.PUT_LINE( l_counter );
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

1
2
3
4
5
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
B) STEP Cláusula de simulación en FOR LOOP declaración

El índice de bucle aumenta en uno después de cada iteración de bucle y no puede


cambiar el incremento, por ejemplo, dos, tres y cuatro. Sin embargo, puede usar
una variable adicional para simular el incremento en dos, tres, cuatro, etc., como se
muestra en el siguiente ejemplo:

DECLARE
l_step PLS_INTEGER := 2;
BEGIN
FOR l_counter IN 1..5 LOOP
dbms_output.put_line (l_counter*l_step);
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Resultado:

2
4
6
8
10
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El resultado muestra que, después de cada iteración del ciclo, el número de salida
se incrementa en dos en lugar de uno.

C) Variable de referencia con el mismo nombre que el índice de bucle

Considere el siguiente ejemplo:

DECLARE
l_counter PLS_INTEGER := 10;
BEGIN
FOR l_counter IN 1.. 5 loop
DBMS_OUTPUT.PUT_LINE (l_counter);
end loop;
-- after the loop
DBMS_OUTPUT.PUT_LINE (l_counter);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

1
2
3
4
5
10
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, teníamos una variable nombrada l_counter, que también es el


nombre del índice. El resultado muestra que l_counter en el FORbucle se oculta la
variable l_counter declarada en el bloque adjunto.

Para hacer referencia a la variable l_counter dentro del bucle, debe calificarla usando
una etiqueta de bloque como se muestra a continuación:
<<outer>>
DECLARE
l_counter PLS_INTEGER := 10;
BEGIN
FOR l_counter IN 1.. 5 loop
DBMS_OUTPUT.PUT_LINE ('Local counter:' || l_counter);
outer.l_counter := l_counter;
end loop;
-- after the loop
DBMS_OUTPUT.PUT_LINE ('Global counter' || l_counter);
END outer;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
D) Índice de bucle de referencia fuera del FOR LOOP

El siguiente ejemplo provoca un error porque hace referencia al índice de bucle,


que no está definido, fuera de la FOR LOOP declaración.

BEGIN
FOR l_index IN 1..3 loop
DBMS_OUTPUT.PUT_LINE (l_index);
END LOOP;
-- referencing index after the loop
DBMS_OUTPUT.PUT_LINE (l_index);
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Oracle emitió el siguiente error:

PLS-00201: identifier 'L_INDEX' must be declared


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

FOR LOOP con REVERSEpalabra clave


A continuación se muestra la estructura de la FOR LOOP declaración con REVERSE
palabra clave:

FOR index IN REVERSE lower_bound .. upper_bound


LOOP
statements;
END LOOP;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Con la REVERSE palabra clave, el index se establece en upper_bound y se reduce en uno


en cada iteración de bucle hasta que alcanza lower_bound.
Vea el siguiente ejemplo:

BEGIN
FOR l_counter IN REVERSE 1..3
LOOP
DBMS_OUTPUT.PUT_LINE( l_counter );
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Resultado:

3
2
1
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Sin la REVERSE palabra clave, el resultado será:

1
2
3

Bucle PL / SQL WHILE

La sintaxis del bucle WHILE


Aquí está la sintaxis de la WHILEdeclaración de bucle:

WHILE condition
LOOP
statements;
END LOOP;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La condición en WHILE es una expresión booleana que se evalúa como TRUE, FALSE
o NULL.

La WHILE sentencia de bucle continúa ejecutando las sentencias entre LOOP


y END LOOP siempre que la condición en la WHILE cláusula se evalúe TRUE.

PL / SQL evalúa la condición en la WHILE cláusula antes de cada iteración del


ciclo. Si la condición es TRUE, entonces se ejecuta el cuerpo del bucle. En caso de
que sea FALSE o NULL, el bucle termina.
Si la condición es FALSE antes de ingresar al bucle, el WHILE bucle no se ejecuta en
absoluto. Este comportamiento es diferente de la LOOP instrucción cuyo cuerpo de
bucle siempre se ejecuta una vez.

Para terminar el ciclo prematuramente, usa una instrucción EXITo EXIT WHEN.

WHILE Ejemplos de bucle PL / SQL


Tomemos algunos ejemplos del uso de la WHILEdeclaración de bucle para ver cómo
funciona.

A) Ejemplo de bucle simple

El siguiente ejemplo ilustra cómo utilizar la WHILEdeclaración de bucle:

DECLARE
n_counter NUMBER := 1;
BEGIN
WHILE n_counter <= 5
LOOP
DBMS_OUTPUT.PUT_LINE( 'Counter : ' || n_counter );
n_counter := n_counter + 1;
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

Counter : 1
Counter : 2
Counter : 3
Counter : 4
Counter : 5
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo:

• Primero, el contador se inicializó a cero.


• En segundo lugar, la condición de la WHILE cláusula se evaluó antes de cada
iteración del ciclo.
• En tercer lugar, dentro del cuerpo del bucle, el contador se incrementó en uno en
cada iteración del bucle. Después de cinco iteraciones, la condición fue la FALSE que
provocó la terminación del ciclo.
B) ejemplo de bucle terminado por EXIT WHEN declaración

El siguiente ejemplo es el mismo que el anterior, excepto que tiene


una EXITWHENdeclaración adicional .

DECLARE
n_counter NUMBER := 1;
BEGIN
WHILE n_counter <= 5
LOOP
DBMS_OUTPUT.PUT_LINE( 'Counter : ' || n_counter );
n_counter := n_counter + 1;
EXIT WHEN n_counter = 3;
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El siguiente es el resultado:

Counter : 1
Counter : 2
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La condición en la EXIT WHEN cláusula evaluada como verdadera cuando el contador


es tres. Por lo tanto, el cuerpo del bucle solo se ejecutó dos veces antes de
terminar.

PL / SQL CONTINUE

CONTINUE Declaración PL / SQL


La CONTINUE declaración le permite salir de la iteración del ciclo actual e
inmediatamente continuar con la siguiente iteración de ese ciclo.

La CONTINUE declaración tiene una sintaxis simple:

CONTINUE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Por lo general, la CONTINUEdeclaración se usa dentro de una IF THEN declaración


para salir de la iteración del ciclo actual en función de una condición específica,
como se muestra a continuación:
IF condition THEN
CONTINUE;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Se CONTINUEpuede utilizar en todas las construcciones de bucle LOOP, incluidos , FOR


LOOPy WHILE LOOP.

CONTINUE Ejemplo de declaración PL / SQL

El siguiente es un ejemplo simple del uso de la CONTINUE declaración para omitir la


ejecución del cuerpo del bucle para números impares:

BEGIN
FOR n_index IN 1 .. 10
LOOP
-- skip odd numbers
IF MOD( n_index, 2 ) = 1 THEN
CONTINUE;
END IF;
DBMS_OUTPUT.PUT_LINE( n_index );
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

La salida es:

2
4
6
8
10
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

CONTINUE WHEN Declaración PL / SQL


La CONTINUE WHEN declaración sale de la iteración del ciclo actual basándose en una
condición e inmediatamente continúa con la siguiente iteración de ese ciclo.

La sintaxis de la CONTINUE WHEN declaración es:

CONTINUE WHEN condition;


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
La condición de la WHEN cláusula se evalúa cada vez CONTINUE WHEN que se
alcanza la declaración. Si la condición es TRUE, se omite el ciclo actual y el control
se transfiere a la siguiente iteración del ciclo. Si la condición no es TRUE, ya
sea FALSEo NULL, la CONTINUE WHEN declaración no hace nada.

Básicamente, la CONTINUE WHEN declaración es la combinación de una IF THEN


declaración y una CONTINUEdeclaración:

IF condition THEN
CONTINUE;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Al igual que en la CONTINUE declaración, se puede utilizar la CONTINUE


WHENdeclaración en LOOP, FOR LOOP y WHILE LOOP.

CONTINUE Ejemplo de declaración PL / SQL

El siguiente ejemplo ilustra cómo usar la CONTINUE WHEN instrucción para omitir la
ejecución del cuerpo del bucle para números pares:

BEGIN
FOR n_index IN 1 .. 10
LOOP
-- skip even numbers
CONTINUE
WHEN MOD( n_index, 2 ) = 0;
DBMS_OUTPUT.PUT_LINE( n_index );
END LOOP;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

1
3
5
7
9
Sección 4. Select into
La SELECT INTO declaración PL / SQL es la forma más sencilla y rápida de recuperar
una sola fila de una tabla en variables . A continuación, se ilustra la sintaxis de
la SELECT INTO declaración PL / SQL :

SELECT
select_list
INTO
variable_list
FROM
table_name
WHERE
condition;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis, el número de columnas en variable_list debe ser el mismo que el


número de variables (o el número de componentes de un registro)
en select_list. Además, su tipo de datos correspondiente debe ser compatible.

Además de la WHERE cláusula, se pueden utilizar otras cláusulas de


la SELECTdeclaración como INNER JOIN, GROUP BY, HAVING, y UNION.

Si la SELECT declaración devuelve más de una fila, Oracle generará


la TOO_MANY_ROWS excepción . Si la SELECT declaración no devuelve ninguna fila,
Oracle generará la NO_DATA_FOUND excepción.

SELECT INTO Ejemplos de PL / SQL


Usemos las tablas customers y contacts en la base de datos de muestra para la
demostración.
A) PL / SQL SELECT INTO - seleccionando un ejemplo de columna

El siguiente ejemplo utiliza una SELECT INTOdeclaración para obtener el nombre de


un cliente en función de la identificación del cliente, que es la clave principal de
la customers tabla.

DECLARE
l_customer_name customers.name%TYPE;
BEGIN
-- get name of the customer 100 and assign it to l_customer_name
SELECT name INTO l_customer_name
FROM customers
WHERE customer_id = 100;
-- show the customer name
dbms_output.put_line( v_customer_name );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo:

• Primero, declare una variable l_customer_name cuyo tipo de datos se ancle a las
columnas de nombre de la tabla de clientes. Esta variable contendrá el nombre del
cliente.
• En segundo lugar, use la SELECT INTO declaración para seleccionar un valor de la
columna de nombre y asígnelo a la l_customer_name variable.
• En tercer lugar, muestre el nombre del cliente mediante el dbms_output.put_line
procedimiento.

Debido a que la customers tabla tiene solo una fila con el ID de cliente 100, el bloque
de código muestra el nombre del cliente.

Verizon
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Si no hubiera tal fila, el bloque de código fallaría con una NO_DATA_FOUND


excepción no controlada .

B) PL / SQL SELECT INTO: selección de un ejemplo de fila completo

El siguiente ejemplo obtiene la fila completa de la customers tabla para un ID de


cliente específico:

DECLARE
r_customer customers%ROWTYPE;
BEGIN
-- get the information of the customer 100
SELECT * INTO r_customer
FROM customers
WHERE customer_id = 100;
-- show the customer info
dbms_output.put_line( r_customer.name || ', website: ' || r_customer.website );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

Verizon, website: http://www.verizon.com


Idioma del código: JavaScript ( javascript )

En este ejemplo:

• Primero, declare un registro basado en la fila de la customers tabla. Este registro


contendrá toda la fila de la customers tabla.
• En segundo lugar, seleccione el cliente cuya identificación es 100 en el r_customer
registro.
• En tercer lugar, muestre el nombre y el sitio web del cliente.

C) PL / SQL SELECT INTO- ejemplo de selección de datos en múltiples variables

El siguiente ejemplo obtiene los nombres de cliente y contacto de


las tablas customers y contacts para una identificación de cliente específica.

DECLARE
l_customer_name customers.name%TYPE;
l_contact_first_name contacts.first_name%TYPE;
l_contact_last_name contacts.last_name%TYPE;
BEGIN
-- get customer and contact names
SELECT
name,
first_name,
last_name
INTO
l_customer_name,
l_contact_first_name,
l_contact_last_name
FROM
customers
INNER JOIN contacts USING( customer_id )
WHERE
customer_id = 100;
-- show the information
dbms_output.put_line(
l_customer_name || ', Contact Person: ' ||
l_contact_first_name || ' ' || l_contact_last_name );
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Oracle emitió el siguiente resultado:

Verizon, Contact Person: Elisha Lloyd


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo:

• En primer lugar, declarar tres


variables l_customer_name, l_contact_first_name, l_contact_last_namepara mantener el
cliente y el nombre del contacto.
• En segundo lugar, use la SELECT INTO declaración para obtener los nombres de
clientes y contactos del ID de cliente 100 de las tablas customers y contacts en las
variables correspondientes
• l_customer_name, l_contact_first_name, l_contact_last_name.
• En tercer lugar, muestre los nombres del cliente y del contacto.

SELECT INTO Errores comunes de PL / SQL


Si el número de columnas y expresión en la SELECT cláusula es mayor que el
número de variables en la INTO cláusula, Oracle emite este error:

ORA-00947: not enough values The INTO list contains fewer


variables than the SELECT list.
Lenguaje de código: PHP ( php )

Oracle emite el siguiente error si el número de columnas y expresión en


la SELECTcláusula es menor que el número de variables en la INTOcláusula:

ORA-00913: too many values The INTO list contains more


variables than the SELECT list.
Lenguaje de código: PHP ( php )
Si el número de variables y elementos en la lista de selección es el mismo, pero sus
tipos de datos correspondientes no son compatibles, Oracle no puede convertir
implícitamente de un tipo a otro. Emitirá el siguiente error:

ORA-06502: PL/SQL: numeric or value error

Sección 5. Controladores de excepciones


• Excepción : muestra cómo manejar las excepciones en un bloque.
• Generar excepciones : aprenda a generar una excepción explícitamente con la RAISE
declaración.
• Usando raise_application_error : genere una excepción con un mensaje de error
definido por el usuario.
• Propagación de excepciones : aprenda cómo PL / SQL propaga una excepción no
controlada desde el bloque actual hasta su bloque adjunto.
• Manejo de otras excepciones no controladas : muestra cómo usar
las funciones SQLCODE y SQLERRM para manejar otras excepciones no controladas.

Excepción PL / SQL

Introducción a las excepciones PL / SQL


PL / SQL trata todos los errores que ocurren en
un bloque , procedimiento o función anónimos como excepciones. Las excepciones
pueden tener diferentes causas, como errores de codificación, errores e incluso
fallas de hardware.

No es posible anticipar todas las posibles excepciones, sin embargo, puede escribir
código para manejar las excepciones y permitir que el programa continúe
ejecutándose normalmente.

El código que escribe para manejar las excepciones se denomina controlador de


excepciones.

Un bloque PL / SQL puede tener una sección de manejo de excepciones, que


puede tener uno o más manejadores de excepciones.

Aquí está la sintaxis básica de la sección de manejo de excepciones:


BEGIN
-- executable section
...
-- exception-handling section
EXCEPTION
WHEN e1 THEN
-- exception_handler1
WHEN e2 THEN
-- exception_handler1
WHEN OTHERS THEN
-- other_exception_handler
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis e1, e2 hay excepciones.

Cuando ocurre una excepción en la sección ejecutable, la ejecución del bloque


actual se detiene y el control se transfiere a la sección de manejo de excepciones.

Si e1 ocurrió la excepción , se exception_handler1ejecuta. Si e2ocurrió la excepción ,


se exception_handler2ejecuta. En caso de que surja alguna otra excepción,
se other_exception_handlerejecuta.

Después de que se ejecuta un manejador de excepciones, el control se transfiere a


la siguiente instrucción del bloque adjunto. Si no hay un bloque adjunto, el control
vuelve al invocador si el manejador de excepciones está en un subprograma o
entorno de host (SQL Developer o SQL * Plus) si el manejador de excepciones está
en un bloque anónimo .

Si ocurre una excepción pero no hay un manejador de excepciones, entonces


la excepción se propaga .

Ejemplos de excepciones PL / SQL


Tomemos algunos ejemplos de manejo de excepciones.

NO_DATA_FOUND Ejemplo de excepción PL / SQL

El siguiente bloque acepta una identificación de cliente como entrada y devuelve el


nombre del cliente:
DECLARE
l_name customers.NAME%TYPE;
l_customer_id customers.customer_id%TYPE := &customer_id;
BEGIN
-- get the customer name by id
SELECT name INTO l_name
FROM customers
WHERE customer_id = l_customer_id;

-- show the customer name


dbms_output.put_line('Customer name is ' || l_name);

END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Si ejecuta el bloque e ingresa la identificación del cliente como cero, Oracle emitirá
el siguiente error:

ORA-01403: no data found


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El ORA-01403 es una excepción predefinida.

Tenga en cuenta que la siguiente línea no se ejecuta en absoluto porque el control


se transfirió a la sección de manejo de excepciones.

dbms_output.put_line('Customer name is ' || l_name);


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Para emitir un mensaje más significativo, puede agregar una sección de manejo de
excepciones de la siguiente manera:

DECLARE
l_name customers.NAME%TYPE;
l_customer_id customers.customer_id%TYPE := &customer_id;
BEGIN
-- get the customer
SELECT NAME INTO l_name
FROM customers
WHERE customer_id = l_customer_id;

-- show the customer name


dbms_output.put_line('customer name is ' || l_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Customer ' || l_customer_id || ' does not exist');
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Si ejecuta este bloque de código e ingresa el ID de cliente 0, obtendrá el siguiente


mensaje:

Customer 0 does not exist


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
TOO_MANY_ROWS Ejemplo de excepción PL / SQL

Primero, modifique el bloque de código en el ejemplo anterior de la siguiente


manera y ejecútelo:

DECLARE
l_name customers.name%TYPE;
l_customer_id customers.customer_id%TYPE := &customer_id;
BEGIN
-- get the customer
SELECT name INTO l_name
FROM customers
WHERE customer_id <= l_customer_id;

-- show the customer name


dbms_output.put_line('Customer name is ' || l_name);

EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Customer ' || l_customer_id || ' does not exist');
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En segundo lugar, ingrese el ID de cliente 10 y obtendrá el siguiente error:

ORA-01422: exact fetch returns more than requested number of


rows
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Esta es otra excepción llamada TOO_MANY_ROWS que no fue manejada por el código.
En tercer lugar, agregue el controlador de excepciones para la TOO_MANY_ROWS
excepción:

DECLARE
l_name customers.NAME%TYPE;
l_customer_id customers.customer_id%TYPE := &customer_id;
BEGIN
-- get the customer
SELECT NAME INTO l_name
FROM customers
WHERE customer_id > l_customer_id;

-- show the customer name


dbms_output.put_line('Customer name is ' || l_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Customer ' || l_customer_id || ' does not exist');
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('The database returns more than one customer');
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Finalmente, si ejecuta el código, ingrese 10 como la identificación del cliente. Verá


que el código no generará ninguna excepción y emitirá el siguiente mensaje:

The database returns more than one customer


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Categorías de excepción PL / SQL


PL / SQL tiene tres categorías de excepción:

• Las excepciones definidas internamente son errores que surgen del entorno de la
base de datos Oracle. El sistema de ejecución genera automáticamente las
excepciones definidas internamente. ORA-27102 (memoria insuficiente) es un
ejemplo de excepciones definidas internamente. Tenga en cuenta que las
excepciones definidas internamente no tienen nombres, sino un código de error.
• Las excepciones predefinidas son errores que ocurren durante la ejecución del
programa. Las excepciones predefinidas son excepciones definidas internamente
que PL / SQL ha dado nombres por ejemplo, NO_DATA_FOUND, TOO_MANY_ROWS.
• Las excepciones definidas por el usuario son excepciones personalizadas definidas
por usuarios como usted. Las excepciones definidas por el usuario se deben
generar explícitamente.
La siguiente tabla ilustra las diferencias entre las categorías de excepción.

Categoría Definidor Tiene código de Tiene Criado Criado


error nombre implícitamente explícitamente

Definido Sistema de tiempo de Siempre Solo si asigna sí Opcionalmente


internamente ejecución uno

Predefinido Sistema de tiempo de Siempre Siempre sí Opcionalmente


ejecución

Usuario definido Usuario Solo si asigna Siempre No Siempre


uno

Excepciones de aumento de PL / SQL

Para generar una excepción explícitamente, usa la RAISE declaración. La RAISE


declaración le permite:

• Genere una excepción definida por el usuario.


• Genere una excepción definida internamente.
• Volviendo a plantear la excepción actual.

Generar una excepción definida por el usuario


Una excepción definida por el usuario la definen usuarios como usted u otros
desarrolladores en la sección de declaración de un bloque o subprograma.

Declarar una excepción definida por el usuario

Para definir una excepción definida por el usuario, utilice la siguiente sintaxis:

DECLARE
exception_name EXCEPTION;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Similar a la declaración de variable , declaras una excepción en la sección de


declaración de un bloque.
Se debe haber asignado una excepción definida por el usuario error_code. Para
hacerlo, usa el EXCEPTION_INIT pragma de la siguiente manera:

PRAGMA EXCEPTION_INIT (exception_name, error_code)


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis, error_code es un número entero que va de -20,999a -


20,000. Y messagees una cadena de caracteres con una longitud máxima
de 2,048bytes.

La sintaxis completa para declarar una excepción definida por el usuario es la


siguiente:

DECLARE
exception_name EXCEPTION;
PRAGMA EXCEPTION_INIT (exception_name, error_number);
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Generación de un ejemplo de excepción definido por el usuario

El siguiente ejemplo ilustra cómo declarar una excepción definida por el usuario y
asociarla con un código de error.

DECLARE
e_credit_too_high EXCEPTION;
PRAGMA exception_init( e_credit_too_high, -20001 );
l_max_credit customers.credit_limit%TYPE;
l_customer_id customers.customer_id%TYPE := &customer_id;
l_credit customers.credit_limit%TYPE := &credit_limit;
BEGIN
-- get the meax credit limit
SELECT MAX(credit_limit)
INTO l_max_credit
FROM customers;

-- check if input credit is greater than the max credit


IF l_credit > l_max_credit THEN
RAISE e_credit_too_high;
END IF;

-- if not, update credit limit


UPDATE customers
SET credit_limit = l_credit
WHERE customer_id = l_customer_id;
COMMIT;
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo,

• Primero, declare una excepción definida por el usuario e_credit_too_high y la


asocie con el número de error -20001.
• En segundo lugar, seleccione el crédito máximo de la customers tabla usando
la MAX()función y asigne este valor a la l_max_credit variable.
• En tercer lugar, verifique si el crédito de entrada con el crédito máximo, si el crédito
de entrada es mayor que el máximo, luego plantee la e_credit_too_high excepción.
• Finalmente, actualice el cliente cuya identificación ingresó el usuario con el nuevo
límite de crédito.

Aquí está el resultado si ingresa la identificación del cliente 100 y el límite de


crédito 20000:

ORA-20001:

Si desea incluir un mensaje personalizado, puede reemplazar la línea:

RAISE e_credit_too_high;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

por la siguiente línea:

raise_application_error(-20001,'Credit is too high');


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Y ejecute el bloque de código nuevamente, recibirá el siguiente error:

ORA-20001: Credit is too high


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Provocando una excepción definida internamente


Normalmente, el sistema en tiempo de ejecución genera implícitamente
excepciones definidas internamente cuando ocurren. Además, puede generar
explícitamente una excepción definida internamente con la RAISE declaración si la
excepción tiene un nombre:

RAISE exception_name;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Este ejemplo muestra cómo generar una excepción definida
internamente INVALID_NUMBER:

DECLARE
l_customer_id customers.customer_id%TYPE := &customer_id;
BEGIN
-- get the meax credit limit
IF l_customer_id < 0 THEN
RAISE invalid_number;
END IF;
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Si ejecuta el bloqueo e ingresa el ID de cliente -10, obtendrá el siguiente error:

ORA-01722: invalid number


Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Reanudando la excepción actual


Puede volver a generar la excepción actual con la RAISE declaración. Al volver a
generar una excepción, se pasa al bloque adjunto, que luego se puede manejar
más adelante. Para volver a generar una excepción, no es necesario que especifique
el nombre de la excepción.

DECLARE
e_credit_too_high EXCEPTION;
PRAGMA exception_init( e_credit_too_high, -20001 );
l_max_credit customers.credit_limit%TYPE;
l_customer_id customers.customer_id%TYPE := &customer_id;
l_credit customers.credit_limit%TYPE := &credit_limit;
BEGIN
BEGIN
-- get the max credit limit
SELECT MAX(credit_limit)
INTO l_max_credit
FROM customers;

-- check if input credit is greater than the max credit


IF l_credit > l_max_credit THEN
RAISE e_credit_too_high;
END IF;
EXCEPTION
WHEN e_credit_too_high THEN
dbms_output.put_line('The credit is too high' || l_credit);
RAISE; -- reraise the exception
END;
EXCEPTION
WHEN e_credit_too_high THEN
-- get average credit limit
SELECT avg(credit_limit)
into l_credit
from customers;

-- adjust the credit limit to the average


dbms_output.put_line('Adjusted credit to ' || l_credit);

-- update credit limit


UPDATE customers
SET credit_limit = l_credit
WHERE customer_id = l_customer_id;

COMMIT;
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo:

• Primero, obtenga el límite de crédito máximo de la customers tabla.


• En segundo lugar, compare el crédito máximo con el crédito ingresado por el
usuario. Si el crédito de entrada del usuario es mayor que el crédito máximo,
genere la e_credit_too_high excepción.
• En tercer lugar, muestre un mensaje y vuelva a generar la excepción en la sección
de manejo de excepciones en el bloque interno.
• Finalmente, en el bloque exterior, reasigne el crédito promedio a la l_creditvariable y
actualice al cliente con el crédito recién ajustado.

Si ingresa la identificación del cliente 100 y el límite de crédito 10000, el límite de


crédito del cliente se actualizará al crédito promedio.

SELECT * FROM customers


WHERE customer_id = 100;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:


Oracle RAISE_APPLICATION_ERROR

Introducción al raise_application_error procedimiento


El procedimiento le raise_application_errorpermite emitir un error definido por el
usuario desde un bloque de código o programa almacenado.

Al utilizar este procedimiento, puede informar errores a las personas que llaman en
lugar de devolver excepciones no controladas .

La raise_application_error sintaxis es la siguiente:

raise_application_error(
error_number,
message
[, {TRUE | FALSE}]
);
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis:

• El error_number es un número entero negativo con el rango de -20999a -20000.


• El message es una cadena de caracteres que representa el mensaje de error. Su
longitud es de hasta 2048 bytes.
• Si el tercer parámetro es FALSE, el error reemplaza todos los errores anteriores. Si es
así TRUE, el error se agrega a la pila de errores anteriores.

El raise_application_error pertenece al paquete DBMS_STANDARD, por lo tanto, no es


necesario calificar las referencias al mismo.

Cuando se raise_application_errorejecuta el procedimiento, Oracle detiene la ejecución


del bloque actual inmediatamente. También invierte todos los cambios realizados
en los parámetros OUT o IN OUT.

Tenga en cuenta que los cambios realizados en la estructura de datos global,


como las variables empaquetadas y objetos de la base de datos, como las tablas,
no se revertirán. Por lo tanto, debe ejecutar explícitamente la ROLLBACKinstrucción
para revertir el efecto del DML.

raise_application_error Ejemplo de Oracle


Echemos un vistazo a algunos ejemplos del uso del raise_application_error
procedimiento para generar excepcion es .

Este ejemplo usa el raise_application_error procedimiento para generar una excepción


con id -20111y mensaje 'Credit Limit Exceeded':

DECLARE
credit_limit_exceed EXCEPTION;
PRAGMA exception_init(credit_limit_exceed, -20111);

l_customer_id customers.customer_id%TYPE := &customer_id;


l_credit_limit customers.credit_limit%TYPE := &credit_limit;

l_customer_credit customers.credit_limit%TYPE;

BEGIN
-- get customer credit limit
SELECT credit_limit INTO l_customer_credit
FROM customers
WHERE customer_id = l_customer_id;

-- raise an exception if the credit limit is exceeded


IF l_customer_credit > l_credit_limit THEN
raise_application_error(-20111,'Credit Limit Exceeded');
END IF;

dbms_output.put_line('Credit Limit is checked and passed');

EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Customer with id ' || l_customer_id || ' does not exist.');
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
En este ejemplo:

• Primero, declare una excepción definida por el usuario credit_limit_exceed asociada


con el número de error -20111.
• En segundo lugar, declare dos variables l_customer_id y l_credit_limit almacene la
identificación del cliente y el límite de crédito ingresado por los usuarios.
• En tercer lugar, obtenga el límite de crédito del cliente en función de la
identificación del cliente.
• Finalmente, verifique el crédito de entrada con el crédito del cliente y
use raise_application_error para generar una excepción.

Propagación de excepciones PL / SQL

Introducción a la propagación de excepciones


Cuando ocurre una excepción , PL / SQL busca un manejador de excepciones en el
bloque actual, por ejemplo, bloque anónimo , procedimiento o función de la
excepción. Si no encuentra una coincidencia, PL / SQL propaga la excepción al
bloque adjunto del bloque actual.

PL / SQL luego intenta manejar la excepción elevándola una vez más en el bloque
adjunto. Este proceso continúa en cada bloque adjunto sucesivo hasta que no
queda ningún bloque en el que generar la excepción . Si no hay un controlador de
excepciones en todos los bloques, PL / SQL devuelve una excepción no controlada
al entorno de la aplicación que ejecutó el bloque PL / SQL más externo.

Tenga en cuenta que una excepción no controlada detiene la ejecución del bloque.

Ejemplos de propagación de excepciones no


controladas
Vea el siguiente bloque anónimo:

DECLARE
e1 EXCEPTION;
PRAGMA exception_init (e1, -20001);
e2 EXCEPTION;
PRAGMA exception_init (e2, -20002);
e3 EXCEPTION;
PRAGMA exception_init (e2, -20003);
l_input NUMBER := &input_number;
BEGIN
-- inner block
BEGIN
IF l_input = 1 THEN
raise_application_error(-20001,'Exception: the input number is 1');
ELSIF l_input = 2 THEN
raise_application_error(-20002,'Exception: the input number is 2');
ELSE
raise_application_error(-20003,'Exception: the input number is not 1 or 2');
END IF;
-- exception handling of the inner block
EXCEPTION
WHEN e1 THEN
dbms_output.put_line('Handle exception when the input number is 1');
END;
-- exception handling of the outer block
EXCEPTION
WHEN e2 THEN
dbms_output.put_line('Handle exception when the input number is 2');
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Primero, ejecute el bloque e ingrese 1 como el número de entrada.

Debido a que la entrada es 1, el bloque interno genera la excepción e1. La parte de


manejo de excepciones del bloque interno maneja la excepción e1 localmente, por
lo tanto, la ejecución del bloque se reanuda en el bloque adjunto.

Esta imagen ilustra el proceso:


En segundo lugar, ejecute el bloque e introduzca 2 como número de entrada.

El bloque interior genera la excepción e2. Debido a que el bloque interno no tiene
un manejador de excepciones para manejar la excepción e2, PL / SQL propaga la
excepción e2 al bloque adjunto.

El bloque adjunto tiene un manejador de excepciones que maneja la excepción


e2. Por lo tanto, el control pasa al entorno host (SQL * Plus o SQL Developer).

La siguiente imagen ilustra la propagación de la excepción no controlada desde el


bloque interno hasta su bloque circundante:
Tercero, ejecute el bloque e ingrese 3 como el número de entrada.

En este caso, tanto el bloque interno como el bloque adjunto no tienen un


manejador de excepciones para manejar la excepción e3. Por lo tanto, el bloque
devuelve una excepción no controlada al entorno del host.

La siguiente imagen ilustra la propagación de la excepción no controlada desde el


bloque interno al bloque circundante y luego al entorno host:
Manejo de otras excepciones no controladas

En esta sección de manejo de excepciones , puede incluir la WHEN OTHERScláusula


para detectar cualquier excepción que de otro modo no se manejaría:

EXCEPTION
...
WHEN OTHERS
-- catch other exceptions
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Debido a que maneja otras excepciones no específicas en la WHEN OTHERScláusula,


necesitará aprovechar las funciones de error integradas como SQLCODEy SQLERRM.
Tenga en cuenta que no puede utilizar SQLCODEo SQLERRMfuncionar directamente en
una sentencia SQL. En su lugar, primero debe asignar los valores devueltos a
las variables y luego usar las variables en la instrucción SQL.

SQLCODE función
La SQLCODE función no acepta argumentos y devuelve un código numérico de la
excepción más reciente.

Si las excepciones son internas, SQLCODEdevuelve un número negativo excepto


la NO_DATA_FOUND excepción que tiene el código numérico +100.

Si la excepción está definida por el usuario, SQLCODEdevuelve +1 o el número que


asoció con la excepción a través del pragma EXCEPTION_INIT.

El SQLCODEsólo es utilizable en la sección de control de excepciones. Si usa


la SQLCODEfunción fuera de un controlador de excepciones, siempre devuelve cero.

Este ejemplo ilustra cómo utilizar la SQLCODEf unción:

DECLARE
l_code NUMBER;
r_customer customers%rowtype;
BEGIN
SELECT * INTO r_customer FROM customers;

EXCEPTION
WHEN OTHERS THEN
l_code := SQLCODE;
dbms_output.put_line('Error code:' || l_code);
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, intentamos recuperar demasiadas filas en un registro, lo que da


como resultado un error con el siguiente código de error:

Error code:-1422
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

SQLERRM función
La función SQLERRMtoma un argumento como un número de error y devuelve el
mensaje de error asociado con ese número de error:

SQLERRM([error_number])
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En esta sintaxis, error_number puede ser cualquier número de error válido de Oracle.

Si omite el error_number argumento, la función devolverá el mensaje de error


asociado con el valor actual de SQLCODE.

Tenga en cuenta que la SQLERRM función sin argumento solo es útil en un


controlador de excepciones.

Este ejemplo ilustra cómo utilizar la función SQLERRM en un controlador de


excepciones:

DECLARE
l_msg VARCHAR2(255);
r_customer customers%rowtype;
BEGIN
SELECT * INTO r_customer FROM customers;

EXCEPTION
WHEN OTHERS THEN
l_msg := SQLERRM;
dbms_output.put_line(l_msg);
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Aquí está el resultado:

ORA-01422: exact fetch returns more than requested number of


rows
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Ejemplo de uso SQLCODE y SQLERRM funciones


El siguiente ejemplo inserta un nuevo contacto en la contacts tabla de la base de
datos de muestra. Tiene un manejador de excepciones en la WHERE OTHERS cláusula
de la sección de manejo de excepciones.
DECLARE
l_first_name contacts.first_name%TYPE := 'Flor';
l_last_name contacts.last_name%TYPE := 'Stone';
l_email contacts.email%TYPE := '[email protected]';
l_phone contacts.phone%TYPE := '+1 317 123 4105';
l_customer_id contacts.customer_id%TYPE := -1;
BEGIN
-- insert a new contact
INSERT INTO contacts(first_name, last_name, email, phone, customer_id)
VALUES(l_first_name, l_last_name, l_email, l_phone, l_customer_id);

EXCEPTION
WHEN OTHERS THEN
DECLARE
l_error PLS_INTEGER := SQLCODE;
l_msg VARCHAR2(255) := sqlerrm;
BEGIN
CASE l_error
WHEN -1 THEN
-- duplicate email
dbms_output.put_line('duplicate email found ' || l_email);
dbms_output.put_line(l_msg);

WHEN -2291 THEN


-- parent key not found
dbms_output.put_line('Invalid customer id ' || l_customer_id);
dbms_output.put_line(l_msg);
END CASE;
-- reraise the current exception
RAISE;
END;

END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo, el controlador de excepciones captura dos excepciones -1 (correo


electrónico duplicado) y -2291 (clave principal no encontrada). Muestra un mensaje
personalizado y vuelve a generar la excepción utilizando la RAISE declaración.
Sección 6. Registros
• Registro : aprenda a usar el tipo de registro para hacer que su código sea más
eficiente cambiando las operaciones de nivel de campo a nivel de registro.

Registro PL / SQL

Descripción general del registro PL / SQL


Un registro PL / SQL es una estructura de datos compuesta que consta de varios
campos; cada uno tiene su propio valor. La siguiente imagen muestra un registro
de ejemplo que incluye nombre, apellido, correo electrónico y número de teléfono:

El registro PL / SQL lo ayuda a simplificar su código al cambiar de operaciones a


nivel de campo a operaciones a nivel de registro.

PL / SQL tiene tres tipos de registros: basados en tablas, basados en cursor y


definidos por el programador. Antes de utilizar un registro, debe declararlo.

Declaración de registros
Usted define y declara registros en la sección de declaración de un bloque o
mediante la especificación del paquete.

Registro basado en tablas

Para declarar un registro basado en una tabla, utilice el %ROWTYPE atributo con un
nombre de tabla. Un registro basado en tabla tiene cada campo correspondiente a
una columna en una tabla.

DECLARE
record_name table_name%ROWTYPE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
El siguiente ejemplo declara un registro nombrado r_contact con la misma estructura
que la contactstabla en la base de datos de muestra :

DECLARE
r_contact contacts%ROWTYPE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Registro basado en cursor

Un registro basado en cursor tiene cada campo correspondiente a una columna o


alias en la instrucción del cursor SELECT .

Para declarar un registro basado en cursor, utilice el %ROWTYPE atributo con un


cursor explícito como se muestra a continuación:

DECLARE
record_name cursor_name%ROWTYPE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El siguiente ejemplo declara un registro con la misma estructura que un cursor


explícito:

DECLARE
CURSOR c_contacts IS
SELECT first_name, last_name, phone
FROM contacts;
r_contact c_contacts%ROWTYPE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este ejemplo:

• En primer lugar, declarar un cursor explícito que obtiene datos de


los first_name, last_namey phonecolumnas de la contactstabla.
• En segundo lugar, declare un registro con nombre r_contactcuya estructura sea la
misma que la del c_contactscursor.

Registro definido por el programador

Los registros basados en tablas y en cursores son lo suficientemente buenos


cuando necesita crear registros basados en estructuras existentes.

Si desea crear un registro cuya estructura no se base en los existentes, utilice el


registro definido por el programador.
Para declarar un registro definido por el programador, utilice los siguientes pasos:

1. Defina un tipo de registro que contenga la estructura que desea en su registro.


2. Declare un registro según el tipo de registro.

A continuación, se muestra la sintaxis para definir un tipo de registro:

TYPE record_type IS RECORD (


field_name1 data_type1 [[NOT NULL] := | DEFAULT
default_value],
field_name2 data_type2 [[NOT NULL] := | DEFAULT
default_value],
...
);
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Para declarar un registro basado en el tipo de registro predefinido, utilice la


siguiente sintaxis:

record_name record_type;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El siguiente ejemplo define un tipo de registro cuyo nombre es customer_contactsy un


registro cuyo tipo es customer_contacts:

DECLARE
-- define a record type
TYPE r_customer_contact_t
IS
RECORD
(
customer_name customers.name%TYPE,
first_name contacts.first_name%TYPE,
last_name contacts.last_name%TYPE );
-- declare a record
r_customer_contacts r_customer_contact_t;
BEGIN
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Hacer referencia al campo de un registro
Hace referencia a un campo en un registro a través de la notación de puntos como
se muestra a continuación:

record_name.field_name
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Por ejemplo, para hacer referencia al first_namecampo del r_contactregistro, usa la


siguiente expresión:

r_contact.first_name
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Asignar registros
Puede asignar un registro a otro registro del mismo tipo, por ejemplo:

r_contact1 := r_contact2;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Pero no puede comparar dos registros del mismo tipo mediante un operador de
comparación. El siguiente ejemplo es una comparación no válida:

IF r_contact1 = r_contact2 THEN


...
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

En este caso, debe comparar campos individuales del registro en su lugar:

IF r.contact1.first_name = r.contact2.first_name AND


r.contact1.last_name = r.contact2.last_name AND
r.contact1.phone = r.contact2.phone THEN
...
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Puede asignar un valor al campo individual de un registro, por ejemplo:

r_contact.first_name := 'John';
r_contact.last_name := 'Doe';
r_contact.phone := '(408-654-2865)';
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Puede utilizar SELECT INTO un registro completo (o campos individuales):

SELECT
first_name, last_name, phone
INTO
r_contact
FROM
contacts
WHERE
contact_id = 100;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Puede FETCH INTO un registro completo o campos individuales:

-- fetch a whole record


FETCH cur_contacts INTO r_contact;

-- fetch individual fields


FETCH
cur_contacts
INTO
r_contact.first_name,
r_contact.last_name,
r_contact.phone;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Registros y INSERT/ UPDATE declaraciones


Puede insertar una nueva fila en una tabla utilizando un %ROWTYPEregistro sin tener
que especificar cada campo. La siguiente declaración crea una nueva tabla con
el nombre persons de demostración:

CREATE TABLE persons (


person_id NUMBER ,
first_name VARCHAR2( 50 ) NOT NULL,
last_name VARCHAR2( 50 ) NOT NULL,
primary key (person_id)
);
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

El siguiente bloque inserta una nueva fila en la persons tabla usando un %ROWTYPE
registro:
DECLARE
r_person persons%ROWTYPE;

BEGIN
-- assign values to person record
r_person.person_id := 1;
r_person.first_name := 'John';
r_person.last_name := 'Doe';

-- insert a new person


INSERT INTO persons VALUES r_person;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Para actualizar una fila de un %ROWTYPE registro, utilice las SET ROW palabras clave
como se muestra en el siguiente ejemplo:

DECLARE
r_person persons%ROWTYPE;

BEGIN
-- get person data of person id 1
SELECT * INTO r_person
FROM persons
WHERE person_id = 1;

-- change the person's last name


r_person.last_name := 'Smith';

-- update the person


UPDATE persons
SET ROW = r_person
WHERE person_id = r_person.person_id;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )

Registro anidado
Un registro puede contener un campo que es otro registro. Anidar registros es una
forma poderosa de estructurar los datos de su programa y ocultar la complejidad
en su código.
El siguiente ejemplo declara un tipo de registro llamado address. Luego, en el tipo
de registro customertiene dos campos ship_to y bill_to que se basan en el tipo de
registro de dirección.

DECLARE
TYPE address IS RECORD (
street_name VARCHAR2(255),
city VARCHAR2(100),
state VARCHAR2(100),
postal_code VARCHAR(10),
country VARCHAR2(100)
);
TYPE customer IS RECORD(
customer_name VARCHAR2(100),
ship_to address,
bill_to address
);
r_one_time_customer customer;
BEGIN

r_one_time_customer.customer_name := 'John Doe';


-- assign address
r_one_time_customer.ship_to.street_name := '4000 North 1st street';
r_one_time_customer.ship_to.city := 'San Jose';
r_one_time_customer.ship_to.state := 'CA';
r_one_time_customer.ship_to.postal_code := '95134';
r_one_time_customer.ship_to.country := 'USA';
-- bill-to address is same as ship-to address
r_one_time_customer.bill_to := one_time_customer.ship_to;
END;

También podría gustarte