0% encontró este documento útil (0 votos)
92 vistas30 páginas

Procedimientos Almacenados Oracle SQL

Este documento resume los principales conceptos sobre procedimientos almacenados y funciones en PL/SQL. Explica la diferencia entre bloques anónimos y subprogramas, y cómo se crean y ejecutan procedimientos almacenados y funciones. También cubre el uso de variables compuestas como registros y colecciones, y cursores, incluyendo cursores explícitos e implícitos y el uso de parámetros en cursores.

Cargado por

Sar Q
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)
92 vistas30 páginas

Procedimientos Almacenados Oracle SQL

Este documento resume los principales conceptos sobre procedimientos almacenados y funciones en PL/SQL. Explica la diferencia entre bloques anónimos y subprogramas, y cómo se crean y ejecutan procedimientos almacenados y funciones. También cubre el uso de variables compuestas como registros y colecciones, y cursores, incluyendo cursores explícitos e implícitos y el uso de parámetros en cursores.

Cargado por

Sar Q
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/ 30

Bases de Datos II

Procedimientos Almacenados

Alberto Shum Chan


[email protected]

Material basado en el curso de Bases de Datos II. María Mora


PL/SQL – Procedure Language extensión for SQL
--sentencia SQL
SELECT ciudad_cliente
FROM cliente
WHERE nombre_cliente = 'Santos';

--bloque de código anónimo


DECLARE
v_ciudad VARCHAR2(20);
BEGIN
SELECT ciudad_cliente INTO v_ciudad
FROM cliente
WHERE nombre_cliente = 'Santos';
END;
Procedimientos Almacenados – Bloques de código
Anónimo Procedimiento Función
[DECLARE] PRODURE nombre FUNCTION nombre
[declaraciones] IS RETURN <tipoDato>
BEGIN [declaraciones] IS
--sentencias BEGIN [declaraciones]
[EXCEPTION] --sentencias BEGIN
--sentencias [EXCEPTION] --sentencias
END; --sentencias [EXCEPTION]
END; --sentencias
END;

Subprogramas
Bloques anónimos vs Subprogramas
Bloque anónimo Subprogramas
Bloques de código sin nombre Bloques de código con nombre
Se compilan cada vez que se ejecutan Se compilan solo una vez
No se almacenan en la base de datos Se almacenan en la base de datos
No pueden ser invocados por otras aplicaciones Al tener nombre pueden ser invocados por otras
aplicaciones
No devuelven valores Las funciones devuelven valores
No pueden recibir parámetros Pueden recibir parámetros
Bloque Anónimo
SET serveroutput ON;

DECLARE
v_ciudad VARCHAR2(20) := '';
BEGIN
SELECT ciudad_cliente INTO v_ciudad
FROM cliente
WHERE nombre_cliente = 'Santos';

dbms_output.put_line (v_ciudad);

INSERT INTO cliente


VALUES ('Alberto', 'La Puebla', v_ciudad);
END;
/
Procedimientos Almacenados (Stored Procedures)

• Encapsular lógica de negocio.


• Mantenibilidad
• Seguridad
• Eficiencia
Procedimientos - Creación
--sintáxis
CREATE OR REPLACE PROCEDURE <nombre_procedimiento>
[(argumento1 [modo] <tipo_de_dato>,
argumento2 [modo] <tipo_de_dato>,
...)]
IS | AS
<cuerpo_procedimiento> --bloque PL/SQL

CREATE OR REPLACE PROCEDURE agregar_sucursal (v_nombre IN VARCHAR2,


v_ciudad IN VARCHAR2,
v_activos IN NUMBER)
IS
BEGIN
INSERT INTO sucursal
VALUES (v_nombre, v_ciudad, v_activos);
DBMS_OUTPUT.put_line ('Se ha insertado la sucursal: ' || v_nombre);
END;
/
Procedimientos - Ejecución
--ejecución
EXEC agregar_sucursal ('Aquel Lugar', 'Cartago' , 100);

--ejecución desde un bloque anónimo


BEGIN
agregar_sucursal ('Aquel Lugar', 'Cartago' , 100);
END;
Procedimientos - Ejecución
CREATE OR REPLACE PROCEDURE cuentas_mayores_sp (v_cuenta VARCHAR2, c1 IN OUT SYS_REFCURSOR)
IS
BEGIN
OPEN c1 FOR
SELECT *
FROM cuenta
WHERE saldo > (SELECT saldo FROM cuenta WHERE numero_cuenta = v_cuenta);
END;
/

