PLSQL Diplomado
PLSQL Diplomado
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.
Arquitectura PL / SQL
La siguiente imagen ilustra la arquitectura PL / SQL:
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.
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.
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.
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 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.
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 )
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 )
¡Hola Mundo!
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 )
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
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.
• Número
• Booleano
• Personaje
• Fecha y hora
Tenga en cuenta que los tipos de datos escalares PL / SQL incluyen tipos de datos
SQL y su propio tipo de datos, como booleano.
Los tipos de datos NUMBER, BINARY_FLOAT y BINARY_DOUBLE son tipos de datos SQL.
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.
SIGNTYPE Representa tres valores -1, 0 o 1, que son útiles para la programación
lógica de tres estados.
Tenga en cuenta que los tipos de datos PLS_INTEGER y BINARY_INTEGER son idénticos.
NÚMERO DEC, DECIMAL, DOBLE PRECISIÓN, FLOAT, INTEGER, INT, NUMERIC, REAL, SMALLINT
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:
En esta sintaxis:
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_.
DECLARE
l_total_sales NUMBER(15,2);
l_credit_limit NUMBER (10,0);
l_contact_name VARCHAR2(255);
BEGIN
NULL;
END;
DECLARE
l_product_name VARCHAR2( 100 ) := 'Laptop';
BEGIN
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
DECLARE
l_product_name VARCHAR2(100) DEFAULT 'Laptop';
BEGIN
NULL;
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
DECLARE
l_shipping_status VARCHAR2( 25 ) NOT NULL := 'Shipped';
BEGIN
l_shipping_status := '';
END;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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 )
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;
En este ejemplo:
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;
Comentarios PL / 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:
Tenga en cuenta que agregamos el punto y coma ( ;) antes del ( --) para que la
declaración sea válida.
/*
This is a multi-line comment
that can span multiple lines
*/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
/*
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 )
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 )
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 )
BEGIN
/*
a multi-line comment
/*
a nested multi-line comment
*/
*/ -- -> error
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Constantes PL / SQL
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.
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:
En esta sintaxis:
nombre_constante
tipo de datos
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.
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 )
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.
- IF THEN
- IF THEN ELSE
-IF THEN ELSIF
IF condition THEN
statements;
END IF;
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.
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 )
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 )
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.
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 simple
Una CASE declaración simple evalúa una sola expresión y compara el resultado con
algunos valores.
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.
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 )
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.
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:
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;
n_commission := 0.15;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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.
Una CASE expresión evalúa una lista de condiciones y devuelve una de las múltiples
expresiones de resultado posibles.
GOTO label_name;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
<<label_name>>;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
<<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:
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 )
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 )
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.
NULL;
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:
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.
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 )
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 )
BUCLE PL / SQL
<<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 puede tener una etiqueta opcional que aparece al principio y al
final de la declaración.
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 )
Inside loop: 1
Inside loop: 2
Inside loop: 3
After loop: 4
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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.
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;
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 )
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
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.
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 )
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
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.
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 )
1
2
3
4
5
10
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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
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 )
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 )
1
2
3
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.
Para terminar el ciclo prematuramente, usa una instrucción EXITo EXIT WHEN.
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 )
Counter : 1
Counter : 2
Counter : 3
Counter : 4
Counter : 5
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
En este ejemplo:
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 )
PL / SQL CONTINUE
CONTINUE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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 )
IF condition THEN
CONTINUE;
END IF;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( 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 )
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 )
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 )
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 )
En este ejemplo:
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 )
En este ejemplo:
Excepción PL / SQL
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.
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:
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;
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;
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 )
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;
• 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.
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 )
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;
En este ejemplo,
ORA-20001:
RAISE e_credit_too_high;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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 )
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;
COMMIT;
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
En este ejemplo:
Al utilizar este procedimiento, puede informar errores a las personas que llaman en
lugar de devolver excepciones no controladas .
raise_application_error(
error_number,
message
[, {TRUE | FALSE}]
);
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
En esta sintaxis:
DECLARE
credit_limit_exceed EXCEPTION;
PRAGMA exception_init(credit_limit_exceed, -20111);
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;
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:
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.
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 )
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.
EXCEPTION
...
WHEN OTHERS
-- catch other exceptions
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( 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.
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 )
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.
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 )
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);
END;
/
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
Registro PL / SQL
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.
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
DECLARE
record_name cursor_name%ROWTYPE;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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:
record_name record_type;
Lenguaje de código: SQL (lenguaje de consulta estructurado) ( sql )
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 )
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:
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 )
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';
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;
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