Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Estructura
Ejemplo
REM Inicializar el parámetro de SQL*Plus por substitución P_SAL
ACCEPT p_sal PROMPT ‘Ingresar el salario mensual:’
DECLARE
v_sal NUMBER(9,2) := &p_sal: -- Inicializar con valor ingresado
BEGIN
/* Calculo del salario anual */
:g_year_sal := v_sal * 12;
END;
/
REM Imprimir el salario anual en la pantalla
PRINT g_year_sal
Declaración de variables
Sintaxis
Identificador [CONSTANT] tipo_de_dato [NOT NULL][:= | DEFAULT expresion_plsql]
Notas
• EL nombre de los identificadores están de acuerdo a las mismas reglas de los objetos de
SQL*Plus
• Se puede restringir las variables para que no puedan contener nulos mediante la palabra
NOT NULL. Las variables de este tipo deben ser inicializadas.
• Inicializar una variable con una expresión PL/SQL con el operador de asignación := o con
la palabra reservada DEFAULT; de lo contrario las variables son inicializadas con NULL.
Tipos de datos
TIPO DESCRIPCION
BINARY_INTEGER Tipo base para enteros entre -2E31 a 2E31 -1
POSITIVE Subtipo para enteros mayores que cero
NATURAL Subtipo para enteros mayores o iguales a 0
V_INGRESO NUMBER(9,2)
V_NAME VARCHAR2(25);
V_GENERO CHAR(1);
DECLARE
v_balance NUMBER(7,2);
v_minimun_balance v_balance%TYPE := 10;
DECLARE
v_apellido S_EMP.LAST_NAME%TYPE;
v_nombre S_EMP.NAME%TYPE;
Etiquetar bloques
Se deben etiquetar los bloques externos para evitar reglas de ámbito donde las
variables declaradas en el no sean visibles.
Sintaxis
<<nombre_etiqueta>>
[DECLARE]
BEGIN
…
END nombre_etiqueta;
Ejemplo de bloques etiquetados
<<bloque_externo>>
DECLARE
v_n NUMBER;
BEGIN
v_n := 5;
/* Aquí empieza el sub-bloque */
DECLARE
v_x NUMBER := 10;
v_n VARCHAR2(10) := ‘FIFTEEN’;
BEGIN
INSERT INTO temp(col1,col2,message)
VALUES (bloque_externo.v_n,v_x,v_n);
COMMIT;
END; /* Fin de sub-bloque */
END bloque_externo;
Ejercicio
DECLARE
v_weight VARCHAR2(3) := ‘600’;
v_message VARCHAR2(255);
BEGIN
DECLARE
v_weight NUMBER(3) := 1;
v_message VARCHAR2(255);
v_new_locn VARCHAR2(50) := ‘Europe’;
BEGIN
v_weight := v_weight + 1; 7.
v_message := v_weight || ‘is overweight’; 8.
v_new_locn := ‘Western ‘|| v_new_locn; 9.
END;
v_weight := v_weight + 1; 10.
v_message := v_weight || ‘is overweight’; 11.
v_new_locn := ‘Western ‘|| v_new_locn; 12.
END;
DECLARE
v_credit_rating s_customer.credit_rating%TYPE
BEGIN
SELECT s_customer.credit_rating INTO v_credit_rating
FROM s_customer.s_ord
WHERE s_customer.id = s_ord.customer_id
AND s_ord.id = &p_ord_id;
IF (v_credit_rating = ‘GOOD’ OR v_credit_rating = ‘EXCELLENT’)
THEN
UPDATE s_ord SET payment_type = ‘CREDIT’
WHERE id = &p_ord_id;
ELSIF (v_credit_rating = ‘POOR’)
THEN
UPDATE s_ord SET payment_type = ‘POOR’
WHERE id = &p_ord_id;
ELSE
UPDATE s_ord SET payment_type = ‘POOR’
WHERE id = &p_ord_id;
END IF;
COMMIT WORK;
END;
Construyendo condiciones lógicas
Se pueden construir condiciones lógicas combinando números, caracteres,
expresiones con fechas con operadores de comparación. Los valores NULL se
operan con el operador IS NULL.
<<nombre_etiqueta>>
LOOP
instrucción1;
instrucción2;
...
END LOOP nombre_etiqueta;
Ejemplo LOOP anidados
<<outer_loop>>
WHILE a > b LOOP
b := b + 1;
<<inner_loop>>
WHILE b > 1 LOOP
c := c + 2;
EXIT outer_loop WHEN c > 200
END LOOP inner_loop;
END LOOP outer_loop;
Procesando múltiples filas
Pasos para declarar y manipular un cursor
1. Declarar el cursor
2. Abrir el cursor (OPEN)
3. Acceder los datos del cursor (FETCH)
4. Cerrar el cursos (CLOSE)
Declaración
DECLARE
CURSOR nombre_cursor IS
instrucción_SELECT
Ejemplo
DECLARE
v_ord_id s_item.ord_id%TYPE;
v_product_id s_item.product_id%TYPE;
v_item_total NUMBER(11,2)
CURSOR item_cursor IS
SELECT product_id,price*quantity
FROM s_item
WHERE ord_id = v_ord_id;
BEGIN
...
END;
Nota:
• No incluir la clausula INTO en la declaración del cursor ya que aparece después
dentro de la instrucción FETCH.
• Si la instrucción SELECT hace referencia a cualquier variable, se debe asegurar
que ésta variable esté declarada anteriormente en la declaración del cursor.
Procesando múltiples filas
Abrir Cursor:
Abrir el cursor antes de especificar las variables de ingreso de
datos.
Sintaxis:
DECLARE
v_ord_id s_item.ord_id%TYPE;
v_product_id s_item.product_id%TYPE;
v_item_total NUMBER(11,2)
CURSOR item_cursor IS
SELECT product_id,price*quantity
FROM s_item
WHERE ord_id = v_ord_id;
BEGIN
v_ord_id := &p_ord_id;
OPEN item_cursor;
END;
Procesando múltiples filas
Abrir Cursor:
Para acceder los datos del cursor, se pueden almacenar en
variables locales.
Sintaxis:
Ejemplo:
Nota:
Sintaxis:
CLOSE nombre_cursor;
Ejemplo:
CLOSE item_cursor;
Nota:
ATRIBUTO DESCRIPCIÓN
Nota:
• No se puede hacer referencia a atributos de cursor directamente dentro de una
instrucción SQL.
Procesando múltiples filas
Recuperando filas en un LOOP:
Solo se pueden recuperar filas (FETCH) cuando el cursor está abierto.
Determinar si un cursor esta abierto usando el atributo %ISOPEN, si es necesario.
Ejemplo:
Recuperar el item actual; si el cursor no esta disponible, abrir el cursor.
IF item_cursor%ISOPEN
THEN
FETCH item_cursor into v_quantity, v_price
ELSE
OPEN item_cursor;
END IF;
Procesando múltiples filas
Recuperando filas en un LOOP:
Recuperar las filas en un LOOP simple y determinar cuando salir del LOOP
usando el atributo %NOTFOUND.
Ejemplo
Recuperar los items para una orden uno por uno hasta que no hayan más.
Almacenar el total acumulativo para cada producto en una tabla separada.
DECLARE
v_ord_id s_item.ord_id%TYPE;
v_product_id s_item.product_id%TYPE;
v_item_total NUMBER(11,2)
CURSOR item_cursor IS
SELECT product_id,price*quantity
FROM s_item
WHERE ord_id = v_ord_id;
BEGIN
OPEN item_cursor;
LOOP
FETCH item_cursor INTO v_product_id,v_item_total;
EXIT WHEN item_cursor%NOTFOUND;
v_order_total := v_order_total + v_item_total;
INSERT INTO temp(product_id,cummulative_total) VALUES (v_product_id,v_order_total)
END LOOP;
CLOSE item_cursor;
COMMIT WORK;
END;
Procesando múltiples filas
Recuperando filas en un LOOP:
Equivalentemente, recuperar las filas en un LOOP WHILE, y determinar
cuando salir del LOOP usando el atributo %FOUND.
Ejemplo
Recuperar los ítems para una orden uno por uno hasta que no hayan más.
Almacenar el total acumulativo para cada producto en una tabla separada.
DECLARE
v_ord_id s_item.ord_id%TYPE;
v_product_id s_item.product_id%TYPE;
v_item_total NUMBER(11,2)
CURSOR item_cursor IS
SELECT product_id,price*quantity
FROM s_item
WHERE ord_id = v_ord_id;
BEGIN
OPEN item_cursor;
FETCH item_cursor INTO v_product_id, v_item_total;
WHILE item_cursor%FOUND LOOP
v_order_total := v_order_total + v_item_total;
INSERT INTO temp(product_id,cummulative_total) VALUES (v_product_id,v_order_total);
FETCH item_cursor INTO v_product_id, v_item_total
END LOOP;
CLOSE item_cursor;
COMMIT WORK;
END;
Procesando múltiples filas
Recuperando filas en un LOOP:
Para recuperar un número exacto de filas, recuperar las filas en un loop FOR
numérico, o recuperar en un loop simple, y determinar cuando salir del loop usando el
atributo %ROWCOUNT.
Ejemplo
Recuperar los ítems para una orden uno por uno hasta que no hayan más. Almacenar el
total acumulativo para cada producto en una tabla separada.
DECLARE
v_ord_id s_item.ord_id%TYPE;
v_product_id s_item.product_id%TYPE;
v_item_total NUMBER(11,2)
CURSOR item_cursor IS
SELECT product_id,price*quantity
FROM s_item
WHERE ord_id = v_ord_id;
BEGIN
OPEN item_cursor;
LOOP
FETCH item_cursor INTO v_product_id, v_item_total;
v_order_total := v_order_total + v_item_total;
INSERT INTO temp(product_id,cummulative_total) VALUES (v_product_id,v_order_total);
EXIT WHEN item_cursor%ROWCOUNT <= 100;
END LOOP;
CLOSE item_cursor;
COMMIT WORK;
END;
Procesando múltiples filas
Recuperando filas en un LOOP:
El loop FOR itera cada vez que una fila es retornada por el query.
Sintaxis
FOR nombre_registro IN nombre_cursor LOOP
Instrucción1;
Instrucción2;
END LOOP;
Nota
DECLARE
v_ord_id s_item.ord_id%TYPE;
v_product_id s_item.product_id%TYPE;
v_item_total NUMBER(11,2)
CURSOR item_cursor IS
SELECT product_id,price*quantity
FROM s_item
WHERE ord_id = v_ord_id;
BEGIN
FOR item_record IN item_cursor LOOP
v_order_total := v_order_total + v_item_total;
INSERT INTO temp(product_id,cummulative_total) VALUES (v_product_id,v_order_total);
END LOOP;
COMMIT WORK;
END;