--step 1 --step 1
VAR c1 REFCURSOR;
EXEC cuentas_mayores_sp('C-102', :c1); VAR c3 REFCURSOR;
BEGIN
--step 2 cuentas_mayores_sp('C-102', :c3);
PRINT c1; END;
/

--step 2
PRINT c3;
Función - Creación
--sintáxis
CREATE OR REPLACE FUNCTION <nombre_funcion>
[(argumento1 [modo] <tipo_de_dato>,
argumento2 [modo] <tipo_de_dato>,
...)]
RETURN <tipo_de_dato>
IS | AS
<cuerpo_funcion> --bloque PL/SQL*

--*Debe incluir RETURN


Función - Creación
CREATE OR REPLACE FUNCTION valida_cuenta (v_cuenta VARCHAR2)
RETURN BOOLEAN IS
v_saldo NUMBER;
v_promedio NUMBER;
BEGIN
SELECT saldo INTO v_saldo
FROM cuenta
WHERE numero_cuenta = v_cuenta;

SELECT AVG (saldo) INTO v_promedio


FROM cuenta;

IF v_saldo < v_promedio THEN


RETURN FALSE;
ELSE
RETURN TRUE;
END IF;
END;
/
Función - Ejecución
--ejecución / retorna TRUE/FALSE
SET SERVEROUTPUT ON;

BEGIN
IF valida_cuenta ('C-333') THEN
DBMS_OUTPUT.put_line ('Cuenta válida');
ELSE
DBMS_OUTPUT.put_line ('Cuenta por debajo del promedio!!');
END IF;
END;
/

--ejemplo la función SYSDATE / retorna un valor


SELECT SYSDATE FROM dual;
• Variables compuestas
• Colecciones
• Registros

• Cursores
Abstracción de datos
• %ROWTYPE. Tipo de registro asociado a alguna
relación en la base de datos.
• Tipos de datos abstractos (ADT). Consisten de una
estructura (atributos) y programas que manipulan los
datos. Pueden ser almacenados en tablas y son la base
de la orientación a objetos en el modelo relacional.
Variables
compuestas:
colecciones
Ejemplo %ROWTYPE
DESC employees;
DECLARE
regEmp employees%ROWTYPE;
v_income employees.salary%TYPE;

BEGIN
regEmp.first_name := 'Alberto';
DBMS_OUTPUT.Put_Line(regEmp.first_name);
v_income := 9500;
DBMS_OUTPUT.Put_Line(v_income);
END;
Cursores
--sintáxis Cursor Explicito
• Puntero a un área privada de memoria. CURSOR <nombre_cursor> IS
<sentencia_SELECT>;
• Utilizada para manipular el resultado de
un SELECT. --ejemplo
DECLARE
• Pueden ser implícitos o explícitos. CURSOR cur_cuentas IS
SELECT nombre_sucursal, saldo
FROM cuenta;
Cursores - Ejemplo
--ejemplo
DECLARE
v_nombre_sucursal VARCHAR2(30);
v_saldo NUMBER(10);
CURSOR cur_cuentas IS
SELECT nombre_sucursal, saldo
Cursor FROM cuenta;
BEGIN
OPEN cur_cuentas; --apertura

FETCH cur_cuentas --recuperar datos


INTO v_nombre_sucursal, v_saldo ;

dbms_output.put_line ('Sucursal: ' ||


v_nombre_sucursal ||
' / Saldo: ' ||
v_saldo);
CLOSE cur_cuentas; --cierre
END;
Cursores - Explícito
DECLARE
v_nombre_sucursal VARCHAR2(30);
v_saldo NUMBER(10);
CURSOR cur_cuentas IS
SELECT nombre_sucursal, saldo
FROM cuenta;
BEGIN
OPEN cur_cuentas;
LOOP --ciclo
FETCH cur_cuentas
INTO v_nombre_sucursal, v_saldo ;

EXIT WHEN cur_cuentas%NOTFOUND; --sale cuando no encuentra mas datos

