INTRODUCCIÓN A SQL
SQL es un lenguaje de programación orientado a las bases de datos, que nos va a permitir obtener información referente a los datos que se almacenan en las mismas. SQL es un estándar de lenguaje a partir del cual han surgido diferentes versiones según el fabricante que los ha ido desarrollando, así nos podemos encontrar con el SQL de Microsoft SQL Server, el de Oracle, ... que son muy similares entre sí, pero pueden tener diferencias significativas.
SQL permite clasificar los comandos en cuatro categorías:
Un comando SELECT es una expresion que me va a devover los datos de una o varias tablas, atendiendo a una serie de filtros o no y mostrándome esos datos ordenados si me interesa. La estructura básica de la select es como sigue:
|
SELECT campos FROM tablas WHERE condiciones ORDER BY campos |
Dentro de las sentencias SELECT encontramos varias partes:
Dentro del área de criterios (dentro del WHERE) tenemos los siguientes operadores:
| CONDICIÓN | EJEMPLO |
| A=B | SELECT title FROM movie WHERE DirectorName ='Spielberg'; |
| A!=B, A<>B | SELECT title FROM movie WHERE DirectorName !='Spielberg'; |
| A>B, A>=B | SELECT * FROM rental WHERE DailyRate>=1.99; |
| A<B, A<=B | SELECT * FROM rental WHERE DailyRate<=1.99; |
| A IN (List) | SELECT title FROM movie WHERE rating IN ('PG!3, 'R'); |
| A BETWEEN x AND y | SELECT * FROM rental WHERE DailyRate BETWEEN (1.99 AND 2.99); |
| A LIKE y | SELECT title FROM movie WHERE DirectorName LIKE 'Spiel%'; |
| A IS NULL | SELECT title FROM movie WHERE rating IS NULL; |
| NOT | SELECT title FROM movie WHERE rating IS NOT NULL; |
Además podemos trabajar con lo que se denominan operadores booleanos, que nos van a permitir añadir criterios de filtrado adicionales, estos operadores son AND y OR.
CLAUSULA GROUP BY
La cláusula GROUP BY me va a permitir trabajar con agregados de datos, por ejemplo, si me interesa saber el salario medio por departamento, el número de trabajadores por departamento, etc. La cláusula GROUP BY necesita de manera obligada llevar una función de agregado dentro de la SELECT. Así tendremos por ejemplo:
| SELECT DepName, AVG(Sal) FROM salary GROUP BY DepName |
Hemos de tener en cuenta que todos los campos que estén en la SELECT y que no formen parte de una función de agregado (AVG, MAX, MIN, COUNT) tendrán que formar parte del GROUP BY.
JOINS
Los joins son la manera que tendremos nosotros para obtener datos de diferentes tablas. Los joins me van a permitir relacionar las claves primarias con sus claves foráneas correspondientes. Tenemos diferentes tipos de joins:
INNER JOIN: me va a coger de la primera tabla todos los registros que estén relacionados con registros de la tabla a la que se va a unir (segunda tabla), y de la tabla segunda todos aquellos registros que estén relacionados con registros de la primera tabla. Es decir, valores que no estén relacionados no me los va a mostrar.
LEFT JOIN: de la primera tabla cogerá todos los registros estén o no relacionados con registros de la tabla de la derecha, mientras que de la tabla de la derecha sólo cogerá aquellos registros que estén relacionados con registros de la tabla de la izquierda
RIGHT JOIN: es el caso contrario del left join.
FULL JOIN: cogerá todos los registros de la tabla de la izquierda, estén o no relacionados con los de la tabla de la derecha, mientras que de la tabla de la derecha cogerá todos los registros estén o no relacionados con registros de la tabla de la izquierda.
CROSS JOIN: hará un producto cartesiano cogiendo los registros de la tabla izquierda y relacionándolos individualmente con los registros de la tabla derecha también de forma individual, y hará lo mismo con los registros de la tabla de la derecha.
La sentencia para estos joins sería como sigue:
| SELECT T1.C1, T1.C2, T2.C2 FROM T1, T2 WHERE T1.PK=T2.FK
--> INNER JOIN
SELECT T1.C1, T1.C2, T2.C2 FROM T1, T2 WHERE T1.PK=T2.FK (+)--> RIGHT JOIN SELECT T1.C1, T1.C2, T2.C2 FROM T1, T2 WHERE T1.PK(+)=T2.FK --> LEFT JOIN |
OPERACIONES CON CONJUNTOS(SET)
Un SET es un conjunto de objetos que comparten una serie de características comunes. Generalmente se denominan en mayúsculas. Así por ejemplo tendremos:
| SEMANA={Lunes, Martes, Miércoles, Jueves, Viernes, Sábado, Domingo} |
Tenemos tres operadores básicos cuando queremos trabajar con conjuntos, estas operaciones son:
UNIÓN: contiene los elementos que forman parte de ambos conjuntos.
Por ejemplo si queremos ver todas las películas que ha hecho Emma Thompson y todas las que ha hecho Anthony Hopkins usaremos la sentencia:
| SELECT title FROM movie WHERE ActorName='Anthony Hopkins' UNION SELECT title FROM movie WHERE actress='Emma Thompson'; |
INTERSECCIÓN: contiene los elementos que son comunes en ambos conjuntos.
Si lo que queremos ahora es ver aquellas películas en las que han participado ambos actores, usaremos la sentencia:
| SELECT title FROM movie WHERE ActorName='Anthony Hopkins' INTERSECT SELECT title FROM movie WHERE actress='Emma Thompson'; |
MINUS: contiene los elementos que forman parte del primer conjunto pero no del segundo.
Si por el contrario queremos que nos muestren las películas donde no ha participado ni Anthony Hopkins ni Emma Thompson tendremos que:
| SELECT title FROM movie WHERE ActorName='Anthony Hopkins' MINUS SELECT title FROM movie WHERE actress='Emma Thompson'; |
Las sentencias DML son aquellas sentencias que me van a permitir manipular los datos, van a modificar el contenido de los datos de la base de datos.
Los cambios que provocan estas sentencias no ocurren al momento, sino que tienen lugar cuando nosotros aceptamos la transacción. Esta aceptación de la transacción se realiza mediante la orden COMMIT. El funcionamiento es el siguiente: Cuando se modifican los datos Oracle guarda esta modificación en su estructura interna, en los segmentos que se denominan de Rollback, en ese mismo momento se produce un bloqueo en el registro que se está modificando para evitar que otros usuarios puedan modificarlo. Cuando se produce el commit, los datos se almacenan en la base de datos y permite a otros usuarios acceder a los mismos. Si por otra parte, decidimos deshacer los cambios que se han producido, antes de realizar un COMMIT, tendremos que hacer un ROLLBACK de los datos que han sido modificados, haciendo esto conseguimos que se recuperen los mismos datos que había antes de la modificación.
La sentencia INSERT
La sentencia insert lo que hará será añadir un nuevo registro dentro de la base de datos, su sentencia básica es la siguiente:
| INSERT INTO tabla (campos) VALUES (valores); |
Siendo el parámetro campos opcional, que lo utilizaremos cuando:
1- No vayamos a insertar tantos valores como campos tiene la tabla, con lo cual le tendremos que indicar que campos quiero rellenar
2- No vayamos a insertar los valores en el orden que tienen los campos en la tabla.
Por ejemplo:
| INSERT INTO movies VALUES (211, 'El piano', 'Jane Campion', 'Harvey Keitel', 'Holly Hunter', 'R') |
| INSERT INTO movies (Id, title, directorname, actorname, actressname, rating) VALUES (211, 'El piano', 'Jane Campion', 'Harvey Keitel', 'Holly Hunter', 'R') |
Podemos insertar registros dentro de una tabla a través de una SELECT, del modo siguiente:
Con esta sentencia insertaríamos en una tabla de morosos todos aquellos clientes que tuvieran en su poder una película por más de un mes.
| INSERT INTO late_return SELECT customerId, firstname, lastname, phone, title, rentdate, returndate FROM customer, movie, rental WHERE customer.customerId=rental.customerId AND movie.movieId=rental.movieID AND MONTHS_BETWEEN(return_date, rent_date)>=1; |
La sentencia UPDATE
Esta sentencia me va a permitir actualizar valores dentro de los diferentes registros de una tabla, su sintaxis básica es:
| UPDATE tabla SET campo=valor WHERE condición |
La sentencia DELETE
Me va a permitir eliminar registros de una tabla. Su sentencia es:
| DELETE FROM tabla WHERE condición |
Tanto en las sentencias delete, como en las de update es importante que tengamos en cuenta de especificar la cláusula WHERE, porque sino lo que tendremos es que se van a actualizar todos los registros de la tabla.
Las funciones de SQL me van a permitir modificar diferentes datos utilizando estas funciones. Tenemos varios tipos de funciones:
Creación
de tablas
Como
expusimos en nuestro artículo anterior, en Oracle cada estructura de información
se denomina TABLA las cuales, junto a los índices y al diccionario de datos del
sistema, componen la base de datos. Por lo tanto, la creación de las tablas en
el proceso de programación en Oracle juegan un papel muy importante. En el
momento de crear las tablas se definen características a dos niveles: Tabla y
Columna, como se muestra a continuación:
A
nivel de Tabla
Nombre:
Nombre de la tabla puede ser de 1 a 30 caracteres.
Propietario:
La
tabla tiene como propietario al usuario que las crea En nuestro caso somos el
usuario EIDOS. Otro usuario que desee usar nuestras tablas debe tener
autorización para ello y hacer referencia a la tabla como eidos.clientes
(propietario.tabla)
Cantidad
de Columnas:
Una tabla puede tener un máximo de 254 columnas.
A
nivel de Columna
Nombre:
Puede tener de 1 a 30 caracteres.
Tipo
de dato y su ancho
CHAR Máximo de 255. Por defecto 1.
NUMBER Máximo de 105 dígitos. Por defecto 44.
INTEGER Numérico sin decimal. Por defecto 38.
DATE Hasta el 31 de diciembre de 4712.
LONG Tipo caracter con tamaño variable hasta 65535 bytes. Permite una
sola columna LONG por tabla. No se puede usar en subconsultas, funciones o índices.
RAW Dato en binario puro (imágenes y sonido) con un ancho máximo de
255.
LONGRAW Igual que LONG, pero para almacenar datos en binario puro.
Restricciones:
Su función es definir reglas de validación de la columna.
Para
facilitar la continuidad del análisis, usaremos como ejemplo las tablas
definidas en el artículo anterior: Clientes y VENTAS.
La
definición de restricciones al crear las tablas permite establecer
reglas de validación de datos, así como los controles necesarios para mantener
la integridad referencial entre tablas a través de las columnas claves. Las
restricciones que se pueden definir son:
Valor
obligatorio:
En Oracle existe el concepto de valor nulo (NULL), como un valor
indefinido o ausencia de valor y que es diferente al numero 0 o al carácter
espacio. Por lo tanto, para que una columna siempre tenga valor (sea
obligatoria) se define como NOT NULL.
Rango
de valores:
Sirven para chequear que el valor sea mayor a un valor determinado o para
que se encuentre entre dos valores.
Clave
Primaria:
Columnas que identifican de forma única al registro, es un valor único
y no nulo (NOT NULL). Por ejemplo: el código del cliente es una clave
primaria que identifica de forma única e irrepetible a cada cliente.
Clave
Externa:
Columna de la tabla que hace referencia a un valor que tiene que estar
registrado en otra tabla. Por ejemplo: la columna código de la tabla VENTAS es
una clave externa que hace referencia a un valor de la columna código (clave
primaria) de la tabla Clientes.
Destacadas
estas cuestiones veamos, entonces cómo se procede para crear las tablas Clientes
y Ventas.
Tabla
Clientes
Objetivo:
Ficha con datos para identificar al cliente. Consta del código del
cliente (número secuencial), fecha de alta al sistema, nombre, teléfono,
dirección y alguna anotación.
Requisitos:
Se debe identificar a cada cliente con un código único (clave
primaria), registrando su nombre, teléfono y fecha de registro (estos datos son
obligatorios). La dirección y anotaciones son campos opcionales.
Creación
de la tabla:
Ver el fuente 1
Fuente
1
CREATE
TABLE clientes
(
codigo integer
NOT NULL
PRIMARY KEY,
fecha date
NOT NULL,
nombre char(30)
NOT NULL,
telefono char(20) NOT
NULL,
direccion char(100),
anotacion LONG
);
Tabla
Ventas
Objetivo:
Registrar las ventas con al siguiente información: Código del cliente,
fecha de la venta, artículo y valor de la venta.
Requisitos:
El número del cliente es una clave externa que hace referencia a la
columna codigo en la tabla Clientes. En este caso, todos los datos son
obligatorios. Se controla que la columna valor sea mayor a cero.
Creación
de la tabla: ver fuente 2
Fuente
2
CREATE
TABLE ventas
(
codigo
INTEGER
NOT NULL
REFERENCES
clientes(codigo),
fecha
DATE
NOT NULL,
articulo
CHAR(20) NOT
NULL,
valor
NUMBER(10,2) NOT NULL
CHECK
(valor>0)
);
Las
restricciones de Claves Primaria y Clave Externa se definieron a nivel de
columna, pero se pueden definir a nivel de tabla, al final de la misma, como se
muestra en el fuente 3:
Fuente
3
CREATE
TABLE clientes
(codigo
INTEGER
NOT NULL,
nombre
CHAR(30)
NOT NULL,
direccion
CHAR(100),
anotacion
LONG,
PRIMARY
KEY (codigo));
CREATE
TABLE ventas
(codigo
INTEGER
NOT NULL,
fecha DATE
NOT NULL,
articulo CHAR(10),
valor NUMBER(6,2)
NOT NULL
CHECK
(valor>0),
FOREIGN
KEY (codigo) REFERENCES
clientes(codigo));
La
definición de la clave a nivel de tabla es necesaria cuando la misma está
formada por más de una columna.
Unicidad
de la clave con índices
Para
garantizar la unicidad de los valores de la clave primaria de la tabla Clientes
(en la versión 6 donde esta restricción sólo es declarativa y no está
activa), se debe crear un índice que garantice la unicidad de la clave
principal. Un requisito importante para la unicidad de la clave principal es que
las columnas de la clave se definen como NOT NULL.
A
continuación mostraremos cómo crear el índice cliente_codigo para
garantizar la unicidad de la clave primaria:
CREATE
UNIQUE INDEX cliente_codigo
ON
clientes(código);
Secuencias:
codificación numérica
La
codificación numérica del cliente se puede realizar con una secuencia que
automáticamente genera los números enteros en orden ascendente, no siendo
necesario recordar cuál fue el último número asignado ; esto evita la
duplicidad de códigos.
La
secuencia es un objeto que genera valores enteros únicos y se emplean para
crear claves primarias numéricas, con el uso del siguiente mandato:
CREATE
SEQUENCE codigo_cliente
INCREMENT BY 1
START WITH 1;
Para
registrar un nuevo código con la secuencia definida anteriormente se usa la
pseudo-columna codigo_cliente.NEXTVAL, la cual nos dará el siguiente
valor que le corresponde a la secuencia, la forma en que esto se realiza se
explicará más adelante, cuando analicemos el ingreso de datos.
Para
conocer el valor actual de la secuencia, o sea, el último código asignado, se
usa la pseudo-columna codigo_cliente.CURRVAL, desde la tabla
DUAL del sistema, cuyo fin es poder consultar pseudo_columnas (como se
muestra a continuación):
SELECT
user,sysdate,codigo_cliente.currval
FROM
DUAL;
donde:
1.-
user es el nombre del usuario
2.-
sysdate es la fecha del sistema
3.-
codigo_cliente.currval es el último valor asignado a la
secuencia.
Ingreso
de datos
Una
vez creadas las tablas, índices y secuencias, estamos en condiciones de
ingresar datos en la tabla.
El
ingreso, modificación y eliminación de registros se realiza fundamentalmente
con el diseño de pantallas (formularios) desde el módulo SQLFORMS (que
será tema de análisis específico en otro artículo). No obstante, en este artículo
veremos el uso de los mandatos INSERT UPDATE y DELETE.
Para
ingresar un nuevo registro debemos ensayar lo que se muestra en la tabla 1:
|
Nombre
de la Tabla (acciones) |
Columnas |
|
INSERT
INTO CLIENTES |
|
|
VALUES( |
|
|
codigo_cliente.NEXTVAL, |
codigo=
secuencia |
|
'PINTURERIAS
PROPIOS', |
nombre |
|
'45
67 89' |
teléfono |
|
TO_DATE('10/04/95','DD/MM/YY'), |
fecha |
|
'Uruguay
1234', |
dirección |
|
'LIBRERIA' |
anotación |
|
); |
|
Tabla1:
Inserción de nuevos registros
Como
se podrá observar, en este ejemplo no se especificó la lista de columnas a
insertar, lo que indica que se van a ingresar datos para todas las columnas. Por
lo tanto, los valores para cada columna se tienen que ingresar en el orden en
que están definidos en la tabla. Además, es de destacar que la palabra
reservada VALUES indica la lista de valores a ingresar; que los datos
tipo carácter van entre comillas; que la fecha se registra como una cadena de
caracteres usando la función TO_DATE (encargada de transformar la cadena
de caracteres '10/04/95' en fecha, a partir de un formato de fecha especificado
-'DD/MM/YY'-).
También
observamos que a la columna codigo se le asignó el siguiente valor de la
secuencia codigo_cliente (codigo_cliente.NEXTVAL).
En
caso de que sólo se asignaran valores a algunas columnas se debe dar la lista
de columnas como se muestra en el fuente 4 correspondiente a la lista de
columnas.
Fuente
4
INSERT
INTO CLIENTES (codigo,nombre,teléfono,fecha)
VALUES
(codigo_cliente.NEXTVAL,'CASA
AUGE DEPORTES',
'598768',TO_DATE('15/04/95','DD/MM/YY'));
Las
columnas a las que se les ingresa información se listan después del nombre de
la tabla, en el orden deseado. Las columnas no listadas tendrán valor NULL,
por ello todas las columnas definidas como obligatorias (NOT NULL) deben
estar en la lista.
Los
siguientes ejemplos muestran posibles errores y sus correspondientes mensajes en
el registro de datos:
1.-
Falta dato del teléfono que es obligatorio:
INSERT INTO
CLIENTES(codigo,nombre)
VALUES (codigo_cliente.NEXTVAL,
'EMPRESA D'
);
Mensaje
de error:
|
ORA‑01400:
mandatory (NOT NULL) column is missing or NULL during insert. |
2.-
Intento de registrar cliente con código ya existente:
INSERT INTO
CLIENTES(codigo,nombre,teléfono)
VALUES (1,'EMPRESA
TTT','341234');
Mensaje
de error:
|
ORA‑00001:
duplicate key in index |
Obsérvese
en el caso 2 que la secuencia codigo_cliente no fue usada al
ingresar el valor del código, y sí en el caso 1, provocando error de
duplicidad de código. Esto ocurre porque la creación de la secuencia no
garantiza la unicidad del código, ya que podemos registrar un código de
cliente sin su uso. Sin embargo, la unicidad esta garantizada por la
definición del índice único visto anteriormente. Si siempre se usa la
secuencia la unicidad por supuesto que está garantizada, pero la simple
definición de la secuencia no es garantía de su uso.
SQLPlus
Todas
las tareas anteriormente estudiadas se realizan con el módulo SQLPlus de
Oracle, que trabaja en forma interactiva. A continuación enunciaremos los pasos
necesarios para usar SQLPLUS y poder crear tablas, índices o secuencias, así
como insertar datos y obtener listados:
1.-
Llamar al programa
SQLPLUS
2.-
Identificación del usuario
Enter
username: EIDOS
Enter
password:
Si
la identificación es correcta se obtiene mensaje de:
Connected to: ORACLE
Si, por el
contrario, la identificación es incorrecta se recibe el siguiente mensaje:
ERROR: ORA01017:
invalid username/password;
logon denied
3.-
Indicador en pantalla de que SQLPlus está a la espera de la
orden:
SQL>_
4.-
Escribir los mandatos de creación de tablas, índices y secuencia en un
archivo (TABLAS.SQL) con el uso del editor.
SQL>edit tablas
5.-
Ejecutar los mandatos escritos en el archivo TABLAS.SQL
SQL>@tablas
6.-
Para salir de SQLPlus
SQL>exit
Otras
tareas
A
continuación examinaremos una serie de mandatos, a nivel de definición de las
tablas, gracias a los cuales se puede:
1.-
Listar estructura de las tablas (DESCRIBE)
Para
obtener la estructura (descripción de una tabla) el mandato que se debe emplear
es:
| SQL>DESCRIBE clientes; |
con
lo que el resultado será el que se ofrece en la tabla 4.
|
|
Name |
Null? |
Type |
|
|
NUMERO |
NOT
NULL |
NUMBER(38) |
|
|
FECHA |
NOT
NULL |
DATE |
|
|
NOMBRE |
NOT
NULL |
CHAR(30) |
|
|
TELEFONO |
NOT
NULL |
CHAR(20) |
|
|
DIRECCION |
|
CHAR(100) |
|
|
ANOTACION |
|
LONG |
Tabla
4: Resultado del uso del mandato DESCRIBE
2.-
Modificar la estructura de las tablas (ALTER TABLE)
La
modificación de la estructura de las tablas con el uso de ALTER permite:
Añadir
nuevas columnas.
Añadir
restricciones a una columna, en este caso la tabla no debe contener datos.
Modificar
el ancho de la columna.
Modificar
el tipo de datos de la columna sólo si la columna no contiene datos o está
vacía.
Modificar
al tipo LONG sólo una columna sin restricciones.
El
siguiente ejemplo muestra cómo añadir, en la tabla Ventas, las columnas
Factura (para registrar el número de factura) y Cobro (tipo carácter
con 2 posibles valores, N=NO cobrada, NULL=cobrada) y modificar la columna valor
para ampliar su ancho.
ALTER
TABLE ventas
ADD
(
factura
integer,
cobro
char
)
MODIFY
(
valor
number(10,2)
);
3.-
Renombrar las tablas (RENAME)
Para
cambiar el nombre de la tabla Clientes a EMPRESAS se usa el
siguiente mandato:
|
SQL>RENAME
clientes TO empresas; |
4.-
Eliminar una tabla (DROP TABLE)
La
eliminación de la tabla es como sigue:
|
SQL>DROP TABLE
clientes; |
En
este caso se eliminan, también, todos los índices de la tabla.
5.-
Eliminar un índice (DROP INDEX)
| SQL>DROP INDEX cliente_codigo; |
6.-
Consultar las tablas del diccionario.
Toda la información de las tablas está registrada en el diccionario del sistema (Data Dictionary), que son tablas especiales que se crean en la instalación de ORACLE (que son administradas por el sistema). Para consultar la lista de tablas que componen el diccionario se escribe:
|
SQL>HELP DATA DICT |
Gracias
a lo cual se muestra una lista con la información de la tabla 5:
|
|
Nombre
de la tabla |
Descripción |
|
|
ACCESSIBLE_COLUMNS |
columns
of all tables, views, and clusters |
|
|
ACCESSIBLE_TABLES |
tables
and views accessible to the user |
|
|
AUDIT_ACTIONS |
maps
action type numbers to action type names |
|
|
ALL_INDEXES |
descriptions
of indexes on accessible |
|
|
ALL_SEQUENCES |
descriptions
of the user's own sequences |
|
|
ALL_TABLES |
description
of tables accessible to the user |
|
|
..... |
|
|
|
USER_TABLES |
descriptions
of the user's own tables |
|
|
USER_TAB_COLUMNS |
columns
of the user's tables, views, and clusters |
|
|
USER_TAB_GRANTS |
grants
on objects where the user is the owner, grantor, or grantee |
Tabla
5: Consulta de las tablas que componen el diccionario
También
podemos ver la estructura de una tabla del diccionario como se muestra a
continuación:
SQL>DESCRIBE
ALL_TABLES;
SQL>DESCRIBE
all_indexes;
SQL>DESCRIBE
all_sequences;
7.-
Listar
las tablas, índices y secuencias definidas por un usuario
Para
las tablas:
SQL>SELECT
TABLE_NAME "TABLA"
FROM
ALL_TABLES
WHERE
OWNER='EIDOS';
Resultado:
Clientes y Ventas
Para
los índices:
SQL>SELECT
table_name,index_name
FROM
all_indexes
WHERE
owner='EIDOS';
Resultado:
Clientes (con índice Cliente_Nombre y Cliente_Numero) y Ventas
(con índice Venta_Numero)
Para
las secuencias:
SQL>SELECT
sequence_name
FROM
all_sequences
WHERE
sequence_owner='EIDOS';
Resultado:
el nombre de la secuencia usada (SEQUENCE_NAME) Codigo_Cliente
Como
hemos visto, la creación de las tablas constituye el fundamento del diseño de
cualquier sistema a desarrollar en Oracle. Una vez definida las tablas el paso lógico
siguiente es conocer las técnicas para realizar un adecuado uso de la información
contenida en el sistema. Por ello, el próximo artículo lo dedicaremos al
lenguaje de Consulta SQL.