Está en la página 1de 14

Capacitación SQL y PL-SQL

Nivel Básico - Intermedio

TO_CHART
Convierte una fecha a una cadena o un número con el formato especificado.

Ejemplo:
SELECT TO_CHAR(sysdate) FROM DUAL;

Devuelve:

30-AGO-23
SELECT TO_CHAR(sysdate, 'dd/mm/yyyy') FROM DUAL;

SELECT TO_CHAR(sysdate, 'Month') FROM DUAL;

SELECT TO_CHAR(123.456, '09999') FROM DUAL;


Devuelve: 00123
SELECT TO_CHAR(123.456, '09999.9') FROM DUAL;
Devuelve: 01234.5

TO_DATE
TO_DATE es la función que se ejecuta en las bases de datos de Oracle para controlar, gestionar y modificar
fechas. Técnicamente, la función TO_DATE() de Oracle es la que permite convertir una cadena de caracteres o
datos de tipo CHAR, VARCHAR2, NCHAR, NVARCHAR2 en un valor de tipo DATE (fecha).

Ejemplo:
select TO_DATE('04/01/2020','DD/MM/YYYY') from dual;
Retorna
04/01/2020

LAST_DAY
Devuelve la fecha del último día del mes de la fecha D.

Ejemplo:
SELECT LAST_DAY(TO_DATE('01/10/2007','DD/MM/YYYY')) FROM DUAL;
Devuelve:
31/10/2007
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

ADD_MONTHS
Devuelve la fecha D más N meses. N puede ser cualquier entero. Si d es el último dia del mes origen y el mes
resultante tiene menos días, el resultado es el último día del mes resultante. En otro caso el día es el mismo.

Ejemplo:
SELECT ADD_MONTHS(TO_DATE('31/10/2007','DD/MM/YYYY'),4) FROM DUAL;

Devuelve:

29/02/2008

UPPER
Devuelve la cadena en mayúsculas.

Ejemplo:
SELECT UPPER('Pepe Perez') FROM DUAL;

Devuelve:

PEPE PEREZ

LOWER
Devuelve la cadena en minúsculas.

Ejemplo:
SELECT LOWER('PEPE PEREZ') FROM DUAL;

Devuelve:

Pepe

INITCAP
Devuelve la cadena con cada palabra empezando con mayúscula y el resto en minúsculas. Se considera que las
palabras están separadas por espacios o caracteres no alfanuméricos.
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio
Ejemplo:

SELECT INITCAP('pepe perez') FROM DUAL;

Devuelve: Pepe Perez

ROUND
Redondea N hasta la posición M a la derecha del punto decimal. Por defecto M es 0. Si M es negativo redondea
hacia la izquierda del punto decimal. Por supuesto, M debe ser entero.

Ejemplo:
SELECT ROUND(45.1242,2) FROM DUAL;

Devuelve: 45.12
SELECT ROUND(45.8242) FROM DUAL;

Devuelve: 46

CEIL
Redondea n hasta el valor superior.

Ejemplo:
SELECT CEIL(45.1242) FROM DUAL;

Devuelve: 46

FLOOR
Redondea n al valor inferior.

Ejemplo:
SELECT FLOOR(45.1242) FROM DUAL;

Devuelve: 45

SELECT FLOOR(-45.8242) FROM DUAL;


Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

Devuelve: -46

LENGTH
Numero de caracteres de una cadena. Si Char es de tipo CHAR, la longitud incluye los blancos del final.
SELECT LENGTH('PEPE PEREZ') FROM DUAL

Devuelve: 10

SELECT LENGTH('PEPE PEREZ ') FROM DUAL;

Devuelve: 15

Operadores Matemáticos
SUM
Devuelve la suma de un campo de la tabla

Ejemplo:
SELECT SUM(Columna) FROM T_PEDIDOS;

COUNT
Cuenta el número de valores en una columna o el número de filas en una tabla.

Ejemplo:
SELECT COUNT(*) FROM T_PEDIDOS;

MAX
Determina el mayor valor de una columna.

Ejemplo:
SELECT MAX(Columna) FROM T_PEDIDOS;
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

MIN
Devuelve el menor valor de un campo en una tabla.

Ejemplo:

SELECT MIN(Columna) FROM T_PEDIDOS;


AVG
Devuelve MEDIA de un campo en una tabla.