dbms_output.put_line ('Sucursal: ' || v_nombre_sucursal ||


' / Saldo: ' || v_saldo);
END LOOP;
CLOSE cur_cuentas;
END;
Cursores - Explícito
DECLARE
CURSOR cur_cuentas IS
SELECT nombre_sucursal, saldo
FROM cuenta;
BEGIN
--variable reg declarada implicitamente
--en lugar del cursor puede ir un (<SELECT>)
FOR reg IN cur_cuentas LOOP --ciclo
DBMS_OUTPUT.PUT_LINE ('Sucursal: ' || reg.nombre_sucursal ||
' / Saldo: ' || reg.saldo);
END LOOP;
END;
Cursores - Implícito
BEGIN
FOR item IN (
SELECT last_name, job_id
FROM employees
WHERE job_id LIKE '%CLERK%'
AND manager_id > 120
ORDER BY last_name
) LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || item. last_name ||
', Job = ' || item.job_id);
END LOOP;
END;
Cursores – Parámetros
--cursor con parametro
DECLARE
CURSOR c_emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
...
BEGIN
OPEN c_emp_cursor (10);
...
CLOSE c_emp_cursor;
OPEN c_emp_cursor (20);
END;
Cursores – Parámetros
DECLARE
CURSOR c1 (job VARCHAR2, max_wage NUMBER) IS
SELECT * FROM employees
WHERE job_id = job
AND salary > max_wage;
BEGIN
FOR person IN c1 ('ST_CLERK', 3000) LOOP
--process data record
dbms_output.put_line (
'Name = ' || person.last_name || ', salary = ' ||
person.salary || ', Job Id = ' || person.job_id);
END LOOP;
END;
Cursores – Pseudocolumna
BEGIN
FOR item IN (
SELECT first_name || ' ' || last_name AS full_name,
salary * 10 AS dream_salary
FROM employees
WHERE ROWNUM <= 5
ORDER BY dream_salary DESC, last_name ASC ) LOOP
DBMS_OUTPUT.Put_Line( item.full_name || ' dreams of making ' ||
item.dream_salary );
END LOOP;
END;
/
Ejemplo: Listar los empleados con mayores salarios
DECLARE BEGIN
TYPE EmpRecTyp IS RECORD highest_paid_emp := nth_highest_salary(1);
(emp_id employees.employee_id%TYPE, next_highest_paid_emp := nth_highest_salary(2);
salary employees.salary%TYPE
);
DBMS_OUTPUT.Put_Line( 'Highest Paid: #' ||
CURSOR desc_salary RETURN EmpRecTyp IS highest_paid_emp.emp_id || ', $' ||
SELECT employee_id, salary highest_paid_emp.salary);
FROM employees DBMS_OUTPUT.Put_Line( 'Next Highest Paid: #' ||
ORDER BY salary DESC; next_highest_paid_emp.emp_id || ', $' ||
next_highest_paid_emp.salary);
highest_paid_emp EmpRecTyp;
next_highest_paid_emp EmpRecTyp; END;

FUNCTION nth_highest_salary (n INTEGER)


RETURN EmpRecTyp IS -- Resultado
emp_rec EmpRecTyp; Highest Paid: #100, $24000
BEGIN Next Highest Paid: #101, $17000
OPEN desc_salary;
FOR i IN 1..n LOOP
FETCH desc_salary INTO emp_rec;
END LOOP;
CLOSE desc_salary;
RETURN emp_rec;
END nth_highest_salary;
Ejemplo
Normalización utilizando procedimientos almacenados:
Se reciben los siguientes datos de usuario en un hoja electrónica.
Ejemplo Los datos deben guardarse utilizando las siguientes tablas
Manejo de Excepciones
--Insert una sucursal con el mismo nombre
EXEC agregar_sucursal('Galapagar', 'Heredia', 7100);

CREATE OR REPLACE PROCEDURE agregar_sucursal (v_nombre IN VARCHAR2,


v_ciudad IN VARCHAR2,
v_activos IN NUMBER) IS
BEGIN
INSERT INTO sucursal VALUES (v_nombre, v_ciudad, v_activos);

DBMS_OUTPUT.put_line ('Se ha insertado la sucursal: ' || v_nombre);


EXCEPTION WHEN OTHERS THEN
IF SQLCODE=-1 THEN
DBMS_OUTPUT.put_line ('Ya existe una sucursal con el nombre: ' || v_nombre);
ELSE
DBMS_OUTPUT.put_line (SQLERRM);
END IF;
END;
/
Manejo de Excepciones

Algunas Excepciones Predefinidas Funciones


Nombre excepción Código de error • Deben ser usadas solamente dentro de
la sección de manejo de excepciones.
NO_DATA_FOUND +100
ZERO_DIVIDE -1476 ➢ SQLERRM: mensaje de error.
unique constraint violated
TOO_MANY_ROWS -1422
VALUE_ERROR -6502 ➢ SQLCODE: código del error.
ORA-00001
Bibliografía
 Silbershatz Abraham, Korth Henry F. , Sudarshan S. (2006). Fundamentos de
bases de datos. Quinta edición, McGraw Hill.

 Oracle 12c (2017). Database PL/SQL Language Reference. Recuperado de


https://docs.oracle.com/database/121/LNPLS/toc.htm

También podría gustarte