2. Experiencia Nombre
Unidad de Competencia Especialidad –
Nivel de la Competencia de
Empleabilidad
Nº 1 Construyendo Bloques
Anónimos PL/SQL Simples
Desarrolla operaciones sobre la base de
datos que permitan administrar los
objetos de la misma de acuerdo a
requerimientos de usuario y buenas
prácticas de la industria.
Resolución de Problemas (N1)
Experiencia de Aprendizaje
y Competencia Asociada
3. Objetivos de la Clase
• Cómo usar sentencias DML en un bloque PL/SQL.
• Cómo controlar las transacciones en PL/SQL
• Qué es un Cursor SQL.
• Qué atributos usar para controlar el resultado de los Cursores
Implícitos.
• Qué Funciones SQL se pueden usar en un bloque PL/SQL
10. 10
Control de Transacciones
en PL/SQL
• Ejemplo:
BEGIN
/* Se aumenta el salario del empleado 100 */
UPDATE empleados
SET salary = salary + 100
WHERE employee_id = 100;
/* Se elimina el empleado 101 */
DELETE FROM job_history
WHERE employee_id = 101;
/* Se marca con el nombre INSERTA la sentencia que inserta un nuevo departamento. */
SAVEPOINT INSERTA;
/* Se inserta un nuevo departamento */
INSERT INTO departments
VALUES(departments_seq.NEXTVAL, 'DEPTO NUEVO', '110', 1700);
/* Se realiza ROLLBACK sólo de la sentencia que inserta el nuevo departamento */
ROLLBACK TO INSERTA;
/* El COMMIT afecta a las sentencias de actualización y eliminación de filas */
COMMIT;
END;
13. 13
Atributos de Cursor SQL
para Cursores Implícitos
• Ejemplo:
DECLARE
v_filas_elim VARCHAR2(30);
v_empno empleados.employee_id%TYPE := 176;
BEGIN
DELETE FROM empleados
WHERE employee_id = v_empno;
v_filas_elim := (SQL%ROWCOUNT || ' fila(s) eliminada(s).');
DBMS_OUTPUT.PUT_LINE (v_filas_elim);
COMMIT;
END;
14. 14
Atributos de Cursor SQL
para Cursores Implícitos
• Ejemplo:
BEGIN
UPDATE empleados
SET salary = salary + (salary * NVL(commission_pct,0))
WHERE salary < 1000;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Se actualizaron ' || SQL%ROWCOUNT || ' filas');
ELSE
DBMS_OUTPUT.PUT_LINE('No se actualizaron filas');
END IF;
DELETE FROM empleados
WHERE salary < 5000;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('No se eliminaron filas');
ELSE
DBMS_OUTPUT.PUT_LINE ('Se eliminaron ' || SQL%ROWCOUNT || ' filas');
END IF;
COMMIT;
END;
18. 18
Funciones SQL para usar en
Sentencias PL/SQL y SQL
• Ejemplo:
DECLARE
v_sal_prom PLS_INTEGER := 0;
v_sal_mayor NUMBER(8) := 0;
BEGIN
SELECT ROUND(AVG(salary)), MAX(salary)
INTO v_sal_prom, v_sal_mayor
FROM employees;
DBMS_OUTPUT.PUT_LINE('Salario promedio es: ' || TO_CHAR(v_sal_prom, '$9,999'));
DBMS_OUTPUT.PUT_LINE('Salario mayor es: ' || TO_CHAR(v_sal_mayor, '$99,999'));
END;
19. 19
Funciones SQL para usar en
Sentencias PL/SQL y SQL
• Ejemplo:
DECLARE
v_apell EMPLEADOS.last_name%TYPE;
v_nombre EMPLEADOS.first_name%TYPE;
v_comision EMPLEADOS.commission_pct%TYPE;
v_salario NUMBER(6);
v_id_emp NUMBER(3):=110;
BEGIN
SELECT last_name, UPPER(first_name), commission_pct, salary
INTO v_apell, v_nombre, v_comision, v_salario
FROM employees
WHERE employee_id = v_id_emp;
IF NVL(v_comision,0)=0 AND v_salario < 5000 THEN
UPDATE empleados
SET salary=salary*1-25
WHERE employee_id=v_id_emp;
COMMIT;
DBMS_OUTPUT.PUT_LINE('Se aumentó el salario del empleado ' || v_nombre || ' ' || v_apell);
ELSE
DBMS_OUTPUT.PUT_LINE('No se actualizó el salario del empleado ' || v_nombre || ' ' || v_apell);
END IF;
END;
20. 20
Conversión de Tipos de
Datos en PL/SQL
En PL/SQL existen
dos tipos de
conversiones:
Implícita y Explícita
En una conversión
implícita, se
convierten tipos de
datos
automáticamente
En una conversión
explícita, se
convierte un valor
de un tipo a otro
utilizando funciones
predefinidas
Se convierte un
valor desde un tipo
a otro para tener
tipos de datos
comparables
21. 21
Conversión de Tipos de
Datos en PL/SQL
• Ejemplo:
DECLARE
v_fecha_reunion DATE:= '09-Mar-2020';
v_fecha_contrato DATE:= TO_DATE('Febrero 02,2000','Month DD, YYYY');
v_fecha_actual VARCHAR2(20);
v_salario NUMBER(6):=6000;
v_bono VARCHAR2(5):='1000';
v_total_salario v_salario%TYPE;
BEGIN
SELECT TO_CHAR(sysdate,'Month DD, YYYY')
INTO v_fecha_actual
FROM dual;
v_total_salario := v_salario + v_bono;
END;
22. 22
Resumen de la Clase
• Se explicó cómo usar sentencias DML en un bloque PL/SQL.
• Se explicó cómo controlar las transacciones en PL/SQL
• Se explicó qué es un Cursor SQL.
• Se explicó qué atributos usar para controlar el resultado de los
Cursores Implícitos.
• Se explicó que Funciones SQL se pueden usar en un bloque
PL/SQL
Notas del editor
Sentencias SQL en Bloques PL/SQL
Cuando se consulta información o se efectúan cambios a la Base de Datos se debe usar SQL. PL/SQL soporta el Lenguaje de Manipulación de datos (DML) y los comandos del control de transacciones de SQL. En un bloque PL/SQL se pueden recuperar una o varias filas desde la Base de Datos utilizando el comando SELECT. Para realizar cambios a una o varias filas de la Base de Datos en un bloque PL/SQL se deben utilizar los comandos DML INSERT, UPDATE, DELETE y/o MERGE. Para controlar una transacción en el bloque PL/SQL de debe utilizar el comando COMMIT, ROLLBACK ó SAVEPOINT.
PL/SQL no admite directamente el uso del lenguaje de definición de datos (DDL), como CREATE TABLE, ALTER TABLE o DROP TABLE. Estas sentencias pueden ejecutar a través de SQL Dinámico.
PL/SQL no admite directamente del lenguaje de control de datos (DCL), como las sentencias GRANT o REVOKE. Para ejecutar estas sentencias se puede utilizar SQL dinámico.
Manipulación de Datos en PL/SQL
Se manipulan los datos en la base de datos mediante el uso de los comandos DML. Se pueden ejecutar comandos DML de INSERT, UPDATE y DELETE sin restricciones en PL/SQL. Los bloqueos de fila (y bloqueos de tabla) se liberan mediante la inclusión de COMMIT O ROLLBACK en las sentencias del bloque PL/SQL.
Todas estas sentencias DML tienen el mismo formato como se usan en sentencias simples de SQL.
La sentencia INSERT agrega nuevas filas a la tabla.
La sentencia UPDATE modifica filas existentes en la tabla.
La sentencia DELETE elimina filas de la tabla.
Inserción de Datos en PL/SQL
En el primer ejemplo, el bloque PL/SQL agrega información de un nuevo empleado a la tabla EMPLEADOS.
En el segundo ejemplo, se crea la tabla BONO la que es utilizada en el bloque PL/SQL para insertar información obtenida desde la tabla EMPLEADOS. En este caso, la identificación del empleado y el 20% del salario valores serán almacenados en las columnas id_empleado y bono de la tabla BONO respectivamente.
Modificación de Datos en PL/SQL
En el bloque PL/SQL del primer ejemplo, se incrementa el salario actual en 800 dólares de todos los empleados cuyo trabajo es ST_CLERK.
En el bloque PL/SQL del segundo ejemplo, se eliminan, desde tabla EMPLEADOS, las filas de los empleados que pertenezcan al departamento 10.
Control de Transacciones en PL/SQL
Una transacción es una serie de sentencias SQL de manipulación de datos que provee una unidad lógica de trabajo. Las sentencias de control de transacciones permiten asegurar la consistencia de la Base de Datos. Las sentencias de control de transacciones usadas son COMMIT, ROLLBACK y SAVEPOINT.
Las sentencias que se ejecutan después del último COMMIT o ROLLBACK comprenden la transacción (o grupo de transacciones activas o actual). De forma implícita se inicia una nueva transacción después de un COMMIT o ROLLBACK. La sentencia COMMIT finaliza la transacción actual y efectúa los cambios en la Base de Datos en forma permanente.
La sentencia ROLLBACK finaliza la transacción actual y deshace todos los cambios realizados en la Base de Datos por la transacción actual. Con la sentencia SAVEPOINT es posible nombrar y marcar un punto determinado donde se podrá retornar el control luego de ejecutarse una sentencia ROLLBACK.
Control de Transacciones en PL/SQL
En el en el bloque del ejemplo, con SAVEPOINT se “marca” la instrucción que inserta una nueva fila a tabla DEPARTMENTS con el nombre INSERTA. Por lo tanto el ROLLBACK se efectúa sólo a la sentencia INSERT y COMMIT afectará a las sentencias UPDATE y DELETE del bloque PL/SQL.
Cursor SQL
Como se ha explicado anteriormente, las sentencias SELECT que devuelven una sola fila se pueden incluir en un bloque PL/SQL. Los datos recuperados por la sentencia SQL se almacenan en las variables mediante la cláusula INTO.
Las sentencias SQL son procesadas por el servidor Oracle quien asigna un área de memoria privada denominada área de contexto para el procesamiento de sentencias SQL. La sentencia SQL se analiza y se procesa en esta área. La información necesaria para el procesamiento y la información obtenida tras el procesamiento se almacenan en esta área. No se tiene control sobre esta área, ya que se gestiona internamente por el servidor Oracle. Un cursor es un puntero a la zona de contexto. Sin embargo, este cursor es un cursor implícito y es gestionado automáticamente por el servidor Oracle. Cuando el bloque PL/SQL ejecuta una sentencia SQL, PL/SQL crea un cursor implícito. Existen dos tipos de cursores:
Cursor Implícito: se crea y está gestionado por el servidor Oracle. No se tiene acceso a él. El servidor de Oracle crea un cursor como cuando tiene que ejecutar una sentencia SQL.
Cursor Explícito: como programador, es posible que desee recuperar varias filas de una tabla de base de datos, En estos casos, se puede declarar cursores explícitamente en función de las necesidades de negocio. Un cursor declarado por los programadores se denomina cursor explícito. Se debe declara un cursor en la sección declarativa de un bloque PL/SQL.
Atributos de Cursor SQL para Cursores Implícitos
Los atributos de cursor de SQL permiten evaluar lo que sucedió cuando un cursor implícito se ha utilizado por última vez. Estos atributos se deben utilizar en las sentencias PL/SQL, pero no en las sentencias SQL.
Se pueden utilizar los atributos SQL%ROWCOUNT, SQL%FOUND, and SQL%NOTFOUND en la sección ejecutable de un bloque después que se ha ejecutado las sentencia DML. PL/SQL no devuelve un error si una sentencia DML no afecta a las filas de la tabla. Sin embargo, si una sentencia SELECT no recupera ninguna fila no se puede controlar usando el atributo SQL%ROWCOUNT ya que PL/SQL devuelve una excepción.
Los atributos tienen el prefijo SQL. Estos atributos del cursor se utilizan con los cursores implícitos que son creados automáticamente por PL/SQL y para los cuales no se conoce los nombres. Por lo tanto, se utiliza SQL en lugar del nombre del cursor.
El atributo SQL%NOTFOUND es contrario a SQL%FOUND. Este atributo puede ser utilizado como la condición de salida en un LOOP. Es útil en UPDATE y DELETE cuando no se modifica ninguna fila porque en estos casos no se retornan excepciones.
Atributos de Cursor SQL para Cursores Implícitos
En el ejemplo, se eliminan las filas de la tabla EMPLEADOS que tienen el ID de empleado 176. Posteriormente se visualiza en total de filas eliminas. Par esto se usa el atributo %ROWCOUNT que retorna el total de filas afectadas por la última sentencia SQL ejecutada.
Atributos de Cursor SQL para Cursores Implícitos
En el bloque del ejemplo, se usa la tabla EMPLEADOS creada en el ejemplo anterior para realizar las modificaciones de datos. En la primera sentencia se aumenta el salario actual sumándole el valor de la comisión a los empleados con salario menor a 1000. Posteriormente se pregunta si la sentencia afectó alguna fila (con el atributo SQL%FOUND) y se mostrará el total de filas que fueron actualizadas (con el atributo SQL%ROWCOUNT). Si no actualizaron filas se mostrará el mensaje No se actualizaron filas.
La segunda sentencia, se eliminan los empleados con salario menor a 5000. Posteriormente se pregunta si no hubieron filas afectadas (con el atributo SQL%NOTFOUND) para mostrar el mensaje No se eliminaron filas, de lo contrario se visualizará el total de filas que fueron eliminadas (con el atributo SQL%ROWCOUNT).
Funciones SQL para usar en Sentencias PL/SQL y SQL
Las funciones disponibles en sentencias procedimentales son aquellas funciones SQL que están disponibles para ser utilizadas en sentencias PL/SQL y en sentencias SQL que forman parte del bloque PL/SQL:
Funciones numéricas de una fila (single_row number): ROUND, TRUNC, MOD.
Funciones de carateres de una fila (single_row character): LOWER, UPPER, INITCAP, CONCAT, SUBSTR, etc.
Conversiones de tipo de dato: TO_CHAR, TO_DATE etc.
Funciones de fecha: SYSDATE, MONTH_BETWEEN, ADD_MONTHS, NEXT_DAY, etc.
Funciones Timestamp.
Funciones generales: COALESCE, NVL, NULLIF, etc.
Las funciones No Disponibles en sentencias PL/SQL son funciones SQL que sólo pueden ser utilizadas en sentencias SQL que forman parte del bloque PL/SQL y no en sentencias propias de PL/SQL:
DECODE.
Funciones de grupo: AVG, MIN, MAX, COUNT, etc.
Funciones SQL para usar en Sentencias PL/SQL y SQL
Las funciones disponibles en sentencias procedimentales son aquellas funciones SQL que están disponibles para ser utilizadas en sentencias PL/SQL y en sentencias SQL que forman parte del bloque PL/SQL:
Funciones numéricas de una fila (single_row number): ROUND, TRUNC, MOD.
Funciones de carateres de una fila (single_row character): LOWER, UPPER, INITCAP, CONCAT, SUBSTR, etc.
Conversiones de tipo de dato: TO_CHAR, TO_DATE etc.
Funciones de fecha: SYSDATE, MONTH_BETWEEN, ADD_MONTHS, NEXT_DAY, etc.
Funciones Timestamp.
Funciones generales: COALESCE, NVL, NULLIF, etc.
Las funciones NO Disponibles en sentencias PL/SQL son funciones SQL que sólo pueden ser utilizadas en sentencias SQL que forman parte del bloque PL/SQL y no en sentencias propias de PL/SQL:
DECODE.
Funciones de grupo: AVG, MIN, MAX, COUNT, etc.
Funciones SQL para usar en Sentencias PL/SQL y SQL
En el bloque del ejemplo, se obtiene el salario promedio (redondeado) y el salario máximo entre todos los empleados. Las funciones AVG y MAX sólo se puede utilizar en la sentencia SQL del bloque PL/SQL. Las funciones ROUND y TO_CHAR se pueden utilizar en sentencias SQL dentro del bloque y también en sentencias PL/SQL.
Funciones SQL para usar en Sentencias PL/SQL y SQL
En el bloque PL/SQL del ejemplo, se usa la función UPPER en la sentencia SELECT para obtener en mayúscula el primer nombre obtiene del empleado 110 (valor que se asigna a la variable v_id_emp.
Posteriormente en la sentencia IF, propia de PL/SQL, se usa la función NVL para preguntar que si el porcentaje de comisión obtenido es cero (si el valor del porcentaje de comisión es nulo, la función NVL lo reemplazará por cero) y el salario es menor a 5000 entonces se aumentará en 25% el salario del empleado 110.
Ambas funciones se pueden usar en sentencias SQL dentro del bloque y también en sentencias propias del lenguaje PL/SQL dentro del bloque.
Conversión de Tipos de Datos en PL/SQL
Cada constante o variable posee un tipo de dato el cual especifica su forma de almacenamiento, restricciones y rango de valores válidos. Se convierte un valor desde un tipo a otro para tener tipos de datos comparables.
En PL/SQL existen dos tipos de conversiones:
Implícita: convierte tipos de datos automáticamente si son variados en una sentencia. Las conversiones implícitas pueden ocurrir entre caracteres y números o caracteres y fechas:
- De VARCHAR2 o CHAR a NUMBER.
- De VARCHAR2 o CHAR a DATE.
- De NUMBER a VARCHAR2.
- DATE a VARCHAR2.
Explícita: es aquella que convierte un valor de un tipo a otro utilizando funciones predefinida:
- TO_CHAR
- TO_DATE
- TO_NUMBER
- TO_TIMESTAMP
Funciones SQL para usar en Sentencias PL/SQL y SQL
En el ejemplo, el valor asignado a la variable v_fecha_de_reunion es un string que tiene un formato de fecha válido, por lo tanto Oracle efectúa una conversión implícita a tipo de datos fecha. La variable v_fecha_contrato es de tipo de dato DATE, por lo tanto se usa la función TO_DATE para convertir explícitamente la fecha dada en un formato particular. La variable v_bono es de tipo VARCHAR2, por lo tanto cuando se efectúa el cálculo en la variable v_total_salario PL/SQL primero convierte v_bono a NUMBER (conversión implícita) y luego se realiza la sumatoria (el resultado de la operación será entonces de tipo NUMBER). En la sentencia SELECT se utiliza la función TO_CHAR para convertir en forma explícita la fecha actual en un formato tipo caracter.