Ejemplo:
SELECT AVG(Columna) FROM T_PEDIDOS;

GROUP BY
La cláusula Oracle GROUP BY se utiliza en una declaración SELECT para recopilar datos en varios registros y
agrupar los resultados en una o más columnas.

Ejemplo:
SELECT expression1, expression2, ... expression_n,
aggregate_function (aggregate_expression)
FROM tables
[WHERE conditions]
GROUP BY expression1, expression2, ... expression_n;
Las expresiones que no están encapsuladas dentro de una función agregada y deben incluirse en la cláusula
GROUP BY.
Puede ser una función como SUM, COUNT, MIN, MAX o AVG.
Esta es la columna o expresión en la que se utilizará la función_agregada.
Las tablas de las que desea recuperar registros. Debe haber al menos una tabla listada en la cláusula FROM.
Opcional. Las condiciones que deben cumplirse para que los registros sean seleccionados.

Ejemplo:
SELECT manager_id, COUNT(department_id)
FROM departments
GROUP BY manager_id;
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

Consultas Multitablas
Consultas SELECT multi-tabla básicas – JOIN, la operación JOIN o combinación permite mostrar columnas de
varias tablas como si se tratase de una sola tabla, combinando entre sí los registros relacionados usando para
ello claves externas.

Nota: Las tablas relacionadas se especifican en la cláusula FROM, y además hay que hacer coincidir los valores
que relacionan las columnas de las tablas.
SELECT em.employee_id, em.manager_id, de.department_name
FROM employees em, departments de
WHERE em.department_id = de.department_id

Para evitar que se produzca como resultado el producto cartesiano entre las dos tablas, expresamos el vínculo
que se establece entre las dos tablas en la cláusula WHERE. En este caso relacionamos ambas tablas mediante el
identificador del departamento, clave existente en ambas. Fíjate en cómo le hemos otorgado un alias a cada
tabla (em y de respectivamente) para no tener que escribir su nombre completo cada vez que necesitamos
usarlas.

Hay que tener en cuenta que, si el nombre de una columna existe en más de una de las tablas indicadas en la
cláusula FROM, hay que poner, obligatoriamente, el nombre o alias de la tabla de la que queremos obtener
dicho valor. En caso contrario nos dará un error de ejecución, indicando que hay un nombre ambiguo.

Subconsultas
Una subconsulta es una sentencia SELECT que aparece dentro de otra sentencia SELECT que llamaremos
consulta principal.
Se puede encontrar en la lista de selección, en la cláusula WHERE o en la cláusula HAVING de la consulta
principal.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando que aparece encerrada
entre paréntesis, no puede contener la cláusula ORDER BY, ni puede ser la UNION de varias sentencias SELECT,
además tiene algunas restricciones en cuanto a número de columnas según el lugar donde aparece en la
consulta principal. Estas restricciones las iremos describiendo en cada caso.
Cuando se ejecuta una consulta que contiene una subconsulta, la subconsulta se ejecuta por cada fila de la
consulta principal.
Se aconseja no utilizar campos calculados en las subconsultas, ralentizan la consulta.
Las consultas que utilizan subconsultas suelen ser más fáciles de interpretar por el usuario.

Referencias externas
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de una columna en la
fila actual de la consulta principal, ese nombre de columna se denomina referencia externa.
Una referencia externa es un nombre de columna que estando en la subconsulta, no se refiere a ninguna
columna de las tablas designadas en la FROM de la subconsulta sino a una columna de las tablas designadas en
la FROM de la consulta principal. Como la subconsulta se ejecuta por cada fila de la consulta principal, el valor de
la referencia externa irá cambiando.
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

Ejemplo:

SELECT numemp, nombre, (SELECT MIN(fechapedido) FROM pedidos WHERE rep = numemp)
FROM empleados;

En este ejemplo la consulta principal es SELECT... FROM empleados.


La subconsulta es ( SELECT MIN(fechapedido) FROM pedidos WHERE rep = numemp ).
En esta subconsulta tenemos una referencia externa ( numemp ) es un campo de la tabla empleados (origen de
la consulta principal).

¿Qué pasa cuando se ejecuta la consulta principal?

- se coge el primer empleado y se calcula la subconsulta sustituyendo numemp por el valor que tiene en el
primer empleado. La subconsulta obtiene la fecha más antigua en los pedidos del rep = 101,
- se coge el segundo empleado y se calcula la subconsulta con numemp = 102 (numemp del segundo
empleado)... y así sucesivamente hasta llegar al último empleado.
Al final obtenemos una lista con el número, nombre y fecha del primer pedido de cada empleado.
Si quitamos la cláusula WHERE de la subconsulta obtenemos la fecha del primer pedido de todos los pedidos no
del empleado correspondiente.

Anidar subconsultas
Las subconsultas pueden anidarse de forma que una subconsulta aparezca en la cláusula WHERE (por ejemplo)
de otra subconsulta que a su vez forma parte de otra consulta principal. En la práctica, una consulta consume
mucho más tiempo y memoria cuando se incrementa el número de niveles de anidamiento. La consulta resulta
también más difícil de leer, comprender y mantener cuando contiene más de uno o dos niveles de subconsultas.

Ejemplo:

SELECT numemp, nombre


FROM empleados
WHERE numemp = (SELECT rep FROM pedidos WHERE clie = (SELECT numclie FROM clientes WHERE nombre =
'Julia Antequera'))
En este ejemplo, por cada línea de pedido se calcula la subconsulta de clientes, y esto se repite por cada
empleado, en el caso de tener 10 filas de empleados y 200 filas de pedidos (tablas realmente pequeñas), la
subconsulta más interna se ejecutaría 2000 veces (10 x 200).

Subconsulta en la lista de selección


Cuando la subconsulta aparece en la lista de selección de la consulta principal, en este caso la subconsulta, no
puede devolver varias filas ni varias columnas, de lo contrario se da un mensaje de error.
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio
Muchos SQLs no permiten que una subconsulta aparezca en la lista de selección de la consulta principal, pero
eso no es ningún problema ya que normalmente se puede obtener lo mismo utilizando como origen de datos las
dos tablas. El ejemplo anterior se puede obtener de la siguiente forma:

SELECT numemp, nombre, MIN(fechapedido)


FROM empleados LEFT JOIN pedidos ON empleados.numemp = pedidos.rep
GROUP BY numemp, nombre
En la cláusula FROM

En la cláusula FROM se puede encontrar una sentencia SELECT encerrada entre paréntesis, pero más que
subconsulta sería una consulta ya que no se ejecuta para cada fila de la tabla origen, sino que se ejecuta una sola
vez al principio, su resultado se combina con las filas de la otra tabla para formar las filas origen de la SELECT
primera y no admite referencias externas.
En la cláusula FROM vimos que se podía poner un nombre de tabla o un nombre de consulta, pues en vez de
poner un nombre de consulta se puede poner directamente la sentencia SELECT correspondiente a esa consulta
encerrada entre paréntesis.

Subconsulta en las cláusulas WHERE y HAVING


Se suele utilizar subconsultas en las cláusulas WHERE o HAVING cuando los datos que queremos visualizar están
en una tabla, pero para seleccionar las filas de esa tabla necesitamos un dato que está en otra tabla.

Ejemplo:

SELECT numemp, nombre


FROM empleados
WHERE contrato = (SELECT MIN(fechapedido) FROM pedidos)

En este ejemplo listamos el número y nombre de los empleados cuya fecha de contrato sea igual a la primera
fecha de todos los pedidos de la empresa.

En una cláusula WHERE / HAVING tenemos siempre una condición y la subconsulta actúa de operando dentro de
esa condición.
En el ejemplo anterior se compara contrato con el resultado de la subconsulta. Hasta ahora las condiciones
estudiadas tenían como operandos valores simples (el valor contenido en una columna de una fila de la tabla, el
resultado de una operación aritmética...) ahora la subconsulta puede devolver una columna entera por lo que es
necesario definir otro tipo de condiciones especiales para cuando se utilizan con subconsultas.
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

Cursores en PL/SQL
Los cursores se utilizan en PL/SQL para manejar las sentencias SELECT. Un cursor está formado por un conjunto
de registros devueltos por una instrucción SQL del tipo SELECT. Desde un punto de visto interno a la base de
datos Oracle, los cursores son segmentos de memoria utilizados para realizar operaciones con los registros
devueltos tras ejecutar una sentencia SELECT.

Cursores PLSQL implícitos


Este tipo de cursores se utiliza para operaciones SELECT INTO. Se usan cuando la consulta devuelve un único
registro.

Atributos con Cursores implícitos


Los atributos de los cursores implícitos que se crean son los siguientes:

SQL%NOTFOUND: Nos dice si el último insert, update, delete o select into no han afectado a ninguna fila.
SQL%FOUND: Nos dice si el último insert, update, delete o select into ha afectado a una o más filas.
SQL%ROWCOUNT: Devuelve el número de filas afectadas por el último insert, update, delete o select into.
SQL% ISOPEN: Nos dice si el cursor está cerrado, por lo que en teoría siempre nos dará falso ya que Oracle cierra
automáticamente el cursor después de cada orden SQL.
Es importante tener en cuenta una serie de cosas si se trata de un select into, debido a que si no devuelve una
única fila nos levantará automáticamente una de estas dos excepciones:

NO_DATA_FOUND: Si la consulta no devuelve ninguna fila.


TOO_MANY_ROWS: Si la consulta devuelve más de una fila.
Cuando un select into hace referencia a una función de grupo, nunca se levantará la excepción
NO_DATA_FOUND y SQL%FOUND siempre será verdadero. Esto se explica porque las funciones de grupo
siempre devuelven algún valor (NULL se considera un valor).

Cursores PLSQL explícitos


Son los cursores que son declarados y controlados por el programador. Se utilizan cuando la consulta devuelve
un conjunto de registros. Ocasionalmente también se utilizan en consultas que devuelven un único registro, por
razones de eficiencia. Son más rápidos.

Los cursores explícitos los utilizamos cuando tenemos consultas que nos devuelven más de una fila. Tenemos 4
operaciones básicas para trabajar con un cursor explícito.

Declaración del cursor: Lo tenemos que declarar en la zona de declaraciones, con el siguiente formato:

CURSOR <nombrecursor> IS <sentencia SELECT>;

Apertura del cursor: Deberá colocarse en la zona de instrucciones, con el siguiente formato:

OPEN <nombrecursor>
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio
Al hacerlo se ejecuta automáticamente la sentencia select y sus resultados se almacenan en las estructuras
internas de memoria manejadas por el cursor.

Recogida de información: Para recuperar la información anteriormente guardada en las estructuras de memoria
interna tenemos que usar el siguiente formato:

FETCH <nombrecursor> INTO {<variable> | <listavariables>};

Si tenemos una única variable que recoge los datos de todas las columnas, el formato de la variable sería el
siguiente:

<variable> <nombrecursor>%ROWTYPE;

Si tenemos una lista de variables, cada una recogerá la columna correspondiente de la cláusula select, por lo que
serán del mismo tipo que las columnas.

Cierre del cursor:

CLOSE <nombrecursor>

Ejemplo de utilización de cursores explícitos:

DECLARE

CURSOR C1 IS SELECT nombre, apellido FROM arbitro;

vnom VARCHAR2(12);

vape VARCHAR2(20);

BEGIN

OPEN C1;

LOOP

FETCH C1 INTO vnom, vape;

EXIT WHEN C1%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(vnom || '' || vapen);

END LOOP;

CLOSE LOOP;

END;

Si nos fijamos, en la declaración de los cursos explícitos no utilizamos la cláusula INTO, que si se utilizaba en los
cursores implícitos.

Además, se puede ver que después del FETCH hemos comprobado si nos devuelve valores con la línea del EXIT.
Es algo importante ya que si no nos devuelve nada el LOOP se interrumpirá.
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio

Atributos del cursor explícito


Para conocer detalles de la situación del cursor tenemos 4 atributos.

nombrecursor%FOUND: devuelve verdadero si el último FETCH ha recuperado algún valor; en caso contrario
devuelve falso; si el cursor no está abierto nos devuelve error.

nombrecursor%NOTFOUND: Hace justamente lo contrario al anterior.

nombrecursor%ROWCOUNT: Nos devuelve el número de filas recuperadas hasta el momento.

nombrecursor%ISOPEN: Devuelve verdadero si el cursor está abierto.

Ejemplo de utilización de %ROWCOUNT:

DECLARE

CURSOR C1 IS SELECT nombre FROM futbolista WHERE cod = 'e1';

vnom VARCHAR2(15);

BEGIN

OPEN C1;

LOOP

