Este documento contiene ejemplos de código SQL y PL/SQL para trabajar con triggers, procedimientos, funciones y cursores. Incluye scripts para crear tablas, insertar datos, y ejemplos de cómo crear un trigger de bitácora, procedimientos para modificar salarios, una función para obtener un salario, y uso de cursores.
1. Ejercicios de PL SQL
• Los siguientes ejercicios han sido
desarrollados basados en el esquema HR
• Si no lo tiene… ejecute los scripts que se le
proporcionaron.
2. TRIGGER(ORACLE)
• Bitácora de inserción, eliminación y actualización.
CREAR TABLAS PARA TRABAJAR TRIGGERS Y OTROS PROCESOS
CREATE TABLE EMP
(EMPNO NUMBER(3,0),
NOMBRE VARCHAR2(40),
TRABAJO VARCHAR2(20),
DEPNO NUMBER(3,0),
SALARIO NUMBER(8,2)
) ;
create table bitacora (accion char(20) NULL,empno
number(3,0) NULL);
3. TRIGGER(SQL)
• Bitácora de inserción, eliminación y actualización.
CREAR TABLAS PARA TRABAJAR TRIGGERS Y OTROS PROCESOS
CREATE TABLE EMP
(EMPNO NUMERIC(3,0),
NOMBRE VARCHAR(40),
TRABAJO VARCHAR(20),
DEPNO NUMERIC(3,0),
SALARIO NUMERIC(8,2)
) ;
create table bitacora (accion char(20) NULL,empno
numeric(3,0) NULL);
4. Trigger para hacer bitácora(ORACLE)
create or replace TRIGGER TR_EMP
BEFORE INSERT OR DELETE OR UPDATE ON EMP
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
BEGIN
IF INSERTING THEN INSERT INTO bitacora VALUES
('INSERTO',:NEW.EMPNO); END IF;
IF DELETING THEN INSERT INTO bitacora VALUES
('ELIMINO',:OLD.EMPNO); END IF;
IF UPDATING THEN INSERT INTO bitacora VALUES
('MODIFICO',:OLD.EMPNO); END IF;
END;
/
5. Trigger para hacer bitácora (sql)
Create TRIGGER TR_EMP
ON EMP
AFTER INSERT,DELETE,UPDATE
AS
DECLARE @nempleado int
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM INSERTED)
begin
select @nempleado=empno from inserted
IF EXISTS(SELECT * FROM DELETED)
INSERT INTO bitacora VALUES ('MODIFICO',@nempleado)
ELSE
INSERT INTO bitacora VALUES ('ADICIONO',@nempleado)
end
ELSE IF EXISTS(SELECT * FROM DELETED)
begin
select @nempleado=empno from deleted
INSERT INTO bitacora VALUES ('ELIMINO', @nempleado)
end
END
6. Estructura de un bloque PL/SQL
en esquema HR(programa 1)
imprimir un valor cualquiera
set serveroutput on;
DECLARE
v_nombre employees.employee_id %
TYPE;
begin
v_nombre:=1;
dbms_output.put_line(v_nombre);
end;
7. Estructura de un bloque PL/SQL
en esquema HR(programa 2)
Salario mayor
DECLARE
v_mayor employees.salary % TYPE;
begin
v_mayor:=0;
select max(salary) into v_mayor
from employees;
dbms_output.put_line(v_mayor);
end;
8. Estructura de un bloque PL/SQL
en esquema HR(programa 3)
Salario mayor, menor … n variables
DECLARE
v_mayor employees.salary % TYPE;
v_menor employees.salary % TYPE;
begin
v_mayor:=0;
v_menor:=0;
select max(salary),min(salary) into v_mayor,v_menor
from employees ;
dbms_output.put_line('salario mayor es '|| to_char (v_mayor));
dbms_output.put_line('salario menor es '||to_char(v_menor));
End;
9. Estructura de un bloque PL/SQL
crear secuencias y una tabla para trabajar los programas
CREATE SEQUENCE NUMEMPLEADOS MINVALUE
0 MAXVALUE 1000 INCREMENT BY 1 START
WITH 0 CACHE 20 NOORDER NOCYCLE ;
10. EN BASE A UNA SECUENCIA GUARDAR INSERTAR
EMPLEADOS CON ESE CORRELATIVOS
DECLARE
v_empno emp.empno%TYPE;
BEGIN
SELECT NUMEMPLEADOS.NEXTVAL
INTO v_empno
FROM dual;
INSERT INTO emp(empno, nombre, trabajo, depno)
VALUES(v_empno, 'nombre'|| to_char
(v_empno),'AUXILIAR', 10);
Commit;
END;
11. INSERTAR 10 REGISTROS EN UN CICLO
FOR .. LOOP
DECLARE
BEGIN
FOR i IN 1..10 LOOP
INSERT INTO emp(empno, nombre)
VALUES(i, 'nombre'|| to_char (i));
END LOOP;
Commit;
END;
12. INSERTAR EN UN CICLO WHILE
desde un valor mínimo hasta un máximo
ACCEPT menor PROMPT 'Introduce el menor: '
ACCEPT mayor PROMPT 'Introduce el mayor: '
DECLARE
maximo number;
minimo number;
BEGIN
maximo:=0;
minimo:=0;
maximo:=to_number(&mayor);
minimo:=to_number(&menor);
WHILE maximo>= minimo LOOP
dbms_output.put_line(minimo);
INSERT INTO emp(empno, nombre, trabajo, depno)
VALUES(minimo, 'nombre'|| to_char (minimo),'AUXILIAR', 10);
minimo:= minimo+1;
END LOOP;
Commit;
END;
13. Uso de rowtype y cursor para imprimir
valores de una tabla(PLSQL)
DECLARE
CURSOR cemp IS
SELECT empno,nombre,depno
FROM emp;
cepm_rec cemp%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE
('no nombre depno');
FOR cemp_rec IN cemp
LOOP
DBMS_OUTPUT.PUT_LINE
(cemp_rec.empno || ' ' || cemp_rec.nombre|| ' ' ||
cemp_rec.depno);
END LOOP;
END;
14. PARA PRACTICAR CON LOS PROCEDIMIENTOS Y FUNCIONES,
AGREGUE UNA COLUMNA LLAMADA SALARIO A EMP Y
PONGALES VALORES FICTICIOS
• EJ. ALTER TABLE EMP ADD SALARIO NUMBER(12,2);
• UPDATE EMP SET SALARIO=2000;
O BORRAR LOS DATOS MANUALMENTE, AGREGAR
COLUMNA EN SQL DEVELOPER
Y TOMANDO DE BASE EL CODIGO QUE ESTA EN LA
LAMINA 8... MODIFICAR EL INSERT…
INSERT INTO emp(empno, nombre, trabajo, depno,
salario)
VALUES(minimo, 'nombre'|| to_char
(minimo),'AUXILIAR', 10,2000);
15. PROCEDIMIENTO1…(oracle)
modificar el salario del empleado n(salario x 1.1)
CREATE OR REPLACE PROCEDURE act_salario
(v_id in emp.empno%TYPE)
IS
BEGIN
UPDATE emp
SET salario = salario * 1.10
WHERE empno =v_id;
END act_salario;
/
Ejecutelo para el empleado 10
EXECUTE act_salario (10);
16. CREATE PROCEDURE act_salario( @numemp INT
OUTPUT )
AS
UPDATE emp
SET salario = salario * 1.10
WHERE empno = @numemp
EXEC dbo.act_salario @numemp = 2
PROCEDIMIENTO1…(SQL)
modificar el salario del empleado n(salario x 1.1)
17. CREATE OR REPLACE PROCEDURE act_sa2
(v_id in emp.empno%TYPE, v_sal in emp.salario%TYPE)
IS
BEGIN
UPDATE emp
SET salario = v_sal
WHERE empno =v_id;
END act_sa2;
/
Ejecutelo para el empleado 10
EXECUTE act_sa2 (10,3000);
PROCEDIMIENTO2…(oracle)
modificar el salario del empleado n, salario x
18. PROCEDIMIENTO2…(SQL)
modificar el salario del empleado n, salario x
CREATE PROCEDURE act_salario2( @numemp INT,
@nsalario DOUBLE OUTPUT )
AS
UPDATE emp
SET salario = @nsalario
WHERE empno = @numemp
EXEC dbo.act_salario2 @numemp = 2, @nsalario = 40
19. FUNCION EN PL SQL(ORACLE)
CREATE OR REPLACE FUNCTION obten_sal
(v_id IN emp.empno%TYPE)
RETURN NUMBER
IS
v_salario emp.salario%TYPE :=0;
BEGIN
SELECT salario INTO v_salary
FROM emp WHERE empno = v_id;
RETURN (v_salary);
END obten_sal;
20. EJECUCION DE FUNCION EN PL SQL(ORACLE)
VARIABLE g_salario number
EXECUTE :g_salario := obten_sal(1)
21. FUNCION EN TRANSACT SQL(SQL)
CREATE FUNCTION fn_ObtenSalario
(
@Numempl int
)
RETURNS DECIMAL(10,2)
AS
BEGIN
DECLARE @mSalario DECIMAL(10,2)
SELECT @mSalario = salario FROM emp WHERE empno=
@Numempl
RETURN @mSalario
END
22. EJECUCION DE FUNCION EN TRANSACT(SQL)
DECLARE @Numempl int, @Resultado DECIMAL(10,2)
SET @Numempl= 2
SET @Resultado =hr.dbo.fn_ObtenSalario(@Numempl)
PRINT @Resultado
23. Cursores en Transact SQL
Un cursor es una variable que nos permite recorrer con
un conjunto de resultados obtenido a través de una
sentencia SELECT fila a fila.
Cuando trabajemos con cursores debemos seguir los
siguientes pasos.
• Declarar el cursor, utilizando DECLARE
• Abrir el cursor, utilizando OPEN
• Leer los datos del cursor, utilizando FETCH ... INTO
• Cerrar el cursor, utilizando CLOSE
• Liberar el cursor, utilizando DEALLOCATE
24. CURSOR TRANSACT SQL
-- Declaracion de variables para el cursor
DECLARE @empno numeric(3,0),
@nombre varchar(40),
@trabajo varchar(20),
@depno numeric(3,0),
@salario numeric(12,2)
-- Declaración del cursor
DECLARE cEMP CURSOR FOR
SELECT empno, nombre, trabajo, depno, salario FROM EMP
-- Apertura del cursor
OPEN cEMP
25. CURSOR TRANSACT SQL
-- Lectura de la primera fila del cursor/ luego impresión en ciclo while
FETCH cEMP INTO @empno, @nombre, @trabajo, @depno, @salario
PRINT ' nemp nombre trabajo depno salario'
-- Lectura de la siguiente fila del cursor
WHILE (@@FETCH_STATUS = 0 )
BEGIN
PRINT STR(@empno)+' '+@nombre + ' ' +replicate ('*',40-LEN(@nombre))+' '+
@trabajo +' '+replicate ('*',20-LEN(@trabajo))+STR(@depno)+' '+STR( @salario)
-- Lectura de la siguiente fila del cursor
FETCH cEMP INTO @empno, @nombre, @trabajo, @depno, @salario
END
-- Cierre del cursor
CLOSE cEMP
-- Liberar los recursos
DEALLOCATE cEMP