FETCH C1 INTO vnom;

EXIT WHEN C1%NOTFOUND;

DBMS_OUTPUT.PUT_LINE (C1%ROWCOUNT || vnom);

END LOOP;

CLOSE C1;

END;

Cursor FOR . LOOP

El trabajo normal de un cursor consiste en declarar un cursor, declarar una variable que recogerá los datos del
cursor, abrir el cursor, recuperar un FETCH, una a una las fils extraídas introduciendo los datos en las variables,
procesándolos y comprobando si se han recuperado datos o no.

Para resumir todas esas tareas, tenemos una estructura cursor FOR... LOOP que hace todas estas cosas de forma
implícita, todas menos la declaración del cursor.
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio
El formato y el uso de esta estructura es:

Se declara la información cursor en la sección correspondiente.

Se presenta el cursor utilizando el siguiente formato:

FOR nombreVarReg IN nombreCursor LOOP

..

END LOOP

Al entrar en el bucle se abre el cursor de manera automática, se declara implícitamente la variable


nombreVarReg de tipo nombrecursor%ROWTYPE y se ejecuta el primer fetch cuyo resultado quedarán en
nombreVarReg. A continuación se realizarán las acciones que correspondan hasta llegar al END LOOP.

Ejemplo de LOOP . END LOOP

DECLARE

cursor c2 is select nombre, peso, estatura, FROM jugador WHERE salario>1200;

BEGIN

FOR vreg IN c2 LOOP

DBMS_OUTPUT.PUT_LINE(vreg.nombre || '-' || vreg.peso || '-' || vreg.estatura);

END LOOP;

END;

Uso de cursores para actualizar filas

Para realizar una actualización con un cursor tenemos que añadir la siguiente FOR UPDATE al final de la
declaración del cursor:

CURSOR nombre_cursor <declaraciones> FOR UPDATE

Esto indica que las filas seleccionadas por el cursor van a ser actualizadas o borradas. Una vez declarado un
cursor FOR UPDATE, se incluirá el especificador CURRENT OF nombre_cursor en la cláusula WHERE para
actualizar o borrar la última fila recuperada mediante la orden FETCH.

{UPDATE | DELETE}... WHERE CURRENT OF nombre_cursor


Capacitación SQL y PL-SQL
Nivel Básico - Intermedio
Ejemplo: Subir el salario de todos los empleados del departamento indicado en la llamada. El porcentaje se
indicará también en la llamada.

CREATE OR REPLACE PROCEDURE subir_salario (num_dept NUMBER, incre NUMBER)

IS

CURSOR c IS SELECT oficio, salario FROM empleados

WHERE cod_dept=num_dept FOR UPDATE;

reg c%ROWTYPE;

inc NUMBER(8);

BEGIN

OPEN c;

FETCH c INTO reg;

WHILE c%FOUND LOOP

inc := (reg.salario/100) * inc;

UPDATE empleados SET salario = salario + inc WHERE CURRENT OF c

FETCH c INTO reg;

END LOOP;

END;

También podemos usar ROWID en lugar de FOR UPDATE. ROWID nos indicará la fila que se va a actualizar. Para
ello, al declarar el cursor en la cláusula SELECT indicaremos que seleccione también el identificador de fila:

CURSOR nombre_cursor IS SELECT columna1, columna2,... ROWID FROM tabla;

Al ejecutarse el FETCH se guardará el número de fila en una variable y después ese número se podrá usar en la
cláusula WHERE de la actualización:

{UPDATE | DELETE}... WHERE ROWID = variable_rowid

El ejemplo anterior utilizando ROWID quedaría de la siguiente manera:

CREATE OR REPLACE PROCEDURE subir_salario (num_dept NUMBER, incre NUMBER)

IS

CURSOR c IS SELECT oficio, salario, ROWID FROM empleados

WHERE cod_dept= num_dept

FOR UPDATE;
Capacitación SQL y PL-SQL
Nivel Básico - Intermedio
reg c%ROWTYPE;

inc NUMBER(8);

BEGIN

OPEN c;

FETCH c INTO reg;

WHILE c%FOUND LOOP

inc:=(reg.salario/100) * inc;

UPDATE empleados SET salario=salario + inc WHERE ROWID = reg.ROWID;

FETCH c INTO reg;

END LOOP;

END;

También podría gustarte