Está en la página 1de 73

EJEMPLOS DE SQL

2008
Los componentes de SQL
El lenguaje SQL se compone de una serie de comandos, clusulas, operadores y funciones agregadas
que se combinan entre ellas para formar las instrucciones necesarias que se ejecutaran utilizando los
correspondientes mtodos de los objetos de acceso a datos, de tal forma que podamos crear, actualizar
y manipular nuestras bases de datos.
A continuacin se enumerarn los distintos componentes que pone a nuestra disposicin el SQL del
motor Microsoft Jet, los cuales se explicarn detalladamente en sus correspondientes apartados dentro
de este manual.

Comandos
Los comandos son aquellas instrucciones que se pueden ejecutar directamente, entendiendo por
instruccin la expresin de consulta SQL generada por el nombre del comando y los restantes
parmetros requeridos por el mismo.
SQL proporciona dos tipos de comandos: los que pertenecen al lenguaje de definicin de datos (DDL) y
los que forman parte del lenguaje de manipulacin de datos (DML). Los primeros permiten crear y
definir nuevas tablas, campos, ndices, usuarios, grupos de trabajo, procedimientos almacenados y
vistas, mientras que los segundos, permiten crear consultas para ordenar, filtrar y extraer los datos de
la base de datos. En las siguientes tablas se detallan las instrucciones de las dos clases comandos
actualmente soportadas por la versin 4.0 del motor de base de datos Microsoft Jet.
Tabla1. Comandos DLL
Comando Descripcin
ADD USER Agrega uno o varios usuarios a un grupo de trabajo. SLO
ADO
ALTER DATABASE Cambia la contrasea de una base de datos. SLO
ADO
ALTER TABLE Modifica el diseo de una tabla, permitiendo asimismo cambiar el tipo de
dato y el tamao de un campo.

ALTER USER Cambia la contrasea de un usuario. SLO
ADO
CREATE GROUP Crea uno o ms grupos de trabajo. SLO
ADO
CREATE INDEX Crea un ndice en una tabla existente.
CREATE
PROCEDURE
Crea un procedimiento almacenado. SLO
ADO
CREATE TABLE Crea una tabla nueva.
CREATE USER Crea uno o varios usuarios. SLO
ADO
CREATE VIEW Crea una nueva vista o consulta. SLO
ADO
DROP GROUP Elimina uno o varios grupos de trabajo. SLO
ADO
DROP INDEX Elimina un ndice existente en una tabla.
1
Prof. : Cesar Arce J.
DROP PROCEDURE Elimina un procedimiento almacenado. SLO
ADO
DROP TABLE Elimina una tabla.
DROP USER Elimina uno o varios usuarios, o quita uno o varios usuarios de un grupo
de trabajo.
SLO
ADO
DROP VIEW Elimina una vista existente. SLO
ADO
EXECUTE Ejecuta un procedimiento almacenado. SLO
ADO
TRANSACTION Comienza y finaliza transacciones explcitas. SLO
ADO

Tabla2. Comandos DML
Comando Descripcin
DELETE Elimna uno o varios registros de la tabla especificada.
INSERT Aade registros por lotes en una nica operacin.
SELECT Selecciona registros que cumplan con un criterio determinado.
UPDATE Actualiza los valores de los campos y registros especificados.

Clusulas
Las clusulas son condiciones de modificacin que se utilizan para definir los datos que deseamos
seleccionar o manipular.
Tabla. Clusulas
Clusula Descripcin
AS Indica un nombre de campo alternativo para el nombre del campo de la tabla o para el
nombre del valor del campo resultante de la llamada a una funcin agregada.
CONSTRAINT Especifica un ndice, y se utiliza para crear o eliminar ndices.
FROM Especifica la tabla de la que se van a seleccionar los registros.
GROUP BY Separa los registros seleccionados en grupos especficos.
HAVING Expresa la condicin que debe satisfacer cada grupo.
ORDER BY Ordena los registros seleccionados de acuerdo con un orden especificado.
PROCEDURE Define un nombre y parmetros opcionales de una consulta.
WHERE Especifica las condiciones que deben cumplir los registros que se van a seleccionar.

Operadores
Existen dos tipos de operadores en SQL: operadores lgicos y operadores de comparacin.
2
Prof. : Cesar Arce J.
Operadores l!icos
Los operadores lgicos se utilizan para evaluar expresiones, generalmente dentro de una clusula
WHERE.
Operador Descripcin
AND Es el " lgico. Evala dos condiciones, devolviendo un valor verdadero slo si las dos
condiciones son ciertas.
NOT Negacin lgica. Devuelve el valor contrario de la expresin.
OR Es el o lgico. Evala dos condiciones, devolviendo un valor verdadero si alguna de las
dos condiciones es cierta.
#$emplos
SELECT * FROM Alumnos WHERE Nombre = 'Juan' AND Edad = 23
Devolver todos los registros de los alumnos cuyo nombre sea Juan y tengan 23 aos de edad.
SELECT * FROM Alumnos WHERE Nombre = 'Juan' OR Edad = 23
Devolver todos los registros de los alumnos cuyo nombre sea Juan, o que tengan 23 aos de edad,
aunque no se llamen Juan.
SELECT * FROM Alumnos WHERE Nombre = 'Juan' AND NOT Edad = 23
Devolver todos los registros de los alumnos cuyo nombre sea Juan pero que su edad sea distinta a 23
aos.
Operadores de comparacin
Los operadores de comparacin se utilizan para comparar valores relativos de dos expresiones con el fin
de determinar la accin que debe ejecutarse.
Operador Descripcin
< Menor que.
<= Menor o igual que.
> Mayor que.
>= Mayor o igual que.
= Igual que.
<> Distinto de.
BETWEEN Se utiliza para especificar un intervalo de valores.
IN Se utiliza para especificar registros de una base de datos.
LIKE Se utiliza en la comparacin de modelos.
#$emplos
SELECT * FROM Alumnos WHERE Nombre = 'Juan'
Devolver todos los registros de los alumnos cuyo nombre sea Juan
SELECT * FROM Alumnos WHERE Apellidos BETWEEN 'Ma%' AND 'Mu%'
Devolver todos los registros de los alumnos cuyos Apellidos estn comprendidos entre las slabas 'Ma' y
'Mu'
SELECT * FROM Alumnos WHERE IdAlumno IN (39, 75, 139, 264)
Devolver los registros de los alumnos cuyo identificador corresponda con el conjunto de valores
especificados
SELECT * FROM Alumnos WHERE Nombre LIKE 'Ma%'
Devolver todos los registros de los alumnos cuyo Nombre empiece por la slaba 'Ma'
3
Prof. : Cesar Arce J.

%unciones a!re!adas
Las funciones agregadas se utilizan dentro de una clusula SELECT en grupos de registros para devolver
un nico valor que se aplica a un grupo de registros.
%uncin a!re!ada Descripcin
AVG Devuelve el promedio de los valores de un determinado campo.
COUNT Devuelve el nmero de registros de la seleccin.
FIRST Devuelve el valor del campo del primer registro del conjunto de resultados obtenido.
LAST Devuelve el valor del campo del ltimo registro del conjunto de resultados obtenido.
MAX Devuelve el valor ms alto de un campo especificado.
MIN Devuelve el valor ms bajo de un campo especificado.
STDEV Devuelve una estimacin de la desviacin estndar de una muestra de poblacin
representada como un conjunto de valores contenidos en un campo especificado de
una consulta.
STDEVP Devuelve una estimacin de la desviacin estndar de una poblacin representada
como un conjunto de valores contenidos en un campo especificado de una consulta.
SUM Devuelve la suma de todos los valores de un determinado campo.
VAR Devuelve la estimacin de la varianza de una muestra de poblacin representada
como un conjunto de valores contenidos en un campo especificado de una consulta.
VARP Devuelve la estimacin de la varianza de una poblacin representada como un
conjunto de valores contenidos en un campo especificado de una consulta.
#$emplos
SELECT COUNT (IdFactura) FROM Facturas WHERE IdCliente = 10251
Devolver el nmero de facturas pertenecientes al cliente cuyo identificador es el 10251
SELECT AVG(Total) AS [Valor Promedio] FROM Facturas WHERE IdCliente = 10251
Devolver en el campo 'Valor Promedio' el valor del promedio total de las facturas pertenecientes al
cliente especificado
SELECT SUM(Total) FROM Facturas WHERE IdCliente = 10251
Devolver la suma del importe total facturado a un cliente
SELECT MAX(Total) AS [Importe Mayor], MIN(Total) AS [Importe Menor] FROM Facturas WHERE
IdCliente = 10251
Devolver en el primer campo el importe de la factura mayor, y en el segundo campo, el importe de la
factura menor del cliente especificado

Cap&tulo ''. Tipos de datos del len!ua$e SQL del motor
Microso(t )et


Descargar (103
KB)

4
Prof. : Cesar Arce J.
Contenido
Tipos de datos del motor Microso(t )et
Datos carcter
Datos num*ricos
Datos enteros
#l tipo de dato Autonum*rico
Datos decimales
Datos apro+imados
Datos monetarios
Datos de (ec,a " ,ora
Datos binarios
Datos para ob$etos OL#
Datos -OOL#A.
Datos /0'D

Tipos de datos del motor Microso(t )et
A la hora de crear una tabla, es importante definir el tipo de dato que utilizarn las columnas o campos
para almacenar los valores de la tabla, a fin de asegurarse que usan la mnima cantidad posible de
espacio de almacenamiento.
Los tipos de datos del SQL del motor de base de datos Microsoft Jet se compone de una serie de datos
primarios definidos por el propio motor, y de varios tipos de datos sinnimos reconocidos por aqullos.
La siguente tabla enumera los tipos de datos del SQL del motor Microsoft Jet, sus sinnimos y los tipos
de datos equivalentes en Microsoft SQL Server y en el estndar SQL de ANSI:
SQL )et Sinnimos SQL Ser1er SQL A.S'
BINARY VARBINARY, BINARY VARYING BINARY, VARBINARY BIT, BIT VARYING
BIT LOGICAL, LOGICAL1, YESNO BIT No admitido
TINYINT INTEGER1, BYTE TINYINT No admitido
COUNTER AUTOINCREMENT, IDENTITY No admitido
MONEY CURRENCY MONEY No admitido
DATETIME DATE, TIME, TIMESTAMP DATETIME DATE, TIME, TIMESTAMP
UNIQUEIDENTIFIER GUID UNIQUEIDENTIFIER No admitido
DECIMAL NUMERIC, DEC DECIMAL DECIMAL
REAL SINGLE, FLOAT4, IEEESINGLE REAL REAL
FLOAT DOUBLE, FLOAT8,
IEEEDOUBLE, NUMBER
FLOAT DOUBLE PRECISION, FLOAT
SMALLINT SHORT, INTEGER2 SMALLINT SMALLINT
INTEGER LONG, INT, INTEGER4 INTEGER INTEGER
IMAGE LONGBINARY, GENERAL,
OLEOBJECT
IMAGE No admitido
TEXT LONGTEXT, LONGCHAR,
MEMO, NOTE, NTEXT
TEXT No admitido
5
Prof. : Cesar Arce J.
CHAR TEXT (n), ALPHANUMERIC,
CHARACTER, STRING,
VARCHAR, NCHAR,
CHARACTER VARYING,
NATIONAL CHAR,
NATIONAL CHARACTER,
NATIONAL CHARACTER
VARYING,
NATIONAL CHAR VARYING
CHAR, VARCHAR,
NCHAR, NVARCHAR
CHARACTER,
CHARACTER VARYING,
NATIONAL CHARACTER,
NATIONAL CHARACTER
VARYING
No admitido No admitido INTERVAL


Datos carcter
Los datos carcter consisten en secuencias de caracteres alfanumricos utilizados para representar
cualquier combinacin de nmeros y letras, o para almacenar nmeros que no se utilicen para efectuar
clculos. La siguiente tabla resume los tipos de datos carcter.
Tipo de dato Descripcin
char, character, nchar,
national char, national
character
Para datos carcter de longitud fija de hasta 255 caracteres. Si no se especifica
el nmero de carcteres, el tamao del campo ser de 255 caracteres. El
tamao de almacenamiento en bytes siempre ser el doble del tamao
definido. Si el tamao del campo es de 25 caracteres, el tamao de
almacenamiento siempre ser de 50 bytes, aunque los datos de la columna
tengan 5 caracteres.
Este tipo de dato es apropiado cuando todos los valores del campo tengan la
misma longitud o se aproximen lo suficiente.
alphanumeric, character
varying, national char
varying, national
character varying,
string, text (n), varchar
Para datos carcter de longitud variable de hasta 255 caracteres. Si no se
especifica el nmero de carcteres, el tamao del campo ser de 255
caracteres. El tamao de almacenamiento en bytes ser el doble del tamao
real. Si el tamao del campo es de 25 caracteres, y los datos de la columna
ocupan 5 caracteres, el tamao de almacenamiento ser de 10 bytes.
Este tipo de dato es apropiado cuando exista una sustancial diferencia de
longitud entre los distintos valores del campo.
longtext, longchar,
memo, note, ntext, text
Para datos carcter de longitud variable de hasta un mximo de 65.536
caracteres, salvo que el campo no contega datos binarios, en cuyo caso el
lmite se encuentra en el tamao de la base de datos (aproximadamente 2.14
gigabytes 1.070,000.000 de caracteres Unicode). El tamao de
almacenamiento en bytes ser el doble del tamao real de los datos
almacenados en el campo.
Este tipo de dato se utiliza para almacenar texto de gran longitud, como bien
puede ser notas o descripciones.
Todos los sinnimos anteriores de tipos de datos slo se pueden especificar cuando se utilice ADO junto
con el proveedor Jet OLE DB 4.0. Si utilizamos la biblioteca de DAO 3.6, o la interfaz de usuario de
Microsoft Access, solamente podremos utilizar los sinnimos siguientes:
Caracteres de longitud fija: CHAR
Caracteres de longitud variable: ALPHANUMERIC, STRING, TEXT, TEXT (n), VARCHAR
6
Prof. : Cesar Arce J.
Cadenas de caracteres largos: LONGTEXT, LONGCHAR, MEMO, NOTE
Si abrmos la tabla en modo de diseo utilizando la interfaz de usuario de Microsoft Access, todos los
campos de longitud fija y variable aparecern con el tipo de dato Te+to, por lo que no tendremos
posibilidad de diferenciar el tipo de longitud de unos y otros campos. Para diferenciar la longitud
tendremos que abrir la tabla, donde observaremos que aparecer sealada toda la celda de la cuadrcula
correspondiente a los campos de longitud fija, estando solamente sealados los datos de las celdas en
los campos de texto de longitud variable, tal y como se puede apreciar en las siguientes imgenes.
Referente a los tipos de datos de caracteres largos, cualquier sinnimo que utilicemos para crear o
modificar el tipo de dato del campo, en la vista de diseo de la interfaz de usuario de Microsoft Access
aparecern con el tipo de dato Memo.
Si desea comprobar ciertas propiedades de los campos (tamao definido, de almacenamiento, etc.),
puede ejecutar el siguiente ejemplo, siempre y cuando utilice la biblioteca de ADO:
Dim rst As ADODB.Recordset
Dim fld As ADODB.Field
' Creamos un nuevo objeto Recordset
'
Set rst = New ADODB.Recordset
With rst
.CursorType = adOpenKeyset
.LockType = adLockOptimistic
.Open "Tabla1", oConexion, , , adCmdTable
End With
' Leemos, campo a campo, todos los registros de la tabla
'
Do
For Each fld In rst.Fields
MsgBox "Tamao definido: " & fld.DefinedSize & " bytes." & vbCrLf & _
"Nmero de caracteres: " & Len(fld.Value) & vbCrLf & _
"Tamao de almacenamiento: " & fld.ActualSize & " bytes." & vbCrLf & _
"Tipo de dato: " & fld.Type, , fld.Name & ": " & fld.Value
Next
rst.MoveNext
Loop Until rst.EOF


Datos num*ricos
Los datos numricos slo consisten en nmeros que pueden ser utilizados para realizar clculos
aritmticos. Al definir un tipo de dato numrico establecemos el nmero de bytes que se usarn para
guardar los datos, lo que afectar a la precisin del nmero guardado en el campo.
Al igual que los restantes tipos de datos, los numricos tambin disponen de un nmero de sinnimos
que podemos utilizar a la hora de definir el tipo de dato, el cual deber de ser elegido dependiendo de si
la tabla permanecer en una base de datos Jet (Microsoft Access) o ser escalada a un servidor de bases
7
Prof. : Cesar Arce J.
de datos, como bien puede ser Microsoft SQL Server. En este ltimo caso, deber de utilizar un nombre
compatible en la declaracin del tipo de dato para hacer ms fcil el cambio.
Podemos definir los tipos de datos numricos en varias categoras dependiendo de la forma de
representar los nmeros.
Datos enteros
Estos tipos de datos representan exclusivamente valores numricos completos, sin decimal alguno,
teniendo la mayora de ellos la capacidad de representar tanto valores positivos como negativos. Los
tipos de datos se diferencian principalmente en la magnitud del nmero que pueden representar, lo que
afectar al tamao de almacenamiento que ocupar el valor de la columna. Por regla general se debera
de utilizar el tipo de dato ms pequeo posible, poniendo especial cuidado en especificar un tamao
suficiente a fin de que los posibles valores del campo no queden fuera del intervalo del rango permitido
por el tipo de dato declarado. La siguiente tabla lista los tipos de datos numricos enteros.
Tipo de dato Descripcin
tinyint, integer1, byte
Para valores enteros positivos en el intervalo de 0 a 255. Cada valor de la
columna ocupa un byte.
smallint, short, integer2
Para valores enteros cortos en el intervalo de -32.768 a 32.767. Cada valor
ocupa dos bytes.
integer, long, int,
integer4
Para valores enteros largos en el rango de -2.147.483.648 a 2.147.483.647.
Cada columna ocupa cuatro bytes.
counter, autoincrement,
identity
Para valores en el mismo rango que los tipos de datos enteros largos, y slo
para campos definidos como utonum!ricos. Cada columna ocupa cuatro bytes.
Slo se puede definir en la tabla un campo utonum!rico.
Todos los tipos de datos indicados podemos declararlos para ser ejecutados con la biblioteca de DAO
3.6, as como desde la interfaz de usuario de Microsoft Acess, salvo los tipos de datos TINYINT e
IDENTITY, que slo se podrn utilizar con ADO y el proveedor Jet OLE DB 4.0.

#l tipo de dato Autonum*rico
El tipo de dato COUNTER se utiliza para definir un valor numrico entero largo en una columna que se
autoincrementar en cada nuevo registro, teniendo la posibilidad de especificar el valor de inicio y el de
incremento a la hora de crear el campo, tal y como se muestra en el siguiente ejemplo, donde se crear
un campo Autonum*rico de valor inicial 10, incrementndose en 5 unidades por cada nuevo registro
que se aada a la tabla:
CREATE TABLE TablaAutoincrementada (
CampoIncremento IDENTITY (10,5),
Campo2 CHAR
)
Si no se especifica el valor de inicio y de incremento, ambos valores tendrn por defecto el valor 1. Slo
podr tener un campo COUNTER en la tabla.
Si utiliza el proveedor Jet OLE DB, tambin puede utilizar el sinnimo IDENTITY para declarar un tipo
de dato Autonum*rico, en cuyo caso ser compatible con el tipo de dato IDENTITY de SQL Server.
En versiones previas de bases de datos Access, el valor de inicio del campo Autonum*rico se
reinicializaba al valor mximo disponible despus de compactar la base de datos. Esto ya no contina
siendo cierto con la versin 4.0 del motor Microsoft Jet, porque para reinicializar el contador, habra que
eliminar primero los registros de la tabla y compactar la base de datos despus. Una solucin viable
8
Prof. : Cesar Arce J.
sera ejecutar una consulta de modificacin de campo mediante el proveedor Jet OLE DB, para indicar el
nuevo valor de inicio y de incremento, tal y como se muestra en el siguiente ejemplo:
ALTER TABLE Clientes ALTER COLUMN IdCliente IDENTITY (10,5)
El siguiente registro que se aada a la tabla Clientes, el campo IdCliente tendr el valor de 10,
incrementndose en cinco unidades los valores de los siguientes registros que posteriormente se
agregen a la tabla.
La variable @@IDENTITY es una variable SQL genrica que nos puede ser til para conocer el ltimo
valor introducido en un campo del tipo Autonum*rico, con las siguientes peculiaridades:
Se debe de utilizar junto con la instruccin SELECT sin especificar en ningn caso el nombre de
la tabla;
Para obtener el valor, la consulta siempre se deber de ejecutar inmediatamente despus de
haber aadido un nuevo registro a la tabla mediante cdigo;
Para aadir un valor al resultado de la variable @@IDENTITY, encierre la variable entre
corchetes;
Por ltimo, dicha variable nicamente se puede utilizar con el proveedor Jet OLE DB y la
biblioteca de ADO.
El siguiente ejemplo muestra la utilizacin de la variable global @@IDENTITY:
' Aadimos un nuevo registro a nuestra tabla de Clientes, donde el campo
' IdCliente es del tipo Autonumrico
'
INSERT INTO Clientes (Nombre, Domicilio) VALUES ('Federico Lpez', 'C:\Nueva, 25')
' Leemos el valor aadido al campo IdCliente, por lo que ser necesario
' abrir un objeto ADODB.Recordset
'
Dim oRst As New ADODB.Recordset
oRst.Open "SELECT @@IDENTITY As Ultimo_Cliente", _
oCnn, , , adCmdText
' Leemos el valor
MsgBox oRst.Fields!Ultimo_Cliente
Si por ejemplo, deseamos guardar en una variable el siguiente valor del campo, le aadiramos el valor
del incremento que dispone nuestro campo Autonum*rico. Suponiendo que el incremento es de cinco
unidades, ejecutaramos la siguiente consulta SQL:
Dim lngSiguienteCliente As Long
oRst.Open "SELECT [@@IDENTITY] + 5 As Proximo_Cliente", oCnn, , , adCmdText
lngSiguienteCliente = oRst.Fields!Proximo_Cliente


Datos decimales SLO ADO
A esta categora de datos pertenecen los tipos de datos DECIMAL y sus sinnimos NUMERIC y DEC,
permitindose nicamente su declaracin para ser ejecutada con la biblioteca de ADO y el proveedor Jet
OLE DB 4.0, ya que desde la interfaz de usuario de Microsoft Access o la biblioteca de DAO 3.6, el nico
nombre de tipo de dato permitido (NUMERIC) crea un campo numrico del tipo DOUBLE.
9
Prof. : Cesar Arce J.
Al igual que en los tipos de datos enteros, el tipo de datos decimal representa valores de forma exacta,
con las siguientes diferencias respecto de los valores enteros:
Los tipos de datos decimales permiten especificar valores decimales, cosa que no permiten los
valores enteros.
El tipo de dato decimal permite una precisin variable, lo que significa que el nmero total de
dgitos (tanto a la derecha como a la izquierda del punto decimal), puede variar entre uno y 28.
Por defecto, la precisin es de 18.
Igualmente permite designar una escala variable, que vendr a representar los dgitos que
aparecern a la derecha del separador decimal. Por defecto, el valor de la escala es cero, y
nunca puede ser inferior a cero o superior al valor definido para la precisin.
Siendo la precisin p y la escala e, el rango de valores permitidos estara representado por la siguiente
expresin:
2 3 e 3 p 3 24
A la hora de declarar el tipo de dato decimal podemos especificar la precisin y escala, y en este mismo
orden, encerrando sus valores entre parntesis y separados ambos por una coma, tras el nombre del
tipo de dato:
CREATE TABLE TablaDecimal (
CampoDecimal DECIMAL (20,2)
)
Por ltimo indicar que, segn la documentacin oficial existente al respecto, el tamao de
almacenamiento de los tipos de datos decimal es de 17 bytes, si bien, al ejecutar el ejemplo
anteriormente mencionado, el tipo de dato del campo arroja un tamao de almacenamiento de 19 bytes.
Datos apro+imados
Los tipos de datos numricos vistos con anterioridad representan los datos de una manera precisa, lo
que en gran medida evita los errores de redondeo. Aunque la precisin de los tipos de datos
aproximados es muy cercana al valor exacto, dicha disminucin se realiza a costa de ofrecer un mayor
rango de intervalo de datos posible que los ofrecidos por los tipos de datos enteros y decimales. La
siguiente tabla lista los tipos de datos numricos aproximados, cuyos nombres pueden ser todos
especificados para ser ejecutados tanto por la biblioteca de ADO como por la de DAO, as como desde la
interfaz de usuario de Microsoft Access.
Tipo de dato Descripcin
real, single, float4,
ieeesingle
Para valores de datos aproximados de coma flotante de precisin simple con un
intervalo comprendido entre -3,402823E38 y -1,401298E-45 para valores
negativos, y entre 1,401298E-45 y 3,402823E38 para valores positivos. El
tamao de almacenamiento es de 4 bytes.
float, double, float",
ieeedouble, number
Para valores de datos aproximados de coma flotante de precisin doble con un
intervalo comprendido entre -1,79769313486231E308 y -4,94065645841247E-
324 para valores negativos, y entre 4,94065645841247E-324 y
1,79769313486231E308 para valores positivos. El tamao de almacenamiento
es de 8 bytes.


10
Prof. : Cesar Arce J.
Datos monetarios
A esta categora de datos pertenece el tipo de dato MONEY y su sinnimo CURRENCY, los cuales pueden
ser especificados para ser ejecutados tanto por la biblioteca de ADO como por la de DAO, as como
desde la interfaz de usuario de Microsoft Access.
Los tipos de datos monetarios comprenden valores de moneda y datos numricos utilizados en clculos
matemticos en los que estn implicados datos que contengan entre uno y cuatro decimales, y se
encuentren comprendidos entre 922.337.203.685.477,5807 y - 922.337.203.685.477,5808. La precisin
es de hasta 15 dgitos a la izquierda del separador decimal y hasta 4 dgitos a la derecha del mismo. Su
tamao de almacenamiento es de 8 bytes.
Cuando se introducen valores en el tipo de dato monetario, se puede utilizar un smbolo de moneda y un
punto decimal, pero procure no introducir una coma como valor decimal: utilice 1234.5678 C en lugar de
1.234,5678 C.


Datos de (ec,a " ,ora
A esta categora de datos pertenecen los tipos de datos DATETIME y sus sinnimos DATE, TIME y
TIMESTAMP, los cuales pueden ser utilizados con las bibliotecas de ADO y DAO, as como desde la
interfaz de usuario de Microsoft Access.
Comprenden valores de fecha y hora dentro del intervalo comprendido entre el 01/01/100 y el
31/12/9999, siendo su tamao de almacenacimiento de 8 bytes.


Datos binarios
Los datos binarios se utilizan para representar datos en su formato binario nativo. La siguiente tabla lista
los tipos de datos binarios y sus sinmicos, teniendo en cuenta que el tipo BINARY VARYING slo se
puede especificar si se utiliza la biblioteca de ADO:
Tipo de dato Descripcin
binary
Para datos binarios de longitud fija de hasta 510 bytes de longitud. Se utiliza
BINARY(n) para definir el tamao, donde n es el nmero de bytes. Su tamao
de almacenamiento es de n bytes. Apropiado cuando todos los campos tienen
la misma longitud.
varbinary, binary
varying
Para datos binarios de longitud variable de hasta 510 bytes de longitud. Se
utiliza VARBINARY(n) para definir el tamao, donde n es el nmero mximo de
bytes. El tamao de almacenamiento es de n bytes. Apropiado cuando todos los
valores de los campos tengan diferente longitud.
El tipo de dato binario no est disponible en la interfaz de usuario de Microsoft Access, por lo que tendr
que ejecutar una consulta SQL de creacin o modificacin de tabla, si desea tener un campo con dicho
tipo de dato.
11
Prof. : Cesar Arce J.
Se puede almacenar cualquier tipo de datos en un campo binario, teniendo en cuenta que los datos
almacenados en el mismo no se puede traducir a otro tipo de dato como bien podra ser a un tipo de
dato de texto. La forma en que se introducen los datos en un campo binario indica cmo aparecern al
mostrarlos.
Si exportamos los datos de la tabla a un archivo de texto, podremos observar la diferencia entre utilizar
el tipo de dato BINARY (datos de longitud fija) y VARBINARY (datos de longitud variable):
En el primer ejemplo, se ha ejecutado las siguientes consultas SQL, produciendo el resultado indicado:
CREATE TABLE Tabla1 (Campo1 BINARY (20), Campo2 VARCHAR (18))
INSERT INTO Tabla1 VALUES ('Binario1', 'Primer registro')
INSERT INTO Tabla1 VALUES ('Binario2', 'Segundo registro')
Campo1;Campo2
42 00 69 00 6E 00 61 00 72 00 69 00 6F 00 31 00 00 00 00 00 ;Primer registro
42 00 69 00 6E 00 61 00 72 00 69 00 6F 00 32 00 00 00 00 00 ;Segundo registro
En el segundo, las siguientes consultas:
CREATE TABLE Tabla2 (Campo1 VARBINARY (20), Campo2 VARCHAR (18))
INSERT INTO Tabla2 VALUES ('Binario1', 'Primer registro')
INSERT INTO Tabla2 VALUES ('Binario2', 'Segundo registro')
Campo1;Campo2
42 00 69 00 6E 00 61 00 72 00 69 00 6F 00 31 00 ;Primer registro
42 00 69 00 6E 00 61 00 72 00 69 00 6F 00 32 00 ;Segundo registro
Como podr observar, a pesar que los dos campos binarios tienen la misma longitud (20), al utilizar
BINARY el campo se rellenar de pares de ceros hasta completar el tamao definido, lo que no sucede
si especificamos VARBINARY.


Datos para ob$etos OL#
A esta categora de datos pertenecen los tipos de datos IMAGE y sus sinnimos LONGBINARY, GENERAL
y OLEOBJECT, los cuales pueden ser utilizados con las bibliotecas de ADO y DAO, as como desde la
interfaz de usuario de Microsoft Access.
Los tipos de dato Objeto OLE se utilizan para guardar objetos binarios largos, como documentos de
Word u hojas de clculo Microsoft Excel, as como archivos grficos. El tamao mximo puede llegar
hasta 2.14 gigabytes.


Datos -OOL#A.
El tipo de dato BIT se utiliza para representar datos Verdadero/Falso o S/No, siendo sus sinnimos BIT,
LOGICAL y LOGICAL1, nombres estos que pueden ser utilizados con las bibliotecas de ADO y DAO o
desde la interfaz de usuario de Microsoft Access. Un valor Verdadero es equivalente a -1 mientras que
un valor Falso es igual a 0, o dicho de otra manera: todo valor numrico distinto de 0 es Verdadero. El
tamao de almacenamiento es de 1 byte.

12
Prof. : Cesar Arce J.

Datos /0'D
El tipo de dato UNIQUEIDENTIFIER y su sinnimo GUID (este ltimo slo se puede utilizar con
Microsoft Access o con la biblioteca de DAO), indica un nmero de identificacin global nico de 16
bytes, utilizado en una base de datos de Access para establecer un identificador exclusivo para la
replicacin. Los GUID se utilizan para identificar rplicas, conjuntos de rplicas, tablas, registros y otros
objetos. En una base de datos de Access, los GUID se denominan Id. de rplica.
Se puede especificar un valor UNIQUEIDENTIFIER como una cadena de 32 caracteres hexadecimales,
segn el siguiente formato: {12345678-90AB-CDEF-1234-567890ABCDEF}.
Para generar un valor GUID puede utilizar la funcin API CoCreate/uid, donde puede encontrar un
ejemplo en el siguiente artculo de la Base del Conocimiento: Cmo 0sar la A5' CoCreate/0'D para
/enerar un /0'D con 6-.
Si lo desea, tambin le puede servir el valor devuelto por la siguiente funcin:
Private Function GenerarGUID(ByVal iLongitud As Integer) As String
Dim x As Integer, strGUID As String
Const strValidar = "0123456789ABCDEF"
Randomize Timer
For x = 1 To iLongitud
strGUID = strGUID & Mid(strValidar, Int(Rnd(1) * Len(strValidar)) + 1, 1)
Next
GenerarGUID = strGUID
End Function
Para llamar a la funcin utilizaramos la siguiente sintaxis:
Dim strTemp As String
' Generamos el GUID
strTemp = GenerarGUID (8) & "-" & _
GenerarGUID (4) & "-" & _
GenerarGUID (4) & "-" & _
GenerarGUID (4) & "-" & _
GenerarGUID (12)
' Encerramos la cadena entre llaves
strTemp = "{" & strTemp & "}"
' Mostramos el resultado
MsgBox strTemp
Cap&tulo '''. Cmo crear7 modi(icar7 copiar " eliminar
tablas


Descargar (156 KB)

Contenido
13
Prof. : Cesar Arce J.
'ntroduccin
Crear una tabla
Modi(icar la estructura de una tabla
A8adir nue1os campos a la tabla
Modi(icar el tipo de dato de un campo
#liminar un campo de la tabla
Copiar una tabla
#liminar una tabla

'ntroduccin
Las tablas constituyen la espina dorsal de una base de datos porque sern ellas las encargadas de
almacenar los datos, por lo que es fundamental que las mismas se encuentren bien diseadas a fin de
garantizar que el mantenimiento de la base de datos en su conjunto se realice de una manera fcil.
En el captulo anterior se describieron los distintos tipos de datos que podemos utilizar con el lenguaje
SQL del motor Microsoft Jet. En este captulo se ver como aplicar los tipos de datos a la creacin de una
tabla, y se estudiarn las sentencias y reglas sintcticas del lenguaje SQL para crear y modificar el
diseo de las mismas, dejando para un captulo posterior el estudio por separado de otra parte muy
importante de la estructura de una tabla, como puede ser la encargada de crear los ndices.
Por ltimo, en este mismo captulo tambin se abordar los temas relacionados con las operaciones del
lenguaje de definicin de datos de SQL encargadas de copiar y eliminar tablas de una base de datos,
tanto nativas como procedentes de otros orgenes de datos a los que el motor Microsoft Jet puede tener
acceso mediante los controladores ISAM instalables correspondientes.

Crear una tabla
Utilizando la instruccin CREATE TABLE del lenguaje de definicin de datos del motor Microsoft Jet,
podemos crear nuevas tablas, tanto en bases de datos Microsoft Access como en otros formatos de
bases de datos de escritorio, como por ejemplo, archivos de dBASE, Excel y de Texto delimitado. Para
estos ltimos formatos necesitaremos tener instalado en nuestro sistema el controlador ISAM instalable
correspondiente con el archivo que deseamos crear, con la nica limitacin de que no se podr
especificar ningn tipo de ndices a la hora de ejecutar la consulta SQL de creacin de tabla.

Sinta+is
CREATE TABLE tabla (
campo1 tipo [(tamao)] [WITH COMPRESSION | WITH COMP] [NOT NULL | NULL] [DEFAULT
valor#efecto1] [$ndice1]
[, campo2 tipo [(tamao)] [WITH COMPRESSION | WITH COMP] [NOT NULL | NULL] [DEFAULT
valor#efecto2] [$ndice2]
[, ...]]
[,CONSTRAINT $ndice%m&ltiples%campos[,...]]
)

5armetro Descripcin
tabla El nombre de la tabla que deseamos crear.
campo1, campo2 El nombre de los campos que se van a crear. Al menos debe de crearse
14
Prof. : Cesar Arce J.
un campo.
tipo El tipo de dato que tendr el campo de la nueva tabla.
tamao
El tamao del campo en caracteres slo para los campos de tipo texto
carcter o BINARY.
WITH COMPRESSION | WITH
COMP
SLO ADO
Atributo opcional que implica comprimir a caracteres de un solo byte
(SBCS) los caracteres Unicode. Slo se puede utilizar con los tipos de
datos CHARACTER y MEMO, as como por sus sinnimos. Se puede utilizar
cualquiera de las dos palabras reservadas indicadas, siempre y cuando
precedan al atributo NOT NULL | NULL, en el supuesto de que se
especifique este atributo.
NOT NULL | NULL
De utilizarse significa que el campo es requerido, por lo que se exige que
los nuevos registros tengan datos vlidos en el campo. Este parmetro es
opcional y su valor por defecto es NULL.
DEFAULT
SLO ADO
Establece el valor por defecto que tendr el campo para los nuevos
registros que se creen. Este parmetro es opcional, pero si se especifica,
deber de aparecer al final de la declaracin del campo. El valor por
defecto indicado deber corresponderse con el tipo de dato declarado.
$ndice1, $ndice2
Una clusula CONSTRAINT que define un ndice de un solo campo,
seguido del nombre del ndice. Este parmetro es opcional.
$ndice%m&ltiples%campos
Una clusula CONSTRAINT que define un ndice de mltiples campos,
seguido del nombre, tipo de ndice y campos que lo forman. Este
parmetro es opcional.

Comentarios
La instruccin CREATE TABLE se utiliza como argumento del mtodo #+ecute de un objeto Database
abierto (biblioteca de DAO) o de un objeto Connection (biblioteca de ADO), as como por el mtodo
#+ecute.onQuer" de un objeto OleDbConnection del espacio de nombre S"stem.Data.OleDb de
ADO .NET, y su objetivo es crear una nueva tabla en la base u origen de datos especificado, siempre y
cuando se incluya en la consulta de creacin de tabla la sintaxis adecuada para crear al menos un campo
en la misma.
Si cualquier nombre de tabla, campo o ndice est formado por varias palabras separadas, o estas
contienen signos de puntuacin, necesariamente debern de incluirse entre corchetes [ ] a fin de evitar
el correspondiente error de sintaxis en la instruccin CREATE TABLE, lo que tambin es vlido para
cualquier otra instruccin SQL.
Se ha aadido el atributo WITH COMPRESSION para las columnas de caracteres debido al soporte de
estos campos para los caracteres Unicode, los cuales requieren siempre dos bytes para cada carcter. Al
convertir al formato Microsoft Jet versin 4.0 las bases de datos creadas con anterioridad que contengan
principalmente datos de tipo carcter, el tamao del archivo de la base de datos puede aumentar el
doble al convertirse al nuevo formato de Jet 4.0. Sin embargo, la representacin Unicode de muchos
juegos de caracteres, denominados anteriormente juegos de caracteres de un solo byte (SBCS), puede
comprimirse fcilmente a caracteres de un solo byte. Por tanto, si definimos una columna tipo
CHARACTER con el atributo WITH COMPRESSION, los datos se comprimirn automticamente cuando
se almacenen, y se descomprimirn cuando se recupere el dato de la columna. Indicar que este atributo
slo se puede especificar cuando utilicemos ADO y el proveedor Jet OLE DB 4.0 para definir la estructura
de la tabla.
Las columnas tipo MEMO tambin pueden ser definidas para que almacenen datos en formato
comprimido, con la excepcin de que slo se comprimirn aquellos datos de la columna que una vez
comprimidos ocupen 4.096 bytes o menos, no comprimindose el resto del campo MEMO que supere
15
Prof. : Cesar Arce J.
dicha cifra, por lo que se puede dar el caso de que en un campo MEMO existan datos comprimidos y no
comprimidos.
El atributo NOT NULL indica que el campo es requerido, por lo que no se podr aadir un nuevo registro
a la tabla si no se especifica un valor para el campo. El valor por defecto para todos los campos es NULL
(no requerido), y su declaracin es opcional.
La versin 4.0 del motor Microsoft Jet ha introducido la palabra reservada DEFAULT, con la cual se
puede establecer el valor predeterminado que tendr el campo, de tal forma que dicho valor aparecer
automticamente en el campo cuando se cree un nuevo registro. El atributo DEFAULT deber de
incluirse al final de la declaracin del campo y su valor se deber de corresponder con el tipo de dato
declarado para el campo. Slo se puede utilizar DEFAULT con la biblioteca de ADO y por tanto, con el
proveedor Microsoft Jet OLE DB 4.0. Si intenta incluir dicha palabra en una consulta SQL de creacin o
de modificacin de tabla para ser ejecutada con la biblioteca de DAO o desde la interfaz de usuario de
Microsoft Access, obtendr el oportuno error de sintaxis.
Se puede crear un ndice a la hora de crear una tabla en una base de datos Access, bien sobre un nico
campo de la tabla o a travs de dos o ms campos (ndice multicolumnas), utilizando para ambos casos
la clusula CONSTRAINT, que deber de aparecer al principio de la definicin del ndice y siempre que se
utilice con las instrucciones CREATE TABLE y ALTER TABLE.
Los tipos de ndices que se pueden designar mediante la clusula CONSTRAINT son tres: UNIQUE,
PRIMARY KEY y FOREIGN KEY. Puede incluirse tambin el atributo NOT NULL, lo que significar que
los valores de los campos que conforman un ndice multicolumna sern requeridos. Respecto a los
ndices de un slo campo, dicho atributo puede omitirse en la clusula CONSTRAINT y especificarse en
la parte correspondiente a la definicin del campo, si deseamos que el campo sea requerido.
Para ms informacin sobre la creacin de ndices, vea el captulo Cmo crear " eliminar los &ndices
de las tablas.
Por ltimo, en lo referente a crear tablas temporales en Microsoft Access con la misma funcionalidad que
sus homnimas de Microsoft SQL Server, he de comentar que hasta la fecha no est soportada an la
clusula TEMPORARY, a pesar de que en la documentacin oficial sobre la sintaxis del SQL de Microsoft
Jet 4.0 se haga referencia a la posibilidad de poder crearlas.

#$emplos
Crear una tabla en una base de Access
El siguiente ejemplo crear una hipottica tabla de Clientes, donde la clave principal de la tabla ser
el campo IdCliente, siendo el campo CIF un ndice donde no se permitirn valores duplicados.
Observe que en algunas declaraciones de campo se especifica su valor por defecto mediante la palabra
reservada DEFAULT:
Dim cnn As ADODB.Connection
Dim SQL As String
' Creo la cadena SQL
SQL = "CREATE TABLE Clientes ("
"IdCliente INTEGER CONSTRAINT PrimaryKey PRIMARY KEY, " & _
"[Nombre Completo] TEXT (50) WITH COMP NOT NULL, " & _
"CIF TEXT (9) WITH COMPRESSION NOT NULL CONSTRAINT IndiceCIF UNIQUE, " & _
"Domicilio TEXT (50) WITH COMP NULL, " & _
"CPostal INTEGER NULL DEFAULT 23000, " & _
"Localidad TEXT (30) WITH COMP NULL, " & _
"Provincia TEXT (20) WITH COMP NULL DEFAULT 99JAN99, " & _
"Pais TEXT (20) WITH COMP NULL DEFAULT ESPAA, " & _
"Telefono TEXT (10) WITH COMP NULL, " & _
"Fax TEXT (10) WITH COMP NULL, " & _
"[Fecha Alta] DATETIME DEFAULT DateValue(Now), " & _
"Observaciones TEXT WITH COMP)"
' Creo un objeto Connection
16
Prof. : Cesar Arce J.
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=C:\Mis documentos\bd1.mdb"
' Abro la conexin
.Open
' Ejecuto la consulta de creacin de tabla
.Execute SQL, , adCmdText
' Cierro la conexin
.Close
End With

Crear un archivo de dBASE versin 5.0
Antes de crear un archivo de dBASE utilizando el lenguaje SQL de Microsoft Jet, deber de tener en
cuenta las siguientes observaciones:
Si el nombre del campo tiene ms de diez caracteres, sern ignorados todos aqullos caracteres
que superen dicha cantidad, sustituyndose los espacios en blanco que hubiere por caracteres
de guin bajo: [Fecha_Alta].
Se tomar las primeras ocho letras del nombre del archivo, ignorndose todas aquellas que
superen la cantidad especificada, por lo que el nombre del archivo tendr el clsico formato 8 +
3.
No es necesario especificar la extensin del archivo, y sta siempre ser DBF, aunque se haya
especificado otra extensin distinta.
Si la consulta contiene campos de tipo MEMO, se crear en la misma carpeta un archivo con el
mismo nombre que la base de datos, pero con extensin DBT.
No se permite la clusula CONSTRAINT, por lo que no se podr crear ndices en el archivo de
dBASE. Asimismo, si en la carpeta existe un archivo de ndice (archivo *.inf) con el mismo
nombre del archivo que se desea crear, ste ser eliminado automticamente, por lo que
deber de tomar las precauciones oportunas si desea conservar el archivo de ndice de dBASE
existente.
El siguiente ejemplo crear un archivo de dBASE utilizando una consulta SQL de creacin de tabla:
Dim cnn As ADODB.Connection
Dim SQL As String
' Creo la cadena SQL
SQL = "CREATE TABLE Clientes#dbf ("
"IdCliente INTEGER, " & _
"[Nombre Completo] TEXT (50), " & _
"CIF TEXT (9), " & _
"Domicilio TEXT (50), " & _
"CPostal INTEGER, " & _
"Localidad TEXT (30), " & _
"Provincia TEXT (20), " & _
"Pais TEXT (20), " & _
"Telefono TEXT (10), " & _
"Fax TEXT (10), " & _
"[Fecha Alta] DATETIME, " & _
"Observaciones TEXT)"
' Creo un objeto Connection
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin
With cnn
17
Prof. : Cesar Arce J.
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=C:\Mis documentos\"
.Properties("Extended Properties") = "dBASE 5.0;"
' Abro la conexin
.Open
' Ejecuto la consulta de creacin de tabla
.Execute SQL, , adCmdText
' Cierro la conexin
.Close
End With

Crear un archivo de texto delimitado
Las observaciones que deber de tener en cuenta son las siguientes:
Se puede asignar un nombre largo al nombre del archivo de texto, necesitando encerrarlo entre
corchetes si el nombre contiene espacios en blanco.
Necesariamente hay que especificar una extensin al nombre del archivo, y debe estar
contemplada en el valor DisabledExtensions de la clave del registro de Windows
:;LM<So(t=are<Microso(t<)et<>.2<#n!ines<Te+t, que por defecto tiene registradas las
siguientes extensiones: !txt, csv, tab, asc, tmp, htm, html.
De especificar una extensin no registrada obtendremos el siguiente mensaje de error: No se puede
modificar el diseo de la tabla 'Nombre archivo#txt'. Esta es una base de
datos de slo lectura.
Si al crear la consulta de creacin de tabla no existe un archivo de configuracin de esquema
Sc,ema.ini, automticamente se crear uno en la misma carpeta, el cul contendr los
nombres de los campos, el formato delimitador de campos entre otros cuntos parmetros
ms.
Si el archivo Sc,ema.ini ya contiene la informacin de esquema correspondiente al mismo
archivo de texto que se desea crear, pero difiere en cuanto al nombre o el nmero de campos
que la especificada en la instruccin CREATE TABLE, se producir el error El motor de
base de datos icrosoft !et no pudo encontrar el ob"eto 'N#$%E#&'&' ,
por lo que deber de poner especial atencin si el archivo Sc,ema.ini incluye una seccin con
el nombre de nuestro archivo de texto, ya que la consulta SQL se deber de ajustar al
contenido del esquema existente.
De existir ya la informacin del archivo en la correspondiente seccin del archivo Sc,ema.ini,
no se modificar ningn parmetro al ejecutar la consulta SQL de creacin de tabla, aunque
sean distintos los tipos de datos de los campos que se desean crean con los existentes en el
archivo de configuracin de esquema, y respecto al mismo nombre del campo de los ya
existentes. Para que los datos incluidos en el archivo Sc,ema.ini se correspondan con los
especificados en la consulta SQL, edite primero el archivo de configuracin de esquema y
modifique los valores oportunos antes de ejecutar la consulta de creacin de tabla.
Ser obligatoria la presencia de un archivo Sc,ema.ini en los siguientes supuestos:
Accedamos a datos de longitud fija.
El archivo de texto contenga tipos de datos D!"#T$%#, C&''#n() o D#($%!*.
Deseamos elegir un juego de caracteres distinto al valor predeterminado existente en
la configuracin del registro de Windows.
El siguiente ejemplo muestra cmo crear un archivo de texto de ancho fijo mediante la instruccin
CREATE TABLE. Para ello, cree primero un archivo Schema.ini en la carpeta donde se crear el archivo
de texto, con los siguientes parmetros:
[Clientes.txt]
ColNameHeader=True
18
Prof. : Cesar Arce J.
CharacterSet=ANSI
Format=FixedLength
TextDelimiter=none
Col1=IdCliente Integer Width 8
Col2=Nombre Char Width 51
Col3=CIF Char Width 10
Col4=Domicilio Char Width 31
Col5=CPostal Integer Width 6
Col6=Localidad Char Width 31
Col7="Fecha Alta" Date Width 11
Col8=Notas LongChar Width 100
A continuacin ejecute el siquiente procediento:
Dim cnn As ADODB.Connection
Dim SQL As String
SQL = "CREATE TABLE Clientes#txt(" & _
"IdCliente INTEGER," & _
"Nombre TEXT (50)," & _
"CIF TEXT (9)," & _
"Domicilio TEXT (30)," & _
"CPostal INTEGER," & _
"Localidad TEXT (30)," & _
"[Fecha Alta] DATETIME," & _
"Notas TEXT)"
' Creo un objeto Connection
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=C:\Mis documentos\"
.Properties("Extended Properties") = "TEXT;HDR=Yes"
' Abro la conexin
.Open
' Ejecuto la consulta de creacin de tabla
.Execute SQL, , adCmdText
' Cierro la conexin
.Close
End With
Obsrvese que en el archivo de configuracin se ha definido un carcter ms a la longitud de los campos
de texto, para que haya un espacio en blanco de separacin entre los campos. Respecto a los tipos de
datos de los restantes campos, si desea que aparezca un espacio en blanco de separacin, procure que
la longitud del valor introducido sea una unidad menos que la definida en el archivo de configuracin.
Si desea ms informacin sobre cmo trabajar con el ISAM de Texto, consulte el siguiente artculo
tcnico:
Traba$ar con los datos de un arc,i1o de te+to

Crear una nueva hoja de clculo de Excel
Si utiliza el ISAM de Excel para crear una nueva hoja de clculo, deber de tener en cuenta las
siguientes observaciones:
Si a la hora de establecer una conexin con el origen de datos de Excel no existe el archivo
especificado en el parmetro D!"! S&'(#, en lugar de obtener un error, el ISAM crear
automticamente un archivo temporal de Excel, cuya versin corresponder con la utilizada en
la cadena de conexin especificada. Dicho archivo temporal se eliminar al cerrar la conexin
19
Prof. : Cesar Arce J.
abierta, excepto si creamos una tabla (en este caso, una hoja de trabajo), en cuyo caso
tendremos a nuestra disposicin un flamante archivo de Excel.
Al crear una hoja de clculo, Excel har caso omiso a los tipos de datos especificados en la
instruccin CREATE TABLE, por lo que todas las celdas tendrn el formato (eneral, a
excepcin de los campos que tengan un tipo de datos de fecha, en los que s reconocer dicho
formato de celda.
No obstante, siempre y cuando el archivo no se haya modificado y guardado desde el propio
programa Microsoft Excel, el objeto %ield de ADO reconocer los tipos de datos especificados
en la consulta SQL de creacin de tabla, con los siguientes detalles:
No es necesario especificar el tamao de los campos de texto, ya que todos tendrn
255 caracteres de longitud, salvo que indiquemos expresamente en la sintaxis la
palabra clave TEXT sin especificar el tamao, en cuyo caso el tipo de dato devuelto
por la propiedad T"pe del objeto %ield ser LONGTEXT o MEMO.
Siempre que se cree una nueva hoja de trabajo mediante la instruccin CREATE TABLE, se
crear as mismo un nuevo rango con idntico nombre que el especificado en la consulta SQL.
No se puede especificar un rango de celdas sin nombre [Hoja1$A1:Z50], como tampoco se
puede especificar el nombre de una hoja de clculo completa [Hoja1$], en el parmetro
correspondiente al nombre de la tabla que deseamos crear: el nico nombre permitido es el
utilizado para definir un rango de celdas con nombre:
CREATE TABLE [Hoja1$A1:Z50] (Campo1 INTEGER)
CREATE TABLE [Hoja1$] (Campo1 INTEGER)
CREATE TABLE [Hoja1] (Campo1 INTEGER)
' No es un nombre vlido.
' No es un nombre vlido.
' S es correcto el nombre de la tabla.
El siguiente ejemplo utilizar ADO .NET para crear una nueva hoja de trabajo de Excel mediante el
proveedor Microsoft Jet OLEDB. La misma sintaxis SQL se puede utilizar tambin con las bibliotecas de
DAO y ADO:
' Importamos el siguiente espacio de nombre
Imports System.Data.OleDb
Dim cnn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim SQL As String
Try
' Configuramos y abrimos la conexin
With cnn
.ConnectionString = _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Libro1.xls;" & _
"Extended Properties=""EXCEL 8.0;HDR=Yes;"""
.Open()
End With
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al abrir la conexin", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End Try
' Creamos la cadena SQL
SQL = "CREATE TABLE Clientes(" & _
"IdCliente INTEGER," & _
"Nombre TEXT (50)," & _
"CIF TEXT (9)," & _
"Domicilio TEXT (30)," & _
"CPostal INTEGER," & _
"Localidad TEXT (30)," & _
20
Prof. : Cesar Arce J.
"[Fecha Alta] DATETIME," & _
"Notas TEXT)"
Try
' Configuramos el objeto Command y ejecutamos
' la consulta
With cmd
.Connection = cnn
.CommandText = SQL
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
MessageBox.Show("Se ha creado la hoja de trabajo.", _
"CREATE TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
' Insertamos dos filas
SQL = "INSERT INTO Clientes VALUES (" & _
"1,'Juan Lpez Prez','25222011J','C/. Bernab Soriano, 24 - 8
Izq.',23001,'JAN','28/04/1962',NULL)"
With cmd
.CommandText = SQL
.ExecuteNonQuery()
End With
SQL = "INSERT INTO Clientes VALUES (" & _
"2,'Flix Cuesta Rodrguez','25940103F','C/. Blas Infante, 35 - 7
A',23008,'JAN','21/08/1961','Esto es una nota')"
With cmd
.CommandText = SQL
.ExecuteNonQuery()
End With
MessageBox.Show("Se han insertado los dos registros.", _
"CREATE TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al crear la hoja de trabajo", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
' Cerramos la conexin
cnn.Close()
Para ms informacin sobre el ISAM de Excel, consulte el siguiente artculo tcnico:
Traba$ar con ADO7 DAO " #+cel

Modi(icar la estructura de una tabla
Una vez creada la tabla, puede que resulte necesario modificar el diseo de la misma, bien para aadir
nuevos campos, cambiar el tipo de dato de algn campo, o bien, eliminar un campo de la tabla. Para
todas estas operaciones utilizaremos la instruccin ALTER TABLE seguida de la correspondiente
clusula SQL, dependiendo de la operacin que desee ejecutar.
Hasta la llegada de la versin 4.0 del motor Microsoft Jet, las nicas operaciones permitidas por el
lenguaje SQL relacionadas con los campos de una tabla, eran las que nos posibilitaba solamente aadir y
eliminar columnas de la tabla. Ahora, tambin nos est permitido modificar el tipo de dato declarado
21
Prof. : Cesar Arce J.
inicialmente para un campo, operacin esta que conlleva el peligro de una prdida de informacin si los
datos incluidos en el campo no se corresponden con el nuevo tipo de dato declarado.
Pero todava contina siendo una asignatura pendiente el poder renombrar el nombre de un campo
existente en la tabla, por lo que tendremos que recurrir a la interfaz de usuario de Microsoft Access, o
bien, implementar un procedimiento para realizar la operacin mediante cdigo fuente.
A continuacin pasar a detallar por separado las operaciones permitidas de modificacin de la
estructura de una tabla, teniendo en cuenta que solamente podr modificar un campo cada vez que
ejecute una instruccin ALTER TABLE.

A8adir nue1os campos a la tabla
Para aadir un campo a la tabla con la instruccin ALTER TABLE utilice la clusula ADD COLUMN, donde
deber especificar el nombre del campo, el tipo de dato, un tamao opcional para los campos de tipo
Te+t y -inar", as como el valor por defecto, teniendo en cuenta que esta ltima opcin slo est
disponible cuando la consulta SQL es ejecutada con la biblioteca de ADO y el proveedor Microsoft Jet
OLE DB 4.0.
La sintaxis para aadir un nuevo campo es la siguiente:
ALTER TABLE nombre'abla ADD COLUMN nombre(ampo tipo#ato [(tamao)]
[WITH COMPRESSION | WITH COMP]
[NOT NULL | NULL]
[DEFAULT valor#efecto]
[$ndice]
El siguiente ejemplo aadir un nuevo campo a una tabla cualquiera. Debido a que el campo ser
requerido (lo que significa que ser obligatoria la entrada de datos), especificaremos un valor por
defecto:
ALTER TABLE Tabla1 ADD COLUMN Campo1 VARCHAR (30)
WITH COMP NOT NULL DEFAULT ""Valor por defecto""
.ota? Respecto a la forma de especificar el valor por defecto, encierre el mismo entre dos pares de
comillas dobles si el valor contiene espacios en blanco.
A continuacin aadiremos un nuevo campo Autonum*rico a la tabla lumnos que ser la clave
principal de dicha tabla. Note que en el campo contador se ha definido el valor de inicio (10) y el de
incremento (5):
ALTER TABLE Alumnos ADD COLUMN IdAlumno COUNTER (10,5) CONSTRAINT ClavePrincipal PRIMARY
KEY

Modi(icar el tipo de dato de un campo
Podemos tambin utilizar la instruccin ALTER TABLE junto con la clusula ALTER COLUMN, para
modificar el tipo de dato de un campo, el tamao opcional para los campos de tipo Te+t y -inar", o el
valor por defecto del mismo, siendo su sintaxis la siguiente:
ALTER TABLE nombre'abla ALTER COLUMN nombre(ampo tipo#ato [(tamao)]
[WITH COMPRESSION | WITH COMP]
[NOT NULL | NULL]
[DEFAULT valor#efecto]
[$ndice]
22
Prof. : Cesar Arce J.
Si solamente desea establecer o modificar el valor por defecto, puede utilizar, si as lo desea, la
siguiente sintaxis:
ALTER TABLE nombre'abla ALTER COLUMN nombre(ampo SET DEFAULT valor#efecto
No utilice la palabra reservada SET cuando modifique a la misma vez el tipo de dato y el valor por
defecto del campo, ya que obtendr un error de sintaxis. La palabra SET nicamente se utiliza cuando
slo se desea modificar o establecer el valor por defecto de un campo, en cuyo caso es completamente
necesario incluirla, tal y como se muestra en el siguiente ejemplo:
ALTER TABLE Alumnos ALTER COLUMN Localidad SET DEFAULT ""Jan""
Advierta que el valor por defecto debe de especificarse encerrando el valor entre pares de comillas
dobles, si el mismo es un valor alfanumrico, y deber de corresponderse con el tipo de valor declarado
para el campo. Si el valor est formado por una sola palabra, no es necesario que se especifique los
pares de comillas, aunque s es recomendable que se incluyan a fin de obtener una compatibilidad con
Microsoft Access, el cual encierra los valores alfanumricos por defecto entre comillas dobles en la vista
#iseo de la tabla. En todo caso, si el valor por defecto incluye espacios en blancos, necesariamente
tendr que encerrar el valor entre pares de comillas dobles, dado que no sirve en este caso encerrar las
palabras entre corchetes []. Por ltimo, si desea eliminar el valor por defecto de un campo, no incluya
ninguna palabra o nmero tras la palabra reservada DEFAULT:
ALTER TABLE Alumnos ALTER COLUMN Localidad SET DEFAULT
A continuacin modifiqueramos el tipo de dato de un campo, de tal forma que su valor incial de texto
pasar ahora a ser del tipo numrico entero largo:
ALTER TABLE Alumnos ALTER COLUMN CodPostal INTEGER DEFAULT
Si los valores existentes en el campo no se pueden convertir al nuevo tipo de dato definido, recibir el
siguiente mensaje de error: )o coinciden los tipos de datos en la expresin de criterios.
En el ejemplo anterior, si algn registro de la tabla tiene un valor alfanumrico en el campo cuyo tipo de
dato queremos modificar, no podremos llevar a cabo dicha operacin si ejecutamos la consulta SQL
utilizando los objetos de la biblioteca de ADO. En cambio, si ejecutamos la misma consulta SQL
utilizando la biblioteca de DAO, o desde la interfaz de usuario de Microsoft Access, no obtendremos el
citado mensaje de error, insertndose valores NULL en el campo de los registros que presenten valores
alfanumricos.
El siguiente ejemplo disminuir el tamao del campo de una columna definida como Te+t:
ALTER TABLE Clientes ALTER COLUMN Domicilio TEXT (30)
Si establece un tamao de la columna ms pequeo que la longitud existente actualmente en algn
registro del campo, no podr modificar el tamao del campo, recibiendo el siguiente mensaje de error:
*l campo es demasiado pe+ueo para aceptar la cantidad de datos +ue intenta agregar, -ntente insertar
o pegar menos datos.
Si tenemos una columna de texto definida inicialmente con un tamao del campo de 50 caracteres, no
podremos disminuir el tamao del mismo si existen datos cuya longitud supera en caracteres el nuevo
tamao del campo que deseamos establecer. Por tanto, si los datos de un registro ocupan 38 caracteres,
no podemos especificar un tamao del campo inferior a esa cifra, si para ejecutar la consulta SQL de
modificacin de campo utilizamos los objetos de la biblioteca de ADO, cosa sta que no ocurre si
utilizamos nuevamente la biblioteca de DAO o la interfaz de usuario de Microsoft Access, en cuyo caso
desaparecern, comenzando por la derecha, los caracteres que superen el nuevo tamao del campo
indicado.
A continuacin, modificaremos el tipo de dato de un campo, de tal forma que sea del tipo
Autonum*rico. Asimismo, indicaremos que su valor inicial sea 10, y que se incremente en valores de
cinco unidades.
ALTER TABLE Clientes ALTER COLUMN IdCliente IDENTITY (10,5)
23
Prof. : Cesar Arce J.
Esta consulta SQL, nicamente ser vlida cuando deseemos modificar el tipo de dato de un campo,
siempre y cuando no existan registros en la tabla, porque de contener un nico registro, es suficiente
para obtener el siguiente mensaje de error: 'ipo de datos de campo no v.lido.
El ejemplo anterior tambin nos puede servir para modificar el valor de inicio o de incremento de un
campo Autonum*rico, en cuyo caso da igual que la tabla tenga o no registros insertados.
Por ltimo, modifiqueramos el tamao de un campo numrico, el cual pasar de FLOAT a REAL:
ALTER TABLE Facturas ALTER COLUMN TotalFactura REAL DEFAULT
La prdida de datos tambin puede ocurrir al cambiar entre los distintos tipos de datos numricos
existentes, por lo que el cambiar de Doble a Simple tambin puede conllevar una prdida de datos,
cuestin esta que es importante que siempre tenga en cuenta.
Al incluir en el ejemplo la palabra clave DEFAULT, sin un valor predeterminado en concreto,
eliminaremos por completo el valor por defecto que tuviera el campo. De camino, como el nuevo valor
es numrico, evitamos que tome el 0 como valor predeterminado.

#liminar un campo de la tabla
Hemos visto como aadir un campo a una tabla ya existente, as como la posibilidad de modificar el tipo
de dato inicialmente declarado, por lo que solo nos queda ver la forma de eliminar un campo de una
tabla. Para ello tambin utilizaremos la instruccin ALTER TABLE, pero esta vez ir acompaada de una
clusula DROP COLUMN, siendo su sintaxis como se detalla a continuacin:
ALTER TABLE nombre'abla DROP COLUMN nombre(ampo
El siguiente ejemplo eliminar un campo cualquiera de una tabla:
ALTER TABLE Tabla1 DROP COLUMN Campo1
Deber de tener en cuenta que, si el campo que desea eliminar forma parte de un ndice o de una
relacin existente, deber eliminar primero el ndice o la relacin antes de proceder a eliminar el campo
de la tabla.
Mediante el lenguaje SQL del motor Microsoft Jet an no es posible renombrar el nombre de un campo
de la tabla, por lo que si no queremos recurrir a Microsoft Access para tal cometido, tendremos que
eliminar el campo y recrearlo de nuevo. Pero si eliminamos el campo, se eliminarn tambin los datos
existentes, salvo que preservemos los datos pasando estos al nuevo campo, tal y como muestra el
siguiente ejemplo:
' Creamos un nuevo campo, el cual tendr el nuevo nombre.
'
ALTER TABLE Clientes ADD COLUMN IdCliente INTEGER
' Pasamos los datos al nuevo campo
'
UPDATE Clientes SET IdCliente = [Num Cliente]
' Eliminamos el campo
'
ALTER TABLE Clientes DROP COLUMN [Num Cliente]
Deber de tener especial cuidado para que el nuevo campo tenga el mismo tipo de datos y tamao que
el campo que desea eliminar, asi como tener en cuenta su posible pertenencia a un ndice de la tabla o a
una relacin existente en la base de datos.
24
Prof. : Cesar Arce J.

Copiar una tabla
Mediante la consulta de creacin de tabla, representada por la instruccin SELECT+++INTO, podemos
crear copias de nuestras tablas, bien como medida de seguridad ante una posible prdida de datos, o
simplemente para importar o exportar los datos desde o hacia otra base de datos externa. No es
necesario copiar los datos de la tabla, ya que puede suceder que slo nos interese copiar la estructura
de la tabla de tal forma que nos sirva de plantilla para una nueva tabla.

Sinta+is
Hay tres tipos de sintaxis diferente que puede utilizar, dependiendo de dnde se encuentren el origen y
el destino de los datos:
El origen y el destino se encuentran en la misma base de datos:
SELECT campo1[, campo2[, ...]] INTO nueva'abla FROM origen [WHERE False]
La tabla de destino se encuentra en una base de datos externa al origen de los datos, que es la
sintaxis a utilizar cuando se desea exportar datos a otra base de datos:
SELECT campo1,[ campo2[, ...]] INTO nueva'abla IN base#atos*xterna FROM origen [WHERE False]
La tabla de origen se encuentra en una base de datos externa distinta del destino de los datos, que es
la sintaxis que debe de utilizar cuando desee importar datos a la base de datos actual:
SELECT campo1,[ campo2[, ...]] INTO nueva'abla FROM origen IN base#atos*xterna [WHERE False]
Cuando necesite indicar una base de datos externa Microsoft Access, podr utilizar cualquiera de las dos
sintaxis que a continuacin se indican, teniendo en cuenta que si la ruta la encierra entre comillas
simples, no deber de utilizar los corchetes. En cambio, si el par de comillas simples va inmediatamente
despus de la clusula IN, s deber de encerrar entre corchetes la cadena de conexin, indicando el
tipo de ISAM a utilizar (/0 ccess, en el supuesto que la base de datos externa sea Microsoft Access), y
la ruta completa de la base de datos en el parmetro DATABASE, as como cualquier otro parmetro
opcional que sea requerido, como bien pudiera ser la contrasea de la base de datos.
Si la base de datos externa es distinta de Microsoft Access, necesariamente deber de utilizar el formato
de corchetes para especificar todos los parmetros requeridos para conectarse con el origen de datos.
IN @Ruta base datos externa@ IN @C:\Mis documentos\Bd1.mdb@
IN @@AMS Access;DATABASE=Ruta base datos
externa;PWD=contraseaB
IN @@AMS Access;DATABASE=C:\Mis
documentos\Bd1.md;PWD=contraseaB

5armetro Descripcin
campo1, campo2 El nombre de los campos que se van a crear. Al menos debe de crearse
un campo.
nueva'abla El nombre de la tabla que deseamos crear.
origen El nombre de la tabla de origen.
25
Prof. : Cesar Arce J.
base#atos*xterna
Ruta completa de la base de datos externa. Si la base de datos no es
Microsoft Access, deber de incluir igualmente el tipo de base ISAM y los
parmetros necesarios para conectarse a la misma.
12*3* 4alse Si se indica la clusula opcional WHERE F!*,#, slo se copiar la
estructura de la tabla indicada en el origen. Tambin se puede especificar
WHERE 1-..

Comentarios
Cuando se crea una nueva tabla mediante la instruccin SELECT+++INTO, los campos solamente
heredarn el tamao y el tipo de dato correspondiente a cada campo de la tabla de origen especificada
en la consulta, no transfirindose ninguna otra propiedad del campo o de la tabla. Igualmente, tampoco
se transferir ningn ndice que pueda tener establecido la tabla de origen.
Si desea conocer los registros que se vern afectados por la consulta de creacin de tabla, dispone de
dos mtodos para saber los registros que se seleccionarn, dependiendo si lo desea conocer antes o
despus de ejecutar la consulta:
Antes de ejecutar la consulta de creacin de tabla, puede examinar el resultado de una
instruccin SELECT que utilice el mismo criterio de seleccin.
Una vez ejecutada la consulta, podemos conocer el nmero de registros afectados leyendo el
valor devuelto por el parmetro CecordsA((ected del mtodo #+ecute del objeto Connection
de ADO, o leyendo el mtodo #+ecute.onQuer" de un objeto Command de ADO .NET, tal y
como se puede apreciar en los siguientes ejemplos.
Para los usuarios de ADO:
Dim lngRegAfectados As Long
Dim rst As ADODB.Recordset
' Antes de ejecutar la consulta de creacin de tabla, consultamos
' los registros que se seleccionarn
'
Set rst = New ADODB.Recordset
rst.Open "SELECT COUNT(*) AS TotalRegistros FROM Tabla1", cnn
MsgBox rst.Fields!TotalRegistros.Value
' Ejecutamos la consulta de creacin de tabla, pasndole una variable
' del tipo Long que devolver el nmero de registros afectados por la
' operacin.
'
cnn.Execute _
"SELECT * INTO Tabla2 FROM Tabla1", lngRegAfectados, adCmdText
MsgBox lngRegAfectados
Para los usuarios de ADO .NET:
With cmd
.Connection = cnn
.CommandText = "SELECT * INTO Tabla2 FROM Tabla1"
' Ejecutamos la consulta de creacin de tabla y leemos
' los registros afectados
'
MsgBox(.ExecuteNonQuery())
End With

26
Prof. : Cesar Arce J.
#$emplos
El siguiente ejemplo mostrar cmo exportar todos los campos de una tabla de Access a otra base
de datos externa Microsoft Access utilizando la biblioteca de ADO:
Dim cnn As ADODB.Connection
Dim lngRegAfectados As String
Dim SQL As String
' Creo la cadena SQL
SQL = "SELECT * INTO [Copia Clientes] IN @@[C:\Mis documentos\Bd2.mdb] FROM Clientes"
' Creo un objeto Connection
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=C:\Mis documentos\bd1.mdb"
' Abro la conexin
.Open
' Ejecuto la consulta de creacin de tabla
.Execute SQL, lngRegAfectados, adExecuteNoRecords
' Cierro la conexin
.Close
End With
A continuacin, vamos a importar una tabla de una base de datos SQL Server a nuestra base de
datos Microsoft Access, utilizando el driver ODBC para conectarnos a la base de datos de SQL Server:
Dim cnn As ADODB.Connection
Dim lngRegAfectados As String
Dim SQL As String
' Creo la cadena SQL de creacin de tabla
SQL = "SELECT * INTO [Employees] FROM Employees " & _
"IN @@[ODBC;Driver={SQL Server};" & _
"Server=Nombre_Servidor_SQL;" & _
"Database=Northwind;" & _
"UID=sa;PWD=]"
' Creo un objeto Connection
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin con la base de datos de Access
' donde deseo importar la tabla
'
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=C:\Mis documentos\bd1.mdb"
' Abro la conexin
.Open
' Ejecutamos la consulta
.Execute SQL, lngRegAfectados, adCmdText
' Cierro la conexin
.Close
End With
Por ltimo, vamos a crear un archivo de texto delimitado con los datos de una tabla de Access,
utilizando ADO .NET:
' Importamos el siguiente espacio de nombre
Imports System.Data.OleDb
27
Prof. : Cesar Arce J.
Dim cnn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim SQL As String
Try
' Configuramos y abrimos la conexin con la base de
' de datos de Access
With cnn
.ConnectionString = _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Bd1.mdb"
.Open()
End With
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al abrir la conexin", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End Try
' Creamos la cadena SQL de creacin de tabla para el exportar
' los datos de dos campos de la tabla Clientes
'
SQL = "SELECT IdCliente, Nombre INTO Clientes#txt" & _
" IN @C:\Mis documentos@ @TEXT;HDR=Yes@" & _
" FROM Clientes"
Try
' Configuramos el objeto Command y ejecutamos
' la consulta
With cmd
.Connection = cnn
.CommandText = SQL
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
MessageBox.Show("Se ha creado el archivo de texto.", _
"Exportar tabla", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al crear el archivo de texto", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
' Cerramos la conexin
cnn.Close()

#liminar una tabla
Mediante la instruccin DROP TABLE del lenguaje de definicin de datos (DDL) de SQL, podemos
eliminar tablas de una base de datos Access, as como de otros formatos de bases de datos de
escritorio.

Sinta+is
DROP TABLE [nombre tabla]
28
Prof. : Cesar Arce J.

5armetro Descripcin
nombre tabla El nombre de la tabla que se desea eliminar.

Comentarios
Al igual que el resto de las instrucciones del lenguaje de definicin de datos vistas con anterioridad, la
instruccin DROP TABLE se utiliza como argumento del mtodo #+ecute de un objeto Database abierto
(DAO) o de un objeto Connection (ADO), al igual que por el mtodo #+ecute.onQuer" de un objeto
OleDbConnection del espacio de nombre System.Data.OleDb de ADO .NET, siendo su nico objetivo
eliminar una tabla de una base de datos.
Hay que tener presente que el usuario deber de tener los permisos necesarios para poder eliminar la
tabla, porque de lo contrario, obtendremos el correspondiente error.
Asimismo, si la tabla que deseamos eliminar es la tabla principal de una relacin de uno a varios con una
tabla externa (es decir, el lado uno de dos tabla relacionadas), necesitaremos primero eliminar la
relacin para posteriormente poder eliminar la tabla. Por ejemplo, si tenemos una relacin establecida
de uno a varios entre las tablas (lientes (parte 1) y 4acturas (parte varios), mediante la instruccin
DROP TABLE no podemos eliminar la tabla (lientes, lo que no impide que s podamos eliminar la tabla
4acturas. Para eliminar la tabla (lientes, primero tendremos que eliminar la relacin con la instruccin
ALTER TABLE y posteriormente ejecutar la instruccin DROP TABLE.
' Eliminamos la relacin existente
ALTER TABLE Facturas DROP CONSTRAINT ClientesFacturas
' Eliminamos la tabla Clientes
DROP TABLE Clientes
Al igual que se puede crear una base de datos ISAM mediante instrucciones SQL, tambin podemos
eliminar archivos de otros formatos de bases de datos con la instruccion DROP TABLE.
Por ltimo indicar que, antes de ejecutar la instruccin DROP TABLE, asegrese que la tabla no se
encuentra abierta.

#$emplos
El siguiente ejemplo eliminar del disco el archivo (lientes,txt. Ntese que si se tiene un archivo de
configuracin de esquema 0chema,ini, tambin se eliminar del mismo las entradas correspondientes al
archivo de texto eliminado.
Dim cnn As ADODB.Connection
' Creo un nuevo objeto Connection
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin
cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos"
cnn. .Properties("Extended Properties") = "TEXT;"
' Abro la conexin
cnn.Open
' Ejecuto la consulta de eliminacin de tabla
cnn.Execute "DROP TABLE [Nombre Archivo#txt]"
29
Prof. : Cesar Arce J.
' Cierro la conexin
cnn.Close

El siguiente ejemplo eliminar de nuestra base de datos una tabla cualquiera:
Dim cnn As ADODB.Connection
' Creo un nuevo objeto Connection
Set cnn = New ADODB.Connection
' Establezco la cadena de conexin
With cnn
.Provider = "Microsoft.Jet.OLEDB.4.0""
.ConnectionString = "Data Source = C:\Mis documentos\bdl.mdb"
' Abro la conexin
.Open
' Ejecuto la consulta de eliminacin de tabla
.Execute "DROP TABLE [Nombre Tabla]"
' Cierro la conexin
.Close
End With

Por ltimo, mediante ADO .NET eliminaremos los valores existentes en una hoja de trabajo de Excel
correspondiente con el rango de celdas con nombre especificado:
' Importamos el siguiente espacio de nombre
Imports System.Data.OleDb
Dim cnn As New OleDbConnection
Dim cmd As New OleDbCommand
Try
' Configuramos y abrimos la conexin
With cnn
.ConnectionString = _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Libro1.xls;" & _
"Extended Properties=99EXCEL 8.0;HDR=Yes;99"
.Open()
End With
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al abrir la conexin", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End Try
Try
' Configuramos el objeto Command y ejecutamos
' la consulta
With cmd
.Connection = cnn
.CommandText = "DROP TABLE [Clientes]"
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
MessageBox.Show("Se ha eliminado la hoja de trabajo.", _
"DROP TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Catch ex As Exception
30
Prof. : Cesar Arce J.
MessageBox.Show(ex.Message, _
"Error al eliminar la hoja de trabajo", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
' Cerramos la conexin
cnn.Close()
Cap&tulo '6. Cmo crear " eliminar los &ndices de las
tablas


Descargar (90 KB)

Contenido
'ntroduccin
La clusula CO.STCA'.T " la inte!ridad re(erencial
Tabla principal " tabla e+terna
La inte!ridad re(erencial
Cmo crear un &ndice
Con la instruccin CC#AT# TA-L#
Con la instruccin ALT#C TA-L#
Con la instruccin CC#AT# ... '.D#D
Cmo eliminar un &ndice
Con la instruccin ALT#C TA-L#
Con la instruccin DCO5 '.D#D

'ntroduccin
Podemos definir el trmino $ndice como el recurso necesario para acelerar la b&s+ueda y ordenacin de
los datos incluidos en una tabla, utili5ando para ello valores clave +ue pueden exigir +ue las filas de una
tabla sean &nicas. No es necesario crear ndices en una tabla, aunque s es recomendable utilizarlos para
aquellos conjuntos de datos que tengan un volumen considerable de registros, ya que se agilizar el
tiempo de acceso a un determinado registro como tambin el proceso de combinacin de registros entre
dos o ms tablas.
Si bien es recomendable que los registros de una tabla se puedan indexar, el crear demasiados ndices
tiene un efecto negativo, ya que al actualizar los datos el motor Microsoft Jet tiene que mantener
automticamente todos los ndices de la tabla base, actualizando estos cada vez que se aaden,
modifican o eliminan registros de la tabla, por lo que la actualizacin de la base de datos puede demorar
un tiempo bastante considerable. Es una buena prctica compactar peridicamente la base de datos a
fin de que se puedan actualizar las estadsticas del ndice.
Los ndices determinan el orden en el que aparecern los registros devueltos por una consulta de
seleccin, aunque se pueden ordenar por otro campo distinto del campo que forma el ndice, pero en
ningn caso determinan el orden en el que se almacenarn los datos en la tabla base.

31
Prof. : Cesar Arce J.
La clusula CO.STCA'.T " la inte!ridad re(erencial
Una restriccin CONSTRAINT es simplemente un ndice, aunque tambin podemos utilizar dicha clusula
para establecer una relacin con otra tabla, entendiendo por relacin la asociacin establecida entre
campos comunes de dos tablas. Dicha clusula slo se puede especificar con las instrucciones CREATE
TABLE y ALTER TABLE, si nuestra intencin es crear un ndice o una relacin, y nicamente con ALTER
TABLE si deseamos eliminar cualquier ndice o relacin existente.
La clusula CONSTRAINT siempre ir al principio de la definicin del ndice, pudindose crear un ndice
sobre un campo individual o sobre un grupo de campos, utilizando para ello la siguiente sintaxis
dependiendo del nmero de campos que formen el ndice.
Para los ndices de campos nicos:
CONSTRAINT nombre {PRIMARY KEY | UNIQUE | NOT NULL |
REFERENCES tabla*xterna [(campo*xterno1 [, campo*xterno2])]
[ON UPDATE CASCADE | SET NULL]
[ON DELETE CASCADE | SET NULL]}
El siguiente ejemplo crear un ndice de un nico campo que a su vez ser la clave principal de la tabla:
CREATE TABLE Facturas (IdFactura INTEGER CONSTRAINT ClavePrincipal PRIMARY KEY)
Para los ndices de campos mltiples:
CONSTRAINT nombre
{PRIMARY KEY (principal1[, principa-2[, ...]]) |
UNIQUE (&nico1[, &nico2[, ...]]) |
FOREIGN KEY [NO INDEX] (ref1[,ref2[, ...]]) REFERENCES tabla*xterna [(campo*xterno1
[,campo*xterno2 [, ...]])]
[ON UPDATE CASCADE | SET NULL]
[ON DELETE CASCADE | SET NULL]}
A continuacin crearemos un ndice de varios campos el cual no podr contener valores duplicados:
ALTER TABLE Clientes ADD CONSTRAINT CodigoFiscal UNIQUE (Nombre, CIF)
A continuacin se detallan los parmetros utilizados en ambas versiones.
Ar!umento Descripcin
nombre El nombre del ndice o restriccin que se desea crear.
principal1, principal2
El nombre del campo o de los campos que han sido designados para
formar la clave principal.
&nico1, &nico2
El nombre del campo o de los campos que han sido designados para
formar una clave nica.
ref1, ref2
El nombre de un campo o de los campos de la clave externa a los que
se hace referencia en campos de otra tabla.
tabla*xterna
El nombre de la tabla externa que contiene el campo o los campos
especificados por campo*xterno.
campo*xterno1, campo*xterno2
El nombre del campo o campos de tabla*xterna especificados por
ref1, ref2. Se puede omitir esta clusula si el campo al que se hace
referencia es la clave principal de la tabla externa.
Son tres los tipos de ndices que se pueden crear mediante la clusula CONSTRAINT:
32
Prof. : Cesar Arce J.
UNIQUE: genera un ndice como clave nica formado por un campo o un conjunto de campos
de la tabla. Esto implica que los registros de la tabla no pueden tener el mismo valor en los
campos indexados. Si el ndice de clave nica est formado por varios campos, los valores
combinados de todos los campos del ndice deben ser nicos, aunque dos o ms registros de la
tabla tengan el mismo valor en uno de los campos que conforman el ndice de mltiples
campos.
PRIMARY KEY: genera un ndice como clave principal formado por un campo o un conjunto de
campos de la tabla. Todos los valores de los campos que conforman el ndice primario deben
ser nicos y no nulos. Cada tabla slo puede tener una nica clave principal, producindose un
error interceptable si se intenta crear una nueva clave principal en una tabla donde ya existe
una restriccin PRIMARY KEY.
FOREIGN KEY: genera un ndice como clave externa, lo que significa que tomar como valor
del ndice un campo o conjunto de campos contenidos en otras tablas. Si la clave principal de la
tabla externa est formado por ms de un campo, debe utilizar una definicin de ndice de
mltiples campos, enumerando todos los campos de referencia, el nombre de la tabla externa y
los nombres de los campos referenciados en la tabla externa y en el mismo orden en que se
especificaron los campos de referencia anteriormente enumerados. Si el campo o los campos
referenciados son la clave principal de la tabla externa, no tiene que especificar los campos
referenciados de manera predeterminada, ya que el motor de datos Microsoft Jet se comportar
como si la clave principal de la tabla externa fuera el campo referido.
Por ejemplo, si deseamos aadir el ndice (lientes%4acturas a la tabla 4acturas de nuestra base de
datos, tendramos que ejecutar la siguiente consulta SQL:
ALTER TABLE Facturas ADD CONSTRAINT Clientes_Facturas FOREIGN KEY (NumCliente) REFERENCES
Clientes (IdCliente)
Al utilizar la palabra clave FOREIGN KEY para crear un ndice, estaremos creando una relacin llamada
(lientes%4acturas entre el campo que conforma la clave principal de la tabla (lientes y el campo
)um(liente externo de la tabla 4acturas, por lo que el motor Jet exigir que se cumpla la integridad
referencial de los datos.

Tabla principal " tabla e+terna
Antes de hablar sobre la integridad referencial, conviene definir ciertos conceptos que le ayudarn a
entender los elementos que conforman una relacin entre dos tablas.
Una tabla principal es el lado uno de dos tablas relacionadas mediante una relacin de uno a varios, y
debe de tener una clave principal donde cada registro debe ser nico. Un ejemplo de una tabla principal
sera el de la tpica tabla de (lientes, donde cada registro se identifica de manera nica mediante el
campo -d(liente, el cual forma parte a su vez de la clave principal de la tabla.
Generalmente, una tabla externa se corresponde con el lado varios de una relacin de uno a varios, la
cul contar con un campo de clave externa, que estar referenciando a la clave principal existente en
otra tabla de la base de datos (el lado uno de la relacin). Un ejemplo de tabla externa es una tabla de
4acturas de clientes, cuyo campo )um(liente est referenciando a una clave externa existente en la
tabla de (lientes, cuya clave principal estar formada por el campo -d(liente.
La clave principal de una tabla deber estar formada por uno o varios campos cuyo valor o valores
identifican de manera nica cada registro de la tabla. Una clave principal no puede permitir valores NULL
(Nulos) y debe tener siempre un ndice nico. La clave principal se utiliza para relacionar una tabla con
claves externas de otras tablas.
La clave externa estar formada tambin por uno o varios campos de una tabla, los cuales hacen
referencia al campo o campos que conforman la clave principal de otra tabla de la base de datos. Una
clave externa indica cmo deben estar relacionadas las tablas, y los tipos de datos de los campos de
ambas claves (externa y principal) deben coincidir, aunque los nombres de los campos sean distintos,
por lo que si la clave principal tiene un tipo de datos Integer, la clave externa debe tener el mismo tipo
de dato. Por ejemplo, una tabla de 4acturas puede contener una clave externa llamada )um(liente (que
no tiene por qu denominarse igual que el nombre de un campo existente en la misma tabla), que hace
33
Prof. : Cesar Arce J.
referencia a la clave principal llamada 6rimary7ey formada por el campo nico -d(liente de una
hipottica tabla de (lientes.
CL'#.T#S %ACT0CAS

(Tabla
principal)

(Tabla
externa)

Clave principal de la tabla,
denominada 6rimary7ey
'dCliente IdFactura
'dCliente
Clave externa de la tabla,
denominada )um(liente


La inte!ridad re(erencial
Podemos definir el trmino integridad referencial como el conjunto de reglas +ue se siguen para
preservar las relaciones definidas entre las tablas a la hora de aadir, modificar o eliminar registros.
Como se ha indicado anteriormente, mediante la clusula CONSTRAINT podemos definir claves
principales y externas para crear relaciones entre tablas de nuestra base de datos Access, y hacer que
se cumpla las reglas de la integridad referencial, las cuales protegen las relaciones entre las tablas
cuando se aaden, modifican o eliminan registrops. De sta forma se impide a los usuarios que aadan
registros a una tabla relacionada para la que no existe un registro asociado en la tabla principal (no
podemos asignar una factura a un identificador de cliente no existente), modificar los valores de la tabla
principal que podran dar lugar a registros hurfanos en la tabla relacionada, salvo que en la relacin se
haya definido la actualizacin de datos en cascada, as como eliminar los registros de la tabla principal
cuando haya registros relacionados coincidentes en la tabla relacionada, salvo que como en el caso
anterior, se permita la eliminacin de registros en cascada en la definicin de la relacin creada.

Cmo crear un &ndice
Existen tres formas de crear un ndice mediante las instrucciones del Lenguaje de Definicin de Datos de
SQL que proporciona el motor de base de datos Microsoft Jet:
Al crear la tabla, con la instruccin CREATE TABLE.
Con la instruccin ALTER TABLE.
Con la instruccin CREATE INDEX.
Con cualquiera de las tres formas se puede crear un ndice, aunque existen diferencias entre elllas.
Mediante las instrucciones CREATE TABLE o ALTER TABLE, podemos aadir una clave externa para
exigir la integridad referencial de los datos, debiendo utilizar para ello una clusula CONSTRAINT. Esta
clusula no es necesario especificarla si utilizamos la instruccin CREATE INDEX, aunque no podremos
entonces exigir la integridad referencial.
No es necesario crear el ndice mediante la instruccin CREATE TABLE, por lo que primero podemos
crear la tabla con dicha instruccin, y posteriormente agregar los ndices a la tabla mediante la
instruccin ALTER TABLE o CREATE INDEX.
Hacer la salvedad que dichas instrucciones solo se pueden utilizar para crear ndices en bases de datos
Microsoft Access, que son las bases de datos nativas del motor Microsoft Jet.

34
Prof. : Cesar Arce J.
Con la instruccin CC#AT# TA-L#
Puede utilizar la sintaxis de una restriccin (CONSTRAINT) de un solo campo en la clusula de definicin
de campo de una instruccin CREATE TABLE, definindola inmediatamente despus de la especificacin
del tipo de datos del campo.
Utilice la sintaxis de restriccin de mltiples campos siempre que utilice la palabra reservada
CONSTRAINT fuera de la clusula de definicin de campo en una instruccin CREATE TABLE.
El siguiente ejemplo crear un ndice de un nico campo que a su vez ser la clave principal de la tabla:
CREATE TABLE Clientes (
IdCliente INTEGER CONSTRAINT CIavePrincipal PRIMARY KEY,
Nombre TEXT (50) WITH COMP NOT NULL)
A continuacin crearemos un ndice de varios campos el cual no podr contener valores duplicados:
CREATE TABLE Clientes (
Nombre TEXT (50) WITH COMP,
IdCliente INTEGER7
CONSTRAINT IndiceClientes UNIQUE (Nombre, IdCliente))
La diferencia existente entre crear un ndice de un nico campo y un ndice de varios campos est en
que, para el ndice de un slo campo, la clusula CONSTRAINT debe aparecer inmediatamente despus
de la especificacin del campo indexado, y para el ndice de varios campos dicha clusula debe aparecer
fuera de la instruccin CREATE TABLE, estando separada de sta por una coma.

Con la instruccin ALT#C TA-L#
Si la tabla ya existe, tambin podemos aadir un ndice utilizando la clusula CONSTRAINT con la
instruccin ALTER TABLE, la cul utiliza la siguiente sintaxis:
ALTER TABLE tabla ADD CONSTRAINT $ndice
{PRIMARY KEY(principal1[,principal2[,...]]) |
UNIQUE (&nico1[,&nico2[,...]]) |
FOREIGN KEY (ref1[,ref2[,...]]) REFERENCES tabla*xterna[(campo*xterno1[,campo*xterno2[,. ..]])]}
El siguiente ejemplo crear la clave principal de una tabla ya existente:
ALTER TABLE Empleados ADD CONSTRAINT ClavePrincipal PRIMARY KEY (IdEmpleado)
A continuacin crearemos un ndice nico formado por mltiples campos de una tabla existente:
ALTER TABLE Alumnos ADD CONSTRAINT NombreCompleto UNIQUE (Nombre, Apellidos)
Por ltimo creamos una relacin de uno a varios entre la tabla Facturas (tabla principal) y Albaranes
(tabla externa):
ALTER TABLE Albaranes
ADD CONSTRAINT NumAlbaranes
FOREIGN KEY (NumFactura) REFERENCES Facturas (IdFactura)
ON UPDATE CASCADE
ON DELETE CASCADE

35
Prof. : Cesar Arce J.
Con la instruccin CC#AT#...'.D#D
Una vez que la tabla ya exista en nuestra base de datos, podemos crear un ndice utilizando la siguiente
sintaxis:
CREATE [UNIQUE] INDEX ndice
ON tabla (campo [ASC|DESC][, campo [ASC|DESC], ...])
[WITH {PRIMARY | DISALLOW NULL | IGNORE NULL}]
En el momento de crear el ndice podemos especificar que se cumplan ciertas reglas de validacin de
datos mediante la clusula opcional WITH, la cual puede incluir las siguientes palabras clave:
PRIMARY, significa que el campo es la clave principal de la tabla.
DISALLOW NULL, indica que todos los campos que conforman el ndice deben rellenarse, por lo
que el campo no se puede dejar en blanco.
IGNORE NULL, si se especifica, indica que el registro no se indexar si el campo est en blanco.
Las tres clusulas se pueden especificar a la misma vez (WITH PRIMARY DISALLOW NULL IGNORE
NULL), pero debe saber que si se especifica PRIMARY, ya se incluye en el ndice el valor UNIQUE y
DISALLOW NULL, debido a que los valores que conforman la clave principal ser nicos y no podrn
dejarse en blanco. En cuanto a las clusulas DISALLOW NULL e IGNORE NULL, debe tener en cuenta lo
siguiente:
S' '/.OC# .0LL es " D'SALLOE .0LL es #ntonces
True False Valor NULL permitido; no se aade ninguna entrada al
ndice.
False False Valor NULL permitido; se aade una entrada al ndice.
True o False True Valor NULL no permitido; no se aade ninguna entrada
al ndice.
Si no se especifica la clusula WITH se crear un ndice donde se admiten entradas duplicadas.
El siguiente ejemplo crear un ndice donde se permitir entradas duplicadas en el campo IdCliente:
CREATE INDEX Mi_Indice ON Clientes (IdCliente)
A continuacin, aadimos un ndice con la clusula WITH donde no se podr aadir a la tabla ningn
registro cuyo campo IdCliente est vaco:
CREATE UNIQUE INDEX Mi_Indice ON Clientes (IdCliente) WITH DISALLOW NULL

Cmo eliminar un &ndice
Una vez creada la tabla y sus correspondientes ndices, puede que nos resulte necesario eliminar algn
ndice, bien de la tabla o de una relacin existente, por lo que el lenguaje SQL del motor Microsoft Jet
pone a nuestra disposicin dos instrucciones para llevar a cabo tal cometido. Pero antes de estudiar por
separado la sintaxis de cada una de ellas, conviene indicar las observaciones a tener en cuenta cuando
vaya a ejecutar una consulta de eliminacin de ndice:
Con ninguna de las dos instrucciones se puede eliminar ms de un ndice a la vez.
Debe de cerrar la tabla antes de proceder a la eliminacin de un ndice. Si es una relacin
existente la que desea eliminar, procure que no se encuentre abierta ninguna de las tablas que
conforma la relacin.
36
Prof. : Cesar Arce J.
Si desea eliminar la clave principal de una tabla que forma el lado uno de una relacin de uno a
varios, deber primero eliminar la relacin existente, dado que no le estar permitido eliminar
el ndice activo que forme parte de una relacin, tanto si sta es de uno a varios como si la
relacin lo es de uno a uno.
Si desea eliminar una relacin, unicamente lo podr hacer con la instruccin ALTER TABLE.

Con la instruccin ALT#C TA-L#
Para eliminar un ndice con la instruccin ALTER TABLE, utilice la siguiente sintaxis:
ALTER TABLE nombre'abla DROP CONSTRAINT nombre8ndice
Seguidamente voy a exponer un ejemplo para eliminar la clave principal de la tabla Facturas. Pero
recuerde que dicha clave es el ndice activo (el lado uno) de la relacin )umlbaranes creada en un
ejemplo anterior, por lo que previamente tendremos que eliminar la relacin para poder eliminar la clave
principal de la tabla:
' Eliminamos la relacin existente
ALTER TABLE Albaranes DROP CONSTRAINT NumAlbaranes
' Eliminamos la clave principal
ALTER TABLE Clientes DROP CONSTRAINT ClavePrincipal

#liminar un &ndice con la instruccin DCO5 '.D#D
Recuerde que esta instruccin no permite eliminar una relacin existente. Si se decide por ejecutar la
instruccin DROP INDEX para llevar a efecto la eliminacin de un ndice, utilice esta sintaxis:
DROP INDEX nombre8ndice ON nombre'abla
A continuacin eliminaremos el ndice multicampos creado anteriormente:
ALTER TABLE Alumnos DROP CONSTRAINT NombreCompleto
El siguiente ejemplo utilizar ADO .NET para establecer una conexin con una base de datos Microsoft
Access y ejecutar una consulta SQL, que en ste caso servir para eliminar la relacin de uno a varios
existente entre la tabla 4acturas (tabla principal) y lbaranes (tabla externa), as como las claves
principales de dichas tablas. La misma sintaxis SQL se puede utilizar tambin con el mtodo #+ecute
del objeto Connection (ADO) y del objeto Database (DAO):
Imports System.Data.OleDb
Dim cnn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim SQL As String
Try
' Configuramos y abrimos la conexin
With cnn
.ConnectionString = _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Bd1.mdb"
.Open()
End With
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al abrir la conexin", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
37
Prof. : Cesar Arce J.
cnn.Close()
Exit Sub

End Try
' Creo la cadena SQL para eliminar la relacin
SQL = "ALTER TABLE Albaranes DROP CONSTRAINT FacturasAlbaranes"
Try
' Configuramos el objeto Command y ejecutamos la consulta
With cmd
.Connection = cnn
.CommandText = SQL
.CommandType = CommandType.Text
.ExecuteNonQuery()
End With
MessageBox.Show("Se ha eliminado la relacin.", _
"ALTER TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al intentar eliminar la relacin.", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
' Creo la cadena SQL para eliminar la clave principal
SQL = "ALTER TABLE Albaranes DROP CONSTRAINT ClavePrincipal"
Try
' Ejecutamos la consulta
cmd.CommandText = SQL
cmd.ExecuteNonQuery()
MessageBox.Show("Se ha eliminado la clave principal de la tabla Albaranes.", _
"ALTER TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al intentar eliminar la clave principal.", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
' Creo la cadena SQL para eliminar la segunda clave principal
SQL = "DROP INDEX ClavePrincipal ON FACTURAS"
Try
' Ejecutamos la consulta
cmd.CommandText = SQL
cmd.ExecuteNonQuery()
MessageBox.Show("Se ha eliminado la clave principal de la tabla Facturas", _
"DROP INDEX", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al intentar eliminar la clave principal.", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
' Cerramos la conexin
cnn.Close()
38
Prof. : Cesar Arce J.
Cap&tulo 6. Consultas de seleccin


Descargar (137 KB)

Contenido
'ntroduccin
La instruccin S#L#CT
Consultas bsicas
#speci(icar el ori!en de los datos
Cecuperar in(ormacin de una base de datos e+terna
#speci(icar un alias para el nombre de los campos
%iltrado " ordenacin de los resuitados
Omitir re!istros duplicados? predicados D'ST'.CT " D'ST'.CTCOE
Seleccionar un nFmero de re!istros? precidado TO5
Criterios de seleccin
La clusula E:#C#
#l operador '.
#l operador -#TE##.
#l operador L';#
#l operador 'S .0LL
A!rupamiento de re!istros
Las (unciones a!re!adas CO0.T7 MAD7 M'. " S0M
La clusula /CO05 -G
La clusula :A6'./
Ordenar los re!istros de1ueltos
La instruccin E'T: OE.#CACC#SS O5T'O.

'ntroduccin
Las consultas de seleccin pueden representar el porcentaje ms elevado de consultas SQL que se
efectan a una base de datos, de ah que cobre un especial protagonismo dentro de las operaciones
correspondientes al 9enguaje de /anipulacin de #atos (DML) de SQL, y se utilizan mayormente para
recuperar, actualizar o eliminar registros de las tablas. Para realizar estas operaciones se pueden utilizar
diversas instrucciones SQL, siendo la ms utilizada la correspondiente a la instruccin SELECT.
En este captulo se estudiar la estructura general correspondiente a la instruccin SELECT, dejando
para posteriores captulos el estudio de otros tipos de consultas de seleccin ms complejas, como las
que se refieren a la subconsultas, combinaciones, consultas de referencias cruzadas y consultas de
unin.

39
Prof. : Cesar Arce J.
La instruccin S#L#CT
La instruccin SELECT se utiliza para recuperar la informacin almacenada en una base de datos,
informacin sta que es devuelta en forma de conjunto de registros para posteriormente ser
manipulados por los distintos objetos de acceso a datos existentes, o bien, para presentar y crear
informes a partir de los datos recuperados. En ningn caso puede modificar los datos de la base de
datos mediante la instruccin SELECT.
La estructura general de la instruccin SELECT es la siguiente:
SELECT lista%campos
FROM nombres%tablas IN nombre%base%datos%externa
WHERE condiciones%b&s+ueda
GROUP BY lista%campos
HAVING grupo%criterios
ORDER BY lista%campos
WITH OWNERACCESS OPTION

Consultas bsicas
La sintaxis bsica de la instruccin SELECT es la siguiente:
SELECT * FROM nombre_tabla
Con dicha instruccin recuperaramos todos los campos de todos los registros de la tabla especificada,
debido a que el predicado por defecto de la instruccin SELECT es la palabra clave ALL, por lo que no
es necesario especificar dicha palabra clave si nuestra intencin es recuperar todos los registros de la
tabla.
El mismo resultado se producira utilizando las siguientes sintaxis:
SELECT ALL * FROM nombre_tabla
SELECT [nombre_tabla].* FROM nombre_tabla
El asterisco significa que se desea recuperar todos los campos o columnas de la tabla o tablas
especificadas. Si no desea recuperar todas las columnas de la tabla tendr que especificar los nombres
de los campos que se mostrarn separados por comas, apareciendo estos en el orden en que los haya
especificado en el consulta de seleccin:
SELECT IdCliente, [Nombre Cliente] FROM Clientes
Si el nombre del campo incluye un espacio en blanco, deber de encerrar el nombre de la columna entre
corchete [].

#speci(icar el ori!en de los datos
Toda instruccin SELECT deber de tener una clusula FROM que indicar la tabla o tablas de origen de
los registros que se recuperarn.
Si el nombre del campo se encuentra incluido en dos o ms tablas de las especificadas en la clusula
FROM, deber de precederlo con el nombre de la tabla y de un punto, tal y como se muestra en el
siguiente ejemplo:
40
Prof. : Cesar Arce J.
SELECT Facturas.IdCliente, Nombre
FROM Clientes, Facturas
WHERE Facturas.IdCliente = CIientes.IdCliente
Cuando la clusula FROM incluye varias tablas, no importa el orden en el que aparecen las mismas.

Cecuperar in(ormacin de una base de datos e+terna
Al igual que podemos recurperar datos de una tabla de la base de datos actual, tambin podemos
recuperar los registros existentes en una base de datos externa, tanto si es otra base de datos Microsoft
Access como si se trata de otro origen de datos distinto al que se pueda conectar el motor de datos
Microsoft Jet, como bien pudiera ser una base de datos dBASE, una hoja de clculo Excel o un simple
archivo de texto delimitado.
Para conectarse a un origen de datos externo se utiliza la clusula IN, que generalmente aparece tras el
nombre de la tabla especificada en la clusula FROM, si se refiere a la tabla de origen, o tras el nombre
de la tabla definida en la clusula INTO, cuando se trata de la tabla de destino incluida en una base de
datos externa. Slo se puede utilizar la clusula IN para conectarse a una nica base de datos externa a
la vez.
Tras la clusula IN deber de especificar la ruta de acceso al origen de datos, disponiendo de varias
sintaxis para especificar la misma dependiendo de que los datos externos se refieran a una tabla de
origen o a una tabla de destino.
Dos maneras de especificar una tabla de origen en una base de datos externa Microsoft Access:
SELECT * FROM Clientes IN @@[C:\Mis documentos\Neptuno.mdb]
SELECT * FROM Clientes IN @C:\Mis documentos\Neptuno.mdb@
Dos formas distintas de especificar una tabla de destino correspondiente a un archivo de texto:
SELECT * INTO CIientes#txt IN @@[TEXT;DATABASE=C:\Mis documentos] FROM Clientes
SELECT * INTO CIientes#txt IN @C:\Mis documentos\' 'TEXT;@ FROM Clientes
Cualquiera de las dos consultas de creacin de tabla anteriores, crearn un nuevo archivo de texto en la
ruta especificada con los datos de la tabla Clientes.
Cuando vaya a trabajar con datos externos, es recomendable adjuntar la tabla a la base de datos en
lugar de especificar una clusula IN que haga referencia a la misma tabla, a fin de obtener un mejor
rendimiento a la hora de ejecutar una consulta SQL de seleccin.

#speci(icar un alias para el nombre de los campos
Como ya se ha indicado anteriormente, al recuperar los datos de una tabla mediante la instruccin
SELECT, estos son devueltos en la tpica estructura relacional de filas y columnas, teniendo los campos
los mismos nombres que los especificados en la tabla de procedencia. Si desea asignar un nombre de
columna diferente o alternativo a fin de hacer ms descriptivo el campo recuperado, deber de indicarlo
mediante la clusula AS, la cual se incluir a continuacin del nombre del campo.
El siguiente ejemplo utiliza el ttulo [Num Seguridad Social] como alternativa al campo de la tabla NSS:
SELECT NSS AS [Num Seguridad Social] FROM Empleados
41
Prof. : Cesar Arce J.

%iltrado " ordenacin de los resultados
Con la consulta bsica de seleccin, lo nico que podemos hacer es recuperar todos los campos y
registros de la tabla especificada, y en el mismo orden en el que fueron agregados a la misma. Si
deseamos recuperar ciertos registros que cumplan con una condicin dada, as como el orden en el que
aparecern en la consulta, el lenguaje SQL nos proporciona varias palabras clave que actuarn de
predicados de la instruccin SELECT, como tambin clusulas opcionales que nos permitirn depurar y
ordenar el conjunto de resultados.
Un predicado es una clusula SQL que califica una instruccin SELECT, y siempre debern de declararse
antes de la lista de campos. Los predicados pueden restringir a un ms el conjunto de registros
devueltos, filtrando en algunos casos los datos duplicados que puedan existir.
El nico predicado utilizado hasta ahora es el que acta como predeterminado, el cual recae sobre la
palabra clave ALL, lo que significa que no ser necesario especificarla si deseamos recuperar todos los
registros de la tabla. A continuacin pasaremos a estudiar con mayor detalle los predicados y clusulas
que ms se utilizan con la instruccin SELECT.

Omitir re!istros duplicados? predicados D'ST'.CT " D'ST'.CTCOE
Mediante la palabra clave DISTINCT evitaremos que en la consulta de seleccin aparezcan registros con
datos duplicados en una columna seleccionada, apareciendo nicamente un solo registro de todos
aquellos que se encuentren duplicados.
Por ejemplo, podemos tener una tabla de Facturas donde apareceran los identificadores de clientes que
nos han efectuado alguna compra. Si algn cliente nos ha realizado compras en varias ocasiones, tendr
tantas facturas como compras haya efectuado, por lo que el identificador del cliente se repetir en varios
registros de la tabla Facturas.
Si deseamos consultar los clientes que al menos nos han realizado una compra, ejecutaramos la
siguiente consulta de seleccin:
SELECT DISTINCT [IdCliente] FROM Facturas
Si omitiramos DISTINCT, la consulta devolvera todas las facturas existentes en la tabla, por lo que no
obtendramos el resultado esperado. Por tanto, eliminando los registros que contengan el mismo
identificador de cliente, obtendremos los clientes que alguna vez nos han efectuado una compra.
Para que la consulta de seleccin sea efectiva, deber de especificar un nico campo en la consulta de
seleccin, campo este que se corresponder con la columna de la tabla donde aparecen datos
duplicados. Si especifica ms de un campo, la consulta omitir los registros cuyos valores se encuentren
duplicados en todos los campos especificados, porque el solo hecho de que un campo de los
especificados no aparezca duplicado, es ms que suficiente para que la consulta devuelva todos los
registros existentes en la tabla, tal y como se puede comprobar ejecutando la siguiente consulta de
seleccin, la cual devolver todos los registros de la tabla Facturas, ya que es poco probable que todos
los clientes hayan efectuado sus compras en la misma fecha:
SELECT DISTINCT IdCliente, [Fecha Factura] FROM Facturas
El conjunto de registros devueltos estar ordenado ascendentemente de manera predeterminada. Si el
resultado de la consulta DISTINCT lo utiliza para abrir un objeto del tipo Recordset, ste ser de slo
lectura, lo que significa que no se podr actualizar y no reflejar las actualizaciones efectuadas
posteriormente por otros usuarios.
42
Prof. : Cesar Arce J.
A diferencia del predicado DISTINCT, que se basa en la duplicidad de campos individuales, el predicado
DISTINCTROW se basa en filas enteras de registros, siempre y cuando se utilice en una consulta de
seleccin que afecte a varias tablas, lo que se conoce como una consulta de combinacin, de esta
manera, no solo se omiten los campos duplicados, sino que se omitirn los registros completos que se
encuentren duplicados en la combinacin efectuada.
Por ejemplo, si aparte de conocer el identificador del cliente, deseamos conocer tambin los nombres de
los clientes que al menos han efectuado una compra, deberamos de combinar las tablas Clientes y
Facturas mediante el campo comn IdCliente:
SELECT DISTINCTROW Clientes.Nombre, Clientes.IdCliente
FROM Clientes
INNER JOIN Facturas ON Clientes.IdCliente = Facturas.IdCliente
Si se omite el predicado DISTINCTROW, la consulta devolvera todos los registros de la tabla Facturas,
por lo que los nombres de los clientes apareceran duplicados, dado que un cliente puede tener varias
facturas. DISTINCTROW es efectivo cuando se utiliza nicamente para seleccionar campos de algunas,
pero no todas, de las tablas utilizadas en la consulta, y no se tiene en cuenta el predicado si la consulta
afecta solo a una tabla. De manera predeterminada, el conjunto de registros devueltos no tiene un
orden determinado en concreto.

Seleccionar un nFmero de re!istros? predicado TO5
La palabra clave TOP es utilizada para devolver un cierto nmero de registros que figuren en la parte
superior o inferior de un intervalo especificado por una clusula ORDER BY. De no especificarse ninguna
clusula ORDER BY, se recuperar el nmero de registros indicados que figuren almacenados al inicio de
la tabla, que es el valor por defecto, o un nmero arbitrario de registros que satisfagan lo indicado en
una clusula WHERE.
Si por ejemplo, queremos efectuar una consulta para conocer las 10 facturas de mayor importe,
escribiramos lo siguiente:
SELECT TOP 10 * FROM Facturas ORDER BY [Total Factura] DESC
El predicado TOP no selecciona entre valores iguales. Si en el ejemplo anterior, las facturas con orden
10 y 11 tienen el mismo importe, la consulta devolver 11 registros. Si en lugar de seleccionar un
nmero de registros deseamos recuperar un porcentaje determinado de registros que figuren en la parte
superior o inferior del intervalo especificado en la clusula ORDER BY, deberemos de especificar la
palabra clave PERCENT.
Continuando con el ejemplo anterior, si en lugar de seleccionar las 10 facturas de mayor importe,
deseamos conocer el 10 por ciento de las facturas con mayor importe, ejecutaramos la siguiente
consulta:
SELECT TOP 10 PERCENT * FROM Facturas ORDER BY [Total Factura] DESC

Criterios de seleccin
Anteriormente hemos visto la forma de recuperar todos los registros, o un nmero limitado de ellos,
segn lo indicado en el predicado utilizado. A continuacin vamos a estudiar la forma de filtrar los
registros para recuperar nicamente aquellos que cumplan con una condicin especificada mediante una
clusula, que recordamos que es la condicin de modificacin utili5ada para definir los datos +ue
deseamos seleccionar o manipular.
43
Prof. : Cesar Arce J.
Pero antes de entrar en detalle con las distintas clusulas existentes, conviene destacar tres detalles a
tener en cuenta a la hora de especificar el criterio de seleccin, y que son las siguientes:
No es posible especificar una condicin de bsqueda en campos del tipo texto largo o Memo.
Si la condicin de bsqueda se refiere a valores contenidos en campos de la tabla del tipo
alfanumrico, deber encerrar entre comillas simples dicha condicin de bsqueda.
Por ltimo, se encuentra la consulta que genera ms nmero de dudas e inquietudes entre los
usuarios de los distintos grupos de noticias de Microsoft donde participo, y es la que se refiere a
especificar el criterio de bsqueda cuando el campo es del tipo Fecha.
Aunque hay muchos formatos y modos de especificar una fecha, siempre (y lo recalco de nuevo,
SIEMPRE) se deber de utilizar el formato de fecha de Estados Unidos (mes/da/ao), aunque no
utilice la versin norteamericana del motor de base de datos Microsoft Jet, a fin de asegurarnos
un buen uso del criterio de bsqueda indicado. Asimismo, deber de incluir el literal de fecha
encerrado entre el smbolo del signo nmerico (#), tal y como se muestra en el siguiente
ejemplo.
Si deseamos buscar los registros con fecha 19 de marzo de 2004 en una base de datos de
Espaa, Francia o Alemania, deberemos ejecutar la siguiente consulta SQL de seleccin:
SELECT * FROM Facturas WHERE [Fecha Factura] = #3/19/04#
Si utiliza Microsoft Visual Basic, tambin puede especificar como criterio de bsqueda, el
resultado devuelto por la funcin Date6alue, la cual tiene en cuenta la configuracin regional
establecida en Microsoft Windows. De esta manera, la consulta para una base de datos de
Estados Unidos sera:
SELECT * FROM Facturas WHERE [Fecha Factura] = DateValue('3/19/04')
Y para una base de datos de Espaa utilizaramos la sintaxis siguiente:
SELECT * FROM Facturas WHERE [Fecha Factura] = DateValue('19/3/04')
La siguiente tabla muestra los formatos vlidos para especificar un criterio de fecha
correspondiente al 19 de marzo de 2004. Cualquier otro formato distinto que se utilice no servir
para recuperar los registros deseados:
#3/19/04# #3-19-04#
#19/3/2004# H #19-3-2004#
#3/19/2004# #3-19-2004#
#2004/3/19# #2004-3-19#
#03/19/04# #03-19-04#
#19/03/2004# H #19-03-2004#
#03/19/2004# #03-19-2004#
#2004/03/19# #2004-03-19#
H Estos formatos se pueden utilizar siempre y cuando la fecha correspondiente al da del mes sea
superior al da 12; si es inferior, el motor Jet tomar el valor del da como si fuera el valor del
mes.
Vuelvo a insistir que, si no desea memorizar todos los formatos de fecha posibles, recuerde al
menos el formato estndar de Estados Unidos: #mes/da/ao# (#03/19/04#).

44
Prof. : Cesar Arce J.
La clusula E:#C#
La clusula WHERE se utiliza para especificar qu registros de las tablas indicados en la clusula FROM
cumplen con las condiciones enumeradas, y por tanto, se debern de incluir en el resultado devuelto por
la instruccin SELECT. Si no se especifica una clusula WHERE, la consulta devolver todos los registros
existentes en la tabla.
Si especifica dos o ms tablas en la clusula FROM de su consulta de seleccin y no incluye una clusula
WHERE o JOIN, la consulta generar un producto cartesiano de las tablas. Tambin deber de tener en
cuenta no olvidar incluir una clusula JOIN cuando realice combinaciones SQL entre mltiples tablas,
porque si bien la clusula WHERE puede realizar una tarea similiar, el incluir esta ltima clusula dara
lugar a que el conjunto de datos resultante de la seleccin no fuera actualizable.
La palabra clave WHERE es opcional, pero si se especifica, necesariamente tendr que aparecer despus
de la clusula FROM, tal y como se muestra en los siguientes ejemplos:
Seleccionamos todos los empleados del departamento de Ventas
SELECT * FROM Empleados WHERE Departamento = 'Ventas'
Seleccionamos todos los empleados cuya edad este comprendida entre 20 y 30 aos
SELECT * FROM Empleados WHERE Edad BETWEEN 20 AND 30
Cuando existen dos condiciones para evaluar, el resultado de la operacin vara en funcin del operador
lgico utilizado. El lenguaje SQL de Microsoft Jet soporta los siguientes operadores lgicos: AND, OR,
XOR, EQV, IMP, IS y NOT. A excepcin de los dos ltimos, todos los dems presentan la siguiente
sintaxis:
<expresin1> operador <expresin2>
La siguiente tabla muestra los diferentes resultados posibles en funcin del resultado individual de cada
expresin y del operador lgico utilizado:
Ie+presin1J Operador Ie+presin2J Cesultado
Verdad AND Falso Falso
Verdad AND Verdad Verdad
Falso AND Verdad Falso
Falso AND Falso Falso
Verdad OR Falso Verdad
Verdad OR Verdad Verdad
Falso OR Verdad Verdad
Falso OR Falso Falso
Verdad XOR Verdad Falso
Verdad XOR Falso Verdad
Falso XOR Verdad Verdad
Falso XOR Falso Falso
Verdad EQV Verdad Verdad
Verdad EQV Falso Falso
Falso EQV Verdad Falso
Falso EQV Falso Verdad
Verdad IMP Verdad Verdad
Verdad IMP Falso Falso
45
Prof. : Cesar Arce J.
Verdad IMP Null Null
Falso IMP Verdad Verdad
Falso IMP Falso Verdad
Falso Imp Null Verdad
Null IMP Verdad Verdad
Null IMP Falso Null
Null IMP Null Null
Si anteponemos el operador NOT a cualquiera de los condiciones especificadas anteriormente, el
resultado de la operacin ser el contrario al devuelto sin el operador NOT.
El operador IS se emplea para comparar dos variables del tipo objeto. Este operador devuelve
Verdadero si los dos objetos son iguales:
<Objeto> IS <Objeto>
A continuacin se muestran varias consultas de seleccin donde el resultado se ver alterado por las
expresiones evaluadas mediante los correspondientes operadores lgicos.
Seleccionamos todos los empleados cuya edad este comprendida entre 20 y 30 aos:
SELECT * FROM Empleados WHERE Edad > 19 AND Edad < 31
Seleccionamos todos los empleados comprendidos en un intervalo de Edad cuyo Sueldo sea superior a
1.000,00 euros:
SELECT * FROM Empleados WHERE (Edad > 19 AND Edad < 31) AND Sueldo > 1000.00
Seleccionamos todos los empleados que se encuentren casados:
SELECT * FROM Empleados WHERE NOT Estado = 'Soltero'
Seleccionamos todos los empleados cuyo sueldo est comprendido exactamente entre 1000 y 2000
euros, o se encuentren en Madrid y estn casados:
SELECT * FROM Empleados WHERE (Sueldo > 999.99 AND Sueldo < 2000.01) OR (Ciudad = 'Madrid'
AND Estado = 'Casado')

#l operador '.
Podemos utilizar el operador IN para recuperar aquellos registros donde el valor del campo se
corresponda con un valor de los incluidos en una lista de valores. Si la expresin coincide con un valor
de la lista, el operador IN devolver Verdadero; en cualquier otro caso, retornar Falso. La sintaxis del
operador IN es la siguiente:
expresin [NOT] IN (valor1, valor2, ..., valor))
Por ejemplo, deseamos recuperar todos aquellos empleados que residan en las provincias de Madrid,
Barcelona y Jan. Para ello escribiremos la siguiente consulta SQL de seleccin:
SELECT * FROM Empleados WHERE Provincia IN ('Madrid', 'Barcelona', 'Jan')
46
Prof. : Cesar Arce J.
Si anteponemos el operador lgico opcional NOT, lo que haremos ser verificar lo contrario del operador
IN. Si deseamos seleccionar los empleados que no residen en las provincias anteriormente
mencionadas, escribiremos:
SELECT * FROM Empleados WHERE Provincia NOT IN ('Madrid', 'Barcelona', 'Jan')

#l operador -#TE##.
Si deseamos especificar un intervalo concreto de valores de un campo, en lugar de utilizar operadores
lgicos podemos emplear el operador BETWEEN, cuya sintaxis es la siguiente:
campo [NOT] BETWEEN valor1 AND valor2
En este supuesto la consulta de seleccin devolvera los registros que contengan en campo un valor
comprendido en el intervalo valor1 y valor2, ambos inclusive. Si anteponemos la condicin opcional NOT,
devolver aquellos valores no incluidos en el intervalo.
Debo de hacer la salvedad para indicar que el lenguaje SQL de Microsoft Jet permite que valor1 sea
mayor que valor2 en la sintaxis del operador BETWEEN, lo que no sucede en el SQL de ANSI, donde
valor1 debe ser igual o menor que valor2. Esto puede representar un obstculo si utiliza orgenes de
datos ODBC, en cuyo caso siempre deber especificar el intervalo de valor1 a valor2.
Algunos de los ejemplos anteriormente vistos, tambin se podran haber escrito de la siguiente manera.
Seleccionamos todos los empleados cuya edad este comprendida entre 30 y 20 aos:
SELECT * FROM Empleados WHERE Edad BETWEEN 30 AND 20
Seleccionamos todos los empleados comprendidos en un intervalo de Edad cuyo Sueldo sea superior a
1.000 euros:
SELECT * FROM Empleados WHERE (Edad BETWEEN 20 AND 30) AND Sueldo > 1000.00
Seleccionamos todos los empleados cuyo sueldo est comprendido exactamente entre 1000 y 2000
euros, o se encuentren en Madrid y estn casados:
SELECT * FROM Empleados WHERE (Sueldo BETWEEN 1000.00 AND 2000.00) OR (Ciudad = 'Madrid'
AND Estado = 'Casado')
Seleccionamos todos los empleados residentes en Madrid:
SELECT * FROM Empleados WHERE Ciudad = IIF(CPostal BETWEEN 28000 AND 28999, 'Madrid',")

#l operador L';#
El operador LIKE se utiliza para comparar una expresin de cadena con un modelo especificado,
recuperndose nicamente aquellos registros que satisfagan el criterio de caracteres indicados en el
modelo de coincidencia. La sintaxis del operador LIKE es la siguiente:
expresin LIKE modelo
47
Prof. : Cesar Arce J.
*xpresin se refiere al nombre del campo de la tabla que se desea comparar. /odelo puede referirse a
una expresin de cadena formada por un valor completo o por una lista de caracteres comodn
permitidos que se indicarn posteriormente.
El SQL de Microsoft Jet es compatible con caracteres comodn del SQL de ANSI y con caracteres comodn
especficos de Microsoft Jet para ser utilizados junto con el operador LIKE. El uso de caracteres comodn
ANSI y Microsoft Jet se excluyen mutuamente, por lo que podr utilizar un conjunto o el otro, pero
nunca mezclarlos.
Es importante que conozca el conjunto de carcteres comodn que puede utilizar, sobretodo cuando
utiliza Jet 4.x y el proveedor Microsoft OLE DB para Jet, dado que en este caso nicamente estarn
disponibles los caracteres comodn del SQL de ANSI. Si intenta utilizar caracteres comodn del SQL de
ANSI mediante la interfaz de usuario de Microsoft Access o con la biblioteca de DAO, los caracteres
comodn sern interpretados como caracteres literales. Sucede lo mismo a la inversa, cuando utiliza Jet
4.x y el proveedor Microsoft OLE DB para Jet, ya que en este caso se interpretarn como literales los
caracteres comodn que pertenezcan al conjunto de caracteres comodn del SQL de Microsoft Jet.
Esto se debe a que el SQL del motor de base de datos Microsoft Jet suele ajustarse a la norma ANSI-89
de nivel1, por lo que ciertas caractersticas del SQL de ANSI no se encuentran implementadas en el SQL
de Microsoft Jet. A partir del lanzamiento de Microsoft Jet versin 4.x, el proveedor Microsoft OLE DB
para Jet introdujo ms sintaxis ANSI-92 SQL, de ah que el SQL de Microsoft Jet se ajuste ms a la
norma estndar cuando se utiliza nicamente con el proveedor Microsoft OLE DB para Jet. Igualmente
sucede a la inversa, el SQL de Microsoft Jet incluye palabras reservadas y caractersticas que no estn
permitidas en el SQL de ANSI.
Los modelos de coincidencia incorporados proporcionan una herramienta verstil para realizar
comparaciones de cadenas. En la siguiente tabla se muestran los caracteres comodn que puede utilizar
con el operador LIKE, el nmero de dgitos o cadenas que comparan y las diferencias existentes entre
los dos tipos de lenguajes SQL, en cuanto a caracteres comodn se refiere:
Caracteres coincidentes
Caracteres comod&n
SQL de Microso(t )et SQL de A.S'
Cualquier carcter ? _ (signo de subrayado)
Cero o ms caracteres * %
Cualquier nmero #
Cualquier carcter que est en lista(aracteres [lista(aracteres]
Cualquier carcter que no est en lista(aracteres [:lista(aracteres]
En el argumento lista(aracteres puede indicar un grupo de uno o ms caracteres entre corchetes ([ ])
para que coincida con cualquier carcter de los indicados en la expresin especificada, teniendo la
posibilidad de incluir prcticamente cualquier carcter incluido en el juego de caracteres ANSI, incluidos
los dgitos, haciendo aqu una salvedad, que ms tarde se comentar, en lo que respecta al carcter de
signo numrico (#) cuando se utiliza Jet 4.x y el proveedor Microsoft OLE DB para Jet.
Asimismo, en lista(aracteres puede indicar un intervalo de valores, separando los lmites superior e
inferior del intervalo mediante un guin (-). Por ejemplo, especificar en modelo el intervalo '[a-z]', hace
que se genere una coincidencia si la posicin del carcter de expresin contiene cualquier letra,
mayscula o minscula, comprendida entre A y Z. Dentro de los corchetes se pueden especificar
mltiples intervalos sin ningn tipo de restriccin. Por ejemplo, el modelo '[a-Z0-9]' hace que haya una
coincidencia con cualquier carcter alfanumrico indicado en la posicin correspondiente de la cadena
utilizada en expresin.
Debe de tener en cuenta que los intervalos de caracteres deben de aparecer en orden ascendente (A-Z,
0-100). '[A-Z]' es un intervalo vlido, no as '[Z-A]'.
Especificar los corchetes separados por un espacio en blanco ([ ]) ser considerado como una cadena de
longitud cero (""), por lo que nicamente servir para recuperar aquellos registros donde expresin
coincida con una cadena de longitud cero, que es distinto de un valor NULL. En este ltimo caso, los
registros se podrn recuperar mediante el operador IS NULL, como se estudiar en un apartado
posterior.
48
Prof. : Cesar Arce J.
A continuacin se exponen algunos ejemplos que muestran el uso del operador LIKE. Dado que este
manual va dirigido fundamentalmente a aquellos usuarios que trabajan mediante ADO y ADO .NET, los
ejemplos utilizaran los caracteres comodn permitidos por el proveedor Microsoft OLE DB para Jet, y que
son los que se corresponden con el SQL de ANSI:
Queremos conocer todos los apellidos de los Empleados que comienzan por la leta M:
SELECT * FROM Empleados WHERE Apellidos LIKE 'M%'
Deseamos seleccionar todos los clientes cuyo nombre empiece por la letra P, y la segunda letra est
comprendida entre la C y M, seguido por ltimo de cualquier cadena:
SELECT * FROM Clientes WHERE Nombre LIKE 'P[C-M]%'
Queremos recuperar todos los clientes cuyos nombres comiencen por las letras de la A a la D seguidas
de cualquier cadena:
SELECT * FROM Clientes WHERE Nombre LIKE '[A-D]%'
En la siguiente tabla se muestran varios modelos diferentes que utilizan el operador LIKE para
comparar varias expresiones de cadena:
Tipo de
coincidencia
Modelo
Coincidencia .o coincide
SQL A.S' SQL )et
Varios caracteres 'a%a' 'a*a' 'aa', 'aCDa', 'Abbbba''ab', 'CDa'
Un carcter especial 'a[&]a' 'a&a' 'aaa'
Varios caracteres 'ma%' 'ma*' 'malo', 'maana' 'ama', 'mmalo'
Un slo carcter 'a_a' 'a?a' 'aaa', 'a3a', 'aBa' 'aBBBa'
Un slo dgito (*) 'a[!a-z]a' 'a#a' 'a0a', 'a1a', 'a2a' 'aaa', 'a10a'
Rango de caracteres '[a-z]' 'b', 'j', 'k', 'z' '3', '$', 'ab'
Fuera de un rango '[!a-z]' '9', '&', '%' 'a', 'b', 'z', '9a'
Distinto de un dgito '[!0-9]' 'A', 'a', '&', '%' '0', '1', '9'
Combinada (*) a[!b-m][!a-z]' 'a[!b-m]#' 'An9', 'az0', 'a99' 'abc', 'aj0'
(*) Aunque en la documentacin oficial se indica que se puede utilizar el carcter de signo numrico (#),
en la prctica su funcionamiento se restringe nicamente al SQL de Microsoft Jet, y cuando se utiliza con
Microsoft Access o la biblioteca de DAO. Si utilizamos ADO junto con el proveedor Microsoft OLE DB para
Jet 4.x, el carcter de signo nmerico ser interpretado como un literal, tal y como podr comprobar en
el siguiente artculo de la Base del Conocimiento, %'D? )et >.2 Treats 9K9 as .umeric Eildcard
C,aracter, por lo que para interpretar dicho carcter numrico con el SQL de ANSI, deber sustituir el
carcter comodn numrico por un modelo que est fuera del rango de .caracteres alfabticos [!a-z],
corriendo el peligro de obtener resultados no deseados si en la expresin de comparacin existen otros
smbolos distintos a los alfabticos (%, $, &, etc.).

#l operador 'S .0LL
Un valor NULL (nulo) es aquel que indica que un campo faltan datos o son desconocidos. Los valores
NULL se pueden especificar en campos cuya informacin se desconoce, as como en expresiones y
consultas. Si utiliza Visual Basic, puede indicar un valor nulo mediante la palabra clava .ull. Debe de
49
Prof. : Cesar Arce J.
tener siempre presente que algunos campos como, por ejemplo, los definidos como clave principal de la
tabla, no pueden contener un valor nulo.
Puede utilizar el operador IS NULL para determinar si el valor de una expresin es igual a un valor nulo.
Dicho operador utiliza la siguiente sintaxis:
campo IS [NOT] NULL
Si, por ejemplo, deseamos conocer aquellos registros de clientes donde no figura su Cdigo Postal,
escribiramos la siguiente consulta SQL:
SELECT * FROM Clientes WHERE CodPostal IS NULL
Aadiendo el operador lgico opcional NOT, podemos comprobar lo contrario del operador IS NULL. En
este caso, la consulta devolver los registros de clientes que s tienen especificado su Cdigo Postal:
SELECT * FROM Clientes WHERE CodPostal IS NOT NULL

A!rupamiento de re!istros
Puede que nos interese agrupar ciertos registros que presenten un valor coincidente en el mismo campo
de la tabla definida en una clusula FROM, con el nico objetivo de presentar un informe que resuma los
datos correspondientes a los registros que cumplan con la condicin indicada en la consulta de seleccin.
Para ello, necesariamente tendremos que utilizar una funcin agregada de las permitidas por el lenguaje
SQL, a fin de recuperar en un nico valor el resultado devuelto por la funcin agregada especificada.

Las (unciones a!re!adas CO0.T7 MAD7 M'. " S0M
El lenguaje SQL incluye una serie de funciones que permiten la realizacin de clculos con un grupo de
valores pertenecientes a los distintos registros recuperados mediante una instruccin SELECT, por lo
que necesariamente deber de indicar el nombre de la funcin agregada a continuacin de la instruccin
SELECT.
A continuacin detallar las funciones agregadas ms utilizadas en SQL. Para ver una referencia de
todas las funciones que puede utilizar en SQL, consulte el tema %unciones a!re!adas en el Captulo I
de este manual.

CO0.T
Calcula el nmero de elementos devueltos por una consulta. Su sintaxis es la siguiente:
COUNT (expresin)
Donde expresin contiene el nombre o nombres de los campos que se desea calcular, y puede incluir el
nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida
por el usuario, pero en ningn caso puede especificar otra funcin agregada de SQL).
La funcin COUNT simplemente cuenta el nmero de registros existentes que coincidan con la expresin
especificada, sin tener en cuenta aquellos valores que contienen NULL, salvo que haya indicado el
carcter comodn asterisco (*), en cuyo caso, COUNT calcula el nmero total de registros devueltos por
la instruccin SELECT, incluyendo aquellos que contienen valores NULL. Utilizar el asterisco en lugar de
un nombre de campo, hace que la consulta se ejecute de una manera ms rpida.
50
Prof. : Cesar Arce J.
Si especifica mltiples campos en expresin, la funcin COUNT cuenta un registro slo si alguno de los
campos no es NULL. Si todos los campos especificados presentan valores NULL, no se contar el
registro. Deber de separar los nombres de los campos con el carcter ampersand (&).
A continuacin se muestran algunos ejemplos tiles donde puede utilizar la funcin COUNT.
Deseamos conocer el nmero de clientes con los que cuenta nuestra empresa:
SELECT COUNT (*) AS [N Clientes] FROM Clientes
El nmero de clientes residentes en Madrid:
SELECT COUNT (*) AS [Total de Residentes] FROM Clientes WHERE Ciudad = 'Madrid'
El nmero de clientes que tienen el Cdigo Postal asignado. En este caso, no se contarn los registros
cuyo campo CodPostal sea NULL:
SELECT COUNT (CodPostal) FROM Clientes
Por ltimo, vamos a seleccionar el nmero total de Clientes, y el nmero de ellos que tienen
cumplimentados los campos Telfono y Cdigo Postal, de esta forma podemos saber los que todava no
tienen asignados dichos campos:
SELECT COUNT(*) AS [N Clientes], COUNT (Telefono & CodPostal) FROM Clientes

MAD " M'.
Calculan el mximo y mnimo respectivamente de un conjunto de valores contenidos en un campo
especfico de una consulta de seleccin. Su sintaxis es:
MIN (expresin)
MAX (expresin)
Donde expresin es el campo sobre el que se desea realizar el clculo. *xpresin puede incluir el nombre
de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el
usuario pero no otras de las funciones agregadas de SQL). Si los campos seleccionados en expresin
incluyen valores NULL no se tendrn en cuenta a la hora de calcular los valores mximo y mnimo.
A continuacin se muestran algunos ejemplos tiles donde puede utilizar las funciones agregadas MAX y
MIN.
Queremos conocer el mayor identificador de cliente asignado a la tabla Clientes:
SELECT MAX(IdCliente) AS MaxIdentificador FROM Clientes
Queremos conocer el importe mayor y menor de las facturas realizadas:
SELECT MAX(Total) AS MaxFactura, MIN(Total) AS MinFactura FROM Facturas
Deseamos conocer la fecha de nacimiento de los empleados ms jvenes y ms antiguos de nuestra
empresa:
SELECT MAX(FechaNto) AS EmpleadosJovenes, MIN(FechaNto) AS EmpleadosMayores FROM Empleados
Queremos felicitar a los empleados que llevan ms tiempo trabajando en nuestra empresa de la
provincia de Jan:
SELECT MIN(FechaIncorporacion) AS Veteranos FROM Empleados WHERE Ciudad = 'Jan'
51
Prof. : Cesar Arce J.

S0M
Devuelve la suma del conjunto de valores contenidos en un campo especfico de una consulta de
seleccin. Su sintaxis es:
SUM (expresin)
Donde expresin representa el nombre del campo cuyos datos desean sumarse, o una expresin que
realiza un clculo utilizando los datos de dichos campos. Los operandos de expresin pueden incluir el
nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida
por el usuario, pero no otra funcin agregada de SQL). Si los campos seleccionados en expresin
incluyen valores NULL no se tendrn en cuenta a la hora de sumar los valores, cosa por cierto, bastante
lgica.
A continuacin se exponen algunos ejemplos tiles que muestran la utilizacin de la funcin SUM.
Deseamos conocer el importe total de las facturas emitidas:
SELECT SUM(Total) AS TotalFacturas FROM Facturas
Queremos conocer la suma de la Base, IVA y Total de todas las facturas correspondientes al segundo
trimestre del ao:
SELECT SUM(Base) AS TotalBase, SUM(IVA) As TotalIVA, SUM(Base+IVA) As Total FROM Facturas
WHERE Fecha BETWEEN #04/01/2004# AND #06/30/2004#

La clusula /CO05 -G
La clusula opcional GROUP BY generar un nico registro mediante el agrupamiento de todos los
registros que tengan un valor idntico en la lista de campos seleccionada. El registro creado contiene un
valor resumen como resultado de la funcin agregada que necesariamente tendr que especificar en la
instruccin SELECT, tal como SUM o COUNT, ya que si no existe una funcin agregada, se omitirn por
completo los valores resumen. La sintaxis de la clusula GROUP BY es la siguiente:
SELECT campos FROM nombre'abla [WHERE criterio] GROUP BY camposgrupados
Respecto de los valores NULL existentes en los campos, los mismos no se omitirn, agrupndose
igualmente como si de otro valor cualquiera se tratara, debiendo tener presente que los valores NULL no
sern evaluados por ninguna funcin agregada que haya especificado, tal y como se ha visto con
anterioridad.
Si no desea agrupar ciertos registros, podr excluirlos especificando una clusula opcional WHERE. Una
vez agrupados los registros, puede que le interese filtrar los mismos, por lo que deber de indicar una
clusula HAVING para tal cometido. La clusula HAVING se estudiar en el siguiente apartado, aunque
adelantar un ejemplo para que lo compare con la clusula WHERE.
Deseamos conocer el nmero de facturas y su importe total agrupado por el identificador del cliente, por
lo que este ser el campo que deberemos de indicar en la clusula GROUP BY, aunque no es necesario
que el campo se incluya en la instruccin SELECT:
SELECT IdCliente, Count(*) AS [N Facturas], SUM(Total) AS [Importe Total] FROM Facturas GROUP BY
IdCliente
A continuacin deseamos ver slo aquellos clientes que todas sus compras han sido realizadas en el
segundo trimestre del ao, por lo que utilizaremos la clusula WHERE para omitir los registros cuya fecha
no est comprendida en el segundo trimestre:
52
Prof. : Cesar Arce J.
SELECT IdCliente, COUNT(*) AS [N Facturas], SUM(Total) AS [Total Facturas] FROM Facturas WHERE
Fecha BETWEEN #04/01/2004# AND #06/30/2004# GROUP BY IdCliente
Advierta que solamente aparecern los registros de los clientes que hayan efectuado sus compras
exclusivamente en el segundo trimestre. Si un cliente, a pesar de haber realizado una compra en el
segundo trimestre, tiene otras compras realizadas fuera del intervalo de fechas indicadas, dichos
registros no se agruparn, por lo que no aparecern en el conjunto de registros devuelto.
Por ltimo, queremos filtrar los registros devueltos anteriormente, para conocer slo aquellos clientes
cuyas compras sean igual o superior a los 1.500 euros:
SELECT IdCliente, COUNT(*) AS [N Facturas], SUM(Total) AS [Total Facturas] FROM Facturas WHERE
Fecha BETWEEN #01/01/2004# AND #03/31/2004# GROUP BY IdCliente HAVING SUM(Total) >=
1500.00
Mediante la clusula GROUP BY puede referenciar cualquier campo de la tabla especificada en la clusula
FROM que no sea del tipo Memo u Objeto OLE, y no es necesario que dicho campo se encuentre incluido
en la instruccin SELECT, siempre que esta ltima instruccin incluya al menos una funcin agregada de
SQL. Los campos especificados en la lista de campos de la instruccin SELECT, necesariamente debern
de incluirse, o bien en la misma clusula GROUP BY, o como argumento de la funcin agregada utilizada.

La clusula :A6'./
La clusula HAVING se utiliza para filtrar los registros que se desean mostrar una vez que se hayan
agrupado con la clusula GROUP BY, siendo su sintaxis la siguiente:
SELECT campos FROM nombre'abla [WHERE criterio] GROUP BY camposgrupados HAVING
nombre(ampo = criterio
HAVING se asemeja a la clusula WHERE en el sentido de que determina los registros que se
seleccionarn, una vez que necesariamente hayan sido agrupados mediante la clusula GROUP BY.
La clusula HAVING es opcional y puede contener hasta 40 expresiones vinculadas por operadores
lgicos, como AND y OR. Los siguientes ejemplos ampliarn el uso de las clusulas GROUP BY y HAVING.
Deseamos conocer el nmero de empleados que tenemos en cada provincia, por lo que este ser el
campo de agrupamiento:
SELECT COUNT(IdEmpleado) AS Total, Ciudad FROM Empleados GROUP BY Ciudad
A continuacin, slo deseamos ver el nmero de empleados que hay en una provincia determinada, por
lo que filtraremos la seleccin agrupada indicando el nombre de la provincia:
SELECT COUNT(IdEmpleado) AS Total, Ciudad FROM Empleados GROUP BY Ciudad HAVING Ciudad =
'Jan'
Por ltimo, vamos a conocer el nmero de ventas efectuadas por un empleado en concreto. Para ello,
combinaremos las tablas Facturas y Empleados:
SELECT COUNT(IdFactura) As [N Facturas], Empleados.Nombre FROM Facturas INNER JOIN Empleados
ON Facturas.IdEmpleado=Empleados.IdEmpleado GROUP BY Nombre HAVING Nombre = 'Enrique
Martnez'

53
Prof. : Cesar Arce J.
Ordenar los re!istros de1ueltos
Una vez que los registros se encuentren seleccionados, quizs nos interese que estos aparezcan
ordenados a la hora de ser recuperados por la consulta. De esto se encarga la clusula ORDER BY,
mediante la cual podemos especificar la columna o columnas que se utilizarn como clave de
ordenacin, as como la forma ascendente o descendente en que se ordenarn los registros devueltos.
La sintaxis de la clusula ORDER BY es la siguiente:
SELECT * FROM tabla ORDER BY campo1 [ASC|DESC] [, campo2] [ASC|DESC]
El siguiente ejemplo ordenar alfabticamente todos los registros de la tabla Clientes:
SELECT * FROM Clientes ORDER BY Nombre ASC
Si deseamos ordenar los registros de forma ascendente, no es necesario indicar la palabra clave ASC, ya
que es el valor por defecto de la clusula ORDER BY. En cambio, si queremos obtener un orden
descendente (Z-A, 9-0), tendr que especificar la palabra clave DESC al final del nombre del campo que
desea ordenar de esta manera. Con respecto al orden en el que aparecern los valores NULL, estos
figurarn en primer lugar si utiliza un orden ascendente, y al final del conjunto de registros devueltos, si
los ordena de forma descendente.
En lugar de indicar el nombre del campo, si lo desea tambin puede especificar el nmero ordinal de la
columna por la que desea ordenar los registros seleccionados. Deber de tener en cuenta que el nmero
ordinal de la columna se corresponder con el orden en el que han sido escritos los nombres de los
campos en la instruccin SELECT, si se ha especificado una lista de campos; si ha utilizado el carcter
comodn de asterisco (*) para recuperar todos los campos de la tabla, el nmero ordinal se
corresponder con el nmero de orden que tiene el campo en la tabla o tablas especificadas en la
clusula FROM.
La consulta anterior tambin se puede escribir de la siguiente manera, si conoce de antemano que el
segundo campo de la tabla corresponde a la columna 'Nombre':
SELECT * FROM Clientes ORDER BY 2 ASC
Como se ha indicado con anterioridad, puede incluir varios campos en la clusula ORDER BY,
ordenndose los registros por el siguiente orden:
1. Se ordenarn por el primer campo especificado en la clusula ORDER BY;
2. Los registros que tengan el mismo valor en el primer campo, se ordenarn por la forma
indicada en el segundo campo, y as sucesivamente.
El siguiente ejemplo ordenar de forma ascendente, y por el nmero de cliente, todas las facturas
existentes. Si un mismo cliente tiene varias facturas, estas se ordenarn de forma descendente segn el
importe total de la factura:
SELECT IdCliente, IdFactura, Total FROM Facturas ORDER BY IdCliente, Total DESC
La clusula ORDER BY generalmente suele ser el ltimo elemento que se incluye en una instruccin
SELECT, y salvo que en la misma instruccin de seleccin especifique los predicados TOP o TOP n
PERCENT, tal y como se vi en su apartado correspondiente, no es necesario que designe una clusula
ORDER BY, en cuyo caso los datos recuperados no presentarn ningn tipo de orden en concreto,
mostrndose en el mismo orden en el que los registros fueron aadidos a la tabla.

La instruccin E'T: OE.#CACC#SS O5T'O.
La instruccin opcional WITH OWNERACCESS OPTION nicamente deber de especificarse cuando su
aplicacin se ejecute en un entorno multiusuario y tenga definido un grupo de trabajo seguro, por lo que
es necesario que al establecer la conexin con el origen de datos, proporcione la ruta donde se
54
Prof. : Cesar Arce J.
encuentre el archivo de informacin de grupos de trabajo (archivo 0ystem,md;) que va a utilizar para
verificar los permisos oportunos que tienen asignados tanto los usuarios como los grupos de trabajo
incluidos en el mismo.
El motivo de que se incluya esta instruccin al final de la instruccin SELECT, no es otro que el autorizar
a un usuario para que pueda ver los datos incluidos en las tablas base que se vayan a utilizar cuando
ejecute una consulta de seleccin (SELECT), de creacin de tabla (SELECT / INTO) o de datos
anexados (INSERT INTO), aunque se le haya restringido de alguna otra manera los oportunos
permisos de usuario para poder acceder a la informacin contenida en dichas tablas.
Pero no vaya a caer en la tentacin de pensar que esta sera la solucin para acceder al contenido de
cualquier tabla, sin tener los preceptivos permisos, porque estar alejado de la realidad, dado que la
seleccin de los datos se deber de efectuar sobre una consulta previamente almacenada en la base de
datos, creada por un usuario que se encuentre incluido en el archivo de informacin de grupos de
trabajo utilizado, y que este disponga de los permisos necesarios para crear la consulta y acceder a los
datos requeridos. Con un ejemplo se ilustrar mejor el uso de la instruccin WITH OWNERACCESS
OPTION:
El usuario dmin desea crear una consulta llamada (onsulta%*mpleados en una base de datos Microsoft
Access, para que todos aquellos usuarios que no tengan permiso de lectura sobre la tabla *mpleados,
pueda consultar los datos incluidos en dicha tabla base:
.ombre de la consulta?
Consulta_Empleados
Sinta+is?
SELECT * FROM Empleados WITH OWNERACCESS OPTION
Ahora, el usuario 'Enrique', que no tiene permisos para leer los datos de la tabla, inicia sesin mediante
un objeto Connection de la biblioteca de ADO, por lo que para ejecutar la consulta, abrira un objeto
Cecordset de alguna de las dos formas que se indican a continuacin:
oRst.Open "Consulta_Empleados", oConexion, adOpenKeyset, adLockOptimistic, adCmdTable
oRst.Open "SELECT * FROM Consulta_Empleados", oConexion, adOpenKeyset, adLockOptimistic,
adCmdText
De sta forma el usuario *nri+ue podr leer los registros de la tabla *mpleados, de la que no tiene
permiso alguno establecido sobre la misma.
Como podr comprobar, la seguridad del motor Microsoft Jet no permite a cualquier usuario acceder a
los datos sin los preceptivos permisos oportunos, por lo que necesariamente deber de ser un usuario
con los suficientes permisos establecidos sobre la tabla, el que permita acceder a otros usuarios a los
registros de la tabla base mediante una consulta almacenada que incluya la instruccin WITH
OWNERACCESS OPTION.
Esta instruccin siempre deber incluirse al final de la instruccin SELECT y solamente ser til en
aplicaciones multiusuario que se encuentren protegidas.
Cap&tulo 6'. Consultas de accin


Descargar (72 KB)

Contenido
'ntroduccin
Consulta de datos ane+ados? la instruccin '.S#CT '.TO
55
Prof. : Cesar Arce J.
Consulta de insercin de un Fnico re!istro
Consulta de insercin de mFltiples re!istros
Consulta de actualiLacin? la instruccin 05DAT#
Consulta de eliminacin? la instruccin D#L#T#

'ntroduccin
En el captulo anterior se estudi la consulta de seleccin, la cual interrogaba a la base de datos para
recuperar un conjunto de registros de una tabla. Pero hay otra serie de sentencias SQL que no
devuelven un valor como resultado de la consulta ejecutada, permitindonos introducir, modificar o
eliminar registros de una tabla. Bajo el nombre genrico de consultas de accin se engloban aquellas
sentencias SQL que nos permiten actualizar los datos de una tabla.

Consulta de datos ane+ados? la instruccin '.S#CT '.TO
Mediante la instruccin INSERT INTO podemos aadir registros a una tabla, construyendo lo que en el
argot del lenguaje SQL se conoce como una consulta de datos anexados, la cual presenta dos tipos de
sintaxis dependiendo de que la consulta que se desea ejecutar permita la insercin de uno o varios
registros.
Pero antes de analizar cada sintaxis por separado, indicar las precauciones que deber de tener en
cuenta cuando desee ejecutar una consulta de datos anexados, que se aplican a ambos casos y que son
las siguientes:
Si la tabla de destino contiene una clave principal, procure anexar valores nicos y distintos de
NULL en el campo o campos que conformen la clave principal.
Igualmente, deber asegurarse que aade valores nicos en el campo o campos que formen un
ndice donde no se permita registros duplicados.
Deber de asignar un valor distinto de NULL para aquellos campos de la tabla que sean
requeridos.
Si la tabla de destino contiene un campo Autonum*rico, no incluya dicho campo en la consulta
de datos anexados, si desea que el motor Jet enumere automticamente los registros aadidos.
No obstante, si desea conservar los valores originales del campo, deber de incluir los campos
contador en la consulta, no permitiendo el motor Microsoft Jet la insercin de aquellos registros
que presenten valores duplicados si el campo Autonum*rico es la clave principal de la tabla o
forma parte de un ndice nico.
Debido a que la instruccin INSERT INTO no devuelve ningn tipo de resultado, si desea
conocer los registros que se aadirn, ejecute primero una consulta de seleccin que utilice los
mismos criterios de seleccin que la consulta de datos anexados. Una vez ejecutada la consulta
de datos aadidos, tambin puede comprobar los registros afectados por la operacin leyendo
el valor del parmetro CecordsA((ected del objeto Connection o Command de la biblioteca
de ADO que haya utilizado para ejecutar la consulta, tal y como se muestra en el siguiente
ejemplo:
Dim objCnn As ADODB.Connection
Dim lngRegAfectados As Long
Set objCnn = New ADODB.Connection
With objCnn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source = C:\Mis documentos\bdl.mdb"
' Abrimos la conexin
56
Prof. : Cesar Arce J.
.Open
' Ejecutamos la consulta de datos aadidos
.Execute "INSERT INTO CIientes2 SELECT * FROM Clientes", lngRegAfectados, adCmdText
End With
' Leemos los registros afectados por la operacin
MsgBox "Registros afectados: " & lngRegAfectados
Si en lugar de insertar registros a la tabla, desea crear una nueva tabla con los datos de otra tabla,
utilice la instruccin SELECT+++INTO, la cual se estudi en el apartado Copiar una tabla del Captulo
II.


Consulta de insercin de un Fnico re!istro
Puede utilizar la instruccin INSERT INTO para aadir un nico registro a una tabla utilizando para ello
la siguiente sintaxis:
INSERT INTO tabla%destino [(campo1[, campo2[, ...]])] VALUES ( valor1[, valor2[, ...])
Esta sintaxis guardar en cada campo especificado el valor indicado en su orden correspondiente: en el
campo1 se guardar el valor1; en el camp<2 se guardar el valor2, y as sucesivamente.
Los registros que aada se insertarn al final de la tabla, teniendo en cuenta que si omite el nombre de
alguna columna en la lista de campos, se insertar en la misma un valor NULL o el valor predeterminado
que tenga establecido el campo.
Si omite por completo la lista de campos, la clusula VALUES deber incluir un valor para cada campo, y
en el mismo orden en el que estos aparecen en la tabla, porque de lo contrario fallar la instruccin
INSERT INTO. Puede utilizar tantas instrucciones INSERT INTO adicionales de un nico registro para
agregar los registros que considere oportunos.
A la hora de especificar los valores de los campos, tenga siempre presente las siguientes normas:
Si indica una cadena de caracteres, acote el valor literal entre comillas simples (').
Si desea incluir una fecha, utilice el formato estndar americano (mes/da/ao) entre caracteres
almohadilla (#).
El siguiente ejemplo aadir un nuevo registro, especificando valores solamente para algunos campos de
la tabla; en el resto de los campos se insertar un valor NULL:
INSERT INTO Empleados (IdEmpleado, Nombre, Fecha_Alta) VALUES (858, 'Felipe Rodrguez Prez',
#04/08/04#)
Ejecutando la anterior consulta SQL, estaremos insertando en la tabla Empleados de la base de datos
una nueva fila con la informacin correspondiente a los campos especificados. Si la informacin que se
desea introducir es la correspondiente a la fila completa de la tabla, entonces podemos ignorar la lista de
campos, como se puede ver en el siguiente ejemplo, el cual aadir un nuevo registro a la tabla,
especificando un valor para cada campo de la misma:
INSERT INTO Empleados VALUES (238, 'Juan Aguilar Ruiz', 23002, 'C:\. Al Andalus, 23', 'Jan',
#04/08/2004#)
Siempre y cuando los campos no sean requeridos, o no constituyan la clave principal de la tabla, si no
deseamos especificar un valor para cada campo, deberemos de especificar explcitamente el valor NULL:
INSERT INTO Empleados VALUES (238, 'Juan Aguijar Ruiz', NULL, NULL, NULL, #04/08/2004#)
57
Prof. : Cesar Arce J.

Consulta de insercin de mFltiples re!istros
Si la consulta de datos aadidos afecta a mltiples registros, utilice la siguiente sintaxis:
INSERT INTO tabla%destino [IN base%datos%externa]
SELECT [origen.]campo1[, campo2[, ...]
FROM tabla%origen
Para ello necesitar utilizar una clusula SELECT +++ FROM con la que especificar los campos de la
tabla o de la consulta almacenada que se agregarn a la tabla de destino indicada.
Tanto la tabla de origen como de destino puede ser una tabla o una consulta que se encuentre
almacenada en la base de datos. Si ha especificado una consulta, se anexar el conjunto de registros a
todas y cada una de las tablas especificadas en la consulta.
El siguiente ejemplo insertar todos los registros de la tabla Clientes_Antiguos en la nueva tabla de
Clientes:
INSERT INTO Clientes SELECT * FROM CIientes_Antiguos
Si en nuestra base de datos tenemos creada una consulta de seleccin llamada Consulta_Clientes, el
siguiente ejemplo mostrar cmo aadir nuevos registros a las tablas que conforman dicha consulta:
INSERT INTO Consulta_Clientes SELECT * FROM Clientes_Antiguos
A continuacin aadiremos los registros existentes en la tabla de un vendedor que cumplan con el
criterio especificado, creando con aquellos nuevos registros en nuestra tabla de Pedidos:
INSERT INTO Pedidos
SELECT IdCliente, Fecha, IdProducto, IdVendedor
FROM Vendedor10
WHERE Fecha > = #04/06/2004#
Cuando necesite indicar una base de datos externa Microsoft Access, podr utilizar cualquiera de las dos
sintaxis que a continuacin se indican, teniendo en cuenta que si la ruta la encierra entre comillas
simples, no deber de utilizar los corchetes. En cambio, si el par de comillas simples va inmediatamente
despus de la clusula IN, s deber de encerrar entre corchetes la cadena de conexin, indicando el
tipo de ISAM a utilizar (/0 ccess, en el supuesto que la base de datos externa sea Microsoft Access), y
la ruta completa de la base de datos en el parmetro DATABASE, as como cualquier otro parmetro
opcional que sea requerido, como bien pudiera ser la contrasea de la base de datos.
Si la base de datos externa es distinta de Microsoft Access, necesariamente deber de utilizar el formato
de corchetes para especificar todos los parmetros requeridos para conectarse con el origen de datos.
IN @Ruta base datos externa@ IN @C:\Mis documentos\Bd1.mdb@
IN @@AMS Access;DATABASE=Ruta base datos
externa;PWD=contraseaB
IN @@AMS Access;DATABASE=C:\Mis
documentos\Bd1.md;PWD=contraseaB
El siguiente ejemplo insertar en una tabla de una base de datos Microsoft Access, los registros
existentes en un archivo de dBASE 5.0 que tiene la misma estructura que la tabla de Access:
INSERT INTO Clientes SELECT * FROM Clientes#dbf IN ''[dBASE 5.0;DATABASE=C:\Mis documentos\]
58
Prof. : Cesar Arce J.
Por ltimo, insertaremos en un archivo de texto los datos de una tabla de Access:
INSERT INTO Clientes#txt IN ''[TEXT;HDR=Yes;DATABASE=C:\Mis documentos\] SELECT * FROM
Clientes

Consulta de actualiLacin? la instruccin 05DAT#
Mediante la instruccin UPDATE podemos crear una consulta de actuali5acin para modificar el valor de
los campos de una tabla segn los criterios especificados en la consulta, siendo su sintaxis la siguiente:
UPDATE nombre'abla SET nombre%campo1 = nuevo%valor1 [, nombre%campo2 = nuevo%valor2]
WHERE criterio
La ejecucin de esta instruccin recorre todas las filas de la tabla indicada en nombre'abla, actualizando
los campos con el nuevo%valor en aquellos registros que cumplan con la condicin impuesta en la
clusula WHERE, por lo que se recomienda utilizar una consulta de actualizacin cuando desee modificar
numerosos registros o cuando estos se encuentren en mltiples tablas.
Al igual que ocurre con la instruccin INSERT INTO, la instruccin UPDATE tampoco devuelve un
conjunto de registros, por lo que necesitar utilizar los mtodos comentados anteriormente en la
consulta de datos anexados, para conocer el nmero de registros que se han sido afectados por la
ejecucin de la consulta de actualizacin.
El siguiente ejemplo actualizar en un 2 por 100 el valor del campo Sueldo de la tabla Empleados, para
todos aquellos trabajadores que tengan un grado determinado:
UPDATE Empleados SET Sueldo = Sueldo * 1.02 WHERE Grado = 5
Tenga muy presente que si no especifica un criterio mediante la clusula WHERE, la consulta de
actualizacin afectar a todos los registros de la tabla:
UPDATE Empleados SET Sueldo = Sueldo * 1.02
A continuacin actualizaremos el Grado y Sueldo personal de un empleado en concreto:
UPDATE Empleados SET Grado = 8, Sueldo = 986.05 WHERE IdEmpleado = 248

Consulta de eliminacin? la instruccin D#L#T#
Hemos visto cmo aadir nuevos registros a una tabla y cmo modificar los valores de los campos
utilizando las correspondientes instrucciones del Lenguaje de Manipulacin de Datos de SQL; ya solo nos
queda por conocer cmo eliminar los registros de una tabla.
Mediante la instruccin DELETE eliminaremos todos aquellos registros que cumplan con el criterio
establecido en una clusula WHERE, y que se encuentren incluidos en la tabla o tablas especificadas en la
clusula FROM. Su sintaxis es la siguiente:
DELETE [ tabla.*] FROM expresin_tabla WHERE criterios
Si desea eliminar todos los registros de la tabla, puede resultar que considere necesario el eliminar la
propia tabla de la base de datos, mediante la instruccin DROP TABLE analizada en el apartado
#liminar una tabla del Captulo II, ya que esta es ms eficaz que ejecutar la consulta de eliminacin.
Pero debe de tener en cuenta que si elimina la tabla, perder toda la estructura de la misma, cosa que
59
Prof. : Cesar Arce J.
no suceder si ejecuta una instruccin DELETE, dado que solamente eliminar los registros existentes,
conservando todas las restantes propiedades e ndices de la tabla, as como de los campos existentes en
la misma.
La instruccin DELETE resulta til cuando deseamos eliminar un gran nmero de registros, accin esta
que se llevar a cabo eliminando filas completas de la tabla. Si solo desea eliminar ciertos valores
correspondientes a un campo, utilice una consulta de actualizacin para establecer a NULL el valor del
campo, siempre que la columna permita la asignacin de dicho valor.
Si la consulta de eliminacin afecta solo a los registros de una tabla, no es necesario que indique el
nombre de la tabla. Por el contrario, si afecta a mltiples tablas, necesariamente tendr que indicar el
nombre de las mismas.
Puede utilizar la instruccin DELETE para eliminar los registros de tablas que formen una relacin de
uno a varios, teniendo en cuenta que si en la relacin ha especificado el valor *liminar en cascada los
registros relacionados, se eliminaran todos los registros correspondientes a la tabla del lado varios
cuando se elimine el registro correspondiente del lado uno de la relacin. Si por el contrario, la relacin
no permite la eliminacin en cascada, no podr eliminar los registros de la tabla del lado uno de la
relacin que tengan registros relacionados en la tabla del lado varios. Un ejemplo tpico de eliminacin
en cascada sera aquella relacin existente entre las tablas Clientes (lado uno) y Facturas (lado varios).
La eliminacin de un registro de la tabla Clientes har que se eliminen tambin todos los registros
relacionados en la tabla Facturas.
Al igual que el resto de las consultas de accin comentadas en este captulo, la instruccin DELETE no
devuelve ningn conjunto de registros que nos haga saber el nmero de registros que han sido
afectados por la consulta de eliminacin.
Por tlimo, y dado que estamos hablando de ELIMINAR DATOS, es sumamente importante que conserve
copias de seguridad de sus datos, debido a que no podr deshacer la operacin ejecutada mediante una
consulta de eliminacin.
El siguiente ejemplo eliminar de la tabla Empleados todos aquellos registros que tengan un Grado en
concreto:
DELETE FROM Empleados WHERE Grado = 8
En el supuesto de que deseemos eliminar todos los registros de la tabla, no indique la clusula WHERE:
DELETE FROM Empleados
A continuacin eliminaremos de la tabla Facturas todos los registros que pertenezcan a un mismo
cliente, por lo que al combinar dos tablas necesariamente tendr que indicar el nombre de la tabla que
contiene los registros que se van a eliminar:
DELETE Facturas.*
FROM Clientes INNER JOIN Facturas ON Clientes.IdCliente = Facturas.IdCliente
WHERE Clientes.IdCliente=258
Por ltimo, el siguiente ejemplo eliminar un registro en las dos tablas especificadas, siempre y cuando
la segunda tabla (que sera el lado varios de una relacin uno a varios) no tenga ms de un registro
relacionado en la primera tabla (el lado uno):
DELETE Clientes.*, Facturas.*
FROM Clientes INNER JOIN Facturas ON Clientes.IdCliente = Facturas.IdCliente
WHERE Clientes.IdCliente=258
Comentar que si ejecuta esta ltima consulta desde la interfaz de usuario de Microsoft Access, no se
eliminar ningn registro. En cambio, si utiliza la biblioteca de DAO o ADO, si hay un nico registro que
satisfaga el criterio especificado, se eliminar el registro tanto en la tabla Clientes como en la tabla
Facturas.
60
Prof. : Cesar Arce J.
E Le!"#a$e SQL
Como en el caso de los ms modernos lenguajes relacionales, SQL est basado en el
clculo relacional de tuplas. Como resultado, toda consulta formulada utilizando el
clculo relacional de tuplas ( o su equivalente, el lgebra relacional se pude formular
tambi!n utilizando SQL. "a#, sin embargo, capacidades que van ms all del clculo o
del lgebra relaciona. $qu% tenemos una lista de algunas caracter%sticas proporcionadas
por SQL que no forman parte del lgebra # del clculo relacionales&
Comandos para inserci'n, borrado o modificaci'n de datos.
Capacidades aritm!ticas& (n SQL es posible incluir operaciones aritm!ticas as%
como comparaciones, por ejemplo $ ) * + ,. -'tese que ni + ni otros
operadores aritm!ticos aparec%an en el lgebra relacional ni en clculo
relacional.
$signaci'n # comandos de impresi'n& es posible imprimir una relaci'n
construida por una consulta # asignar una relaci'n calculada a un nombre de
relaci'n.
.unciones agregadas& /peraciones tales como promedio (average), suma (sum),
mximo (max), etc. se pueden aplicar a las columnas de una relaci'n para
obtener una cantidad 0nica.
Seec%
(l comando ms usado en SQL es la instrucci'n S(L(C1, que se utiliza para recuperar
datos. La sinta2is es&
SELECT 0ALL1DISTINCT2
3 / 1 expr)* 0AS c)alias)*2 04 +++
04 expr)+ 0AS c)alias)+2225
FROM table)name)* 0t)alias)*2
04 +++ 04 table)name)n 0t)alias)n222
0WHERE condition2
0GROUP BY name)of)attr)i
04+++ 04 name)of)attr)"22 0HAVING condition22
03UNION 0ALL2 1 INTERSECT 1 EXCEPT5 SELECT +++2
0ORDER BY name)of)attr)i 0ASC1DESC2
04 +++ 04 name)of)attr)" 0ASC1DESC22226

3lustraremos a4ora la compleja sinta2is de la instrucci'n S(L(C1 con varios ejemplos.
Las tablas utilizadas para los ejemplos se definen en& La Base de Datos de Proveedores
y Artculos.
Select sencillas
$qu% tenemos algunos ejemplos sencillos utilizando la instrucci'n S(L(C1&
E$e&'o 4. Q#er( se!c)a co! c#a)f)cac)*!
61
Prof. : Cesar Arce J.
5ara recuperar todas las tuplas de la tabla 5$61 donde el atributo 563C( es ma#or que
17, formularemos la siguiente consulta&
SELECT / FROM PART
WHERE PRICE 7 1.6
# obtenemos la siguiente tabla&
PNO 1 PNAME 1 PRICE
8888898888888888888988888888
: 1 C#'';, 1 1<
= 1 L#>!, 1 ?<
8tilizando 9:9 en la instrucci'n S(L(C1 solicitaremos todos los atributos de la tabla. Si
queremos recuperar s'lo los atributos 5-$;( # 563C( de la tabla 5$61 utilizaremos
la instrucci'n&
SELECT PNAME4 PRICE
FROM PART
WHERE PRICE 7 1.6
(n este caso el resultado es&
PNAME 1 PRICE
888888888888988888888
C#'';, 1 1<
L#>!, 1 ?<
-'tese que la S(L(C1 SQL corresponde a la 9pro#ecci'n9 en lgebra relaciona, no a la
9selecci'n9 (vea lgebra Relacional para ms detalles.
Las cualificaciones en la clausula <"(6( pueden tambi!n conectarse l'gicamente
utilizando las palabras claves /6, $-=, # -/1&
SELECT PNAME4 PRICE
FROM PART
WHERE PNAME - @C#'';,@ AND
(PRICE - . OR PRICE A 1<)6
dar como resultado&
PNAME 1 PRICE
888888888888988888888
C#'';, 1 1<
Las operaciones aritm!ticas se pueden utilizar en la lista de objetivos # en la clausula
<"(6(. 5or ejemplo, si queremos conocer cuanto cuestan si tomamos dos piezas de
un art%culo, podr%amos utilizar la siguiente consulta&
62
Prof. : Cesar Arce J.
SELECT PNAME4 PRICE / ? AS DOUBLE
FROM PART
WHERE PRICE / ? A <.6
# obtenemos&
PNAME 1 DOUBLE
8888888888889888888888
T'n$**, 1 ?.
T&#'(!, 1 1B
C#'';, 1 :.
-'tese que la palabra =/*L( tras la palabra clave $S es el nuevo t%tulo de la segunda
columna. (sta t!cnica puede utilizarse para cada elemento de la lista objetivo para
asignar un nuevo t%tulo a la columna resultante. (ste nuevo t%tulo recibe el calificativo
de 9un alias9. (l alias no puede utilizarse en todo el resto de la consulta.
Joins (Cruces)
(l siguiente ejemplo muestra como las joins (cruces) se realizan en SQL.
5ara cruzar tres tablas S855L3(6, 5$61 # S(LLS a trav!s de sus atributos comunes,
formularemos la siguiente instrucci'n&
SELECT S+SNAME4 P+PNAME
FROM SUPPLIER S4 PART P4 SELLS SE
WHERE S+SNO - SE+SNO AND
P+PNO - SE+PNO6

# obtendremos la siguiente tabla como resultado&
SNAME 1 PNAME
888888898888888
S%$"C 1 T'n$**,
S%$"C 1 T&#'(!,
Jn#, 1 L#>!,
AD!%, 1 T'n$**,
AD!%, 1 C#'';,
B*!E# 1 T&#'(!,
B*!E# 1 C#'';,
B*!E# 1 L#>!,

(n la clausula .6/; 4emos introducido un alias al nombre para cada relaci'n porque
4a# atributos con nombre com0n (S-/ # 5-/ en las relaciones. $4ora podemos
distinguir entre los atributos con nombre com0n simplificando la adicci'n de un prefijo
al nombre del atributo con el nombre del alias seguido de un punto. La join se calcula de
la misma forma, tal como se muestra en Una Inner Join (Una Join Interna). 5rimero
el producto cartesiano& S855L3(6 > 5$61 > S(LLS $4ora seleccionamos 0nicamente
aquellas tuplas que satisfagan las condiciones dadas en la clausula <"(6( (es decir,
63
Prof. : Cesar Arce J.
los atributos con nombre com0n deben ser iguales. .inalmente eliminamos las
columnas repetidas (S.S-$;(, 5.5-$;(.
Operadores Agregados
SQL proporciona operadores agregados (como son $?@, C/8-1, S8;, ;3-, ;$A
que toman el nombre de un atributo como argumento. (l valor del operador agregado se
calcula sobre todos los valores de la columna especificada en la tabla completa. Si se
especifican grupos en la consulta, el clculo se 4ace s'lo sobre los valores de cada
grupo (vean la siguiente secci'n.
E$e&'o 5. A""re"a%es
Si queremos conocer el coste promedio de todos los art%culos de la tabla 5$61,
utilizaremos la siguiente consulta&
SELECT AVG(PRICE) AS AVGFPRICE
FROM PART6
(l resultado es&
AVGFPRICE
88888888888
1=+<
Si queremos conocer cuantos art%culos se recogen en la tabla 5$61, utilizaremos la
instrucci'n&
SELECT COUNT(PNO)
FROM PART6
# obtendremos&
COUNT
8888888
=
Agregacin por Grupos
SQL nos permite particionar las tuplas de una tabla en grupos. (n estas condiciones, los
operadores agregados descritos antes pueden aplicarse a los grupos (es decir, el valor
del operador agregado no se calculan sobre todos los valores de la columna
especificada, sino sobre todos los valores de un grupo. (l operador agregado se calcula
individualmente para cada grupo.
(l particionamiento de las tuplas en grupos se 4ace utilizando las palabras clave
+,O-P ./ seguidas de una lista de atributos que definen los grupos. Si tenemos
64
Prof. : Cesar Arce J.
+,O-P ./ A
1
0 0 A
1
4abremos particionado la relaci'n en grupos, de tal modo que dos
tuplas son del mismo grupo si # s'lo si tienen el mismo valor en sus atributos $
1
, , $
B
.
E$e&'o 6. A"re"a2os
Si queremos conocer cuntos art%culos 4an sido vendidos por cada proveedor
formularemos la consulta&
SELECT S+SNO4 S+SNAME4 COUNT(SE+PNO)
FROM SUPPLIER S4 SELLS SE
WHERE S+SNO - SE+SNO
GROUP BY S+SNO4 S+SNAME6
# obtendremos&
SNO 1 SNAME 1 COUNT
888889888888898888888
1 1 S%$"C 1 ?
? 1 Jn#, 1 1
: 1 AD!%, 1 ?
= 1 B*!E# 1 :
=emos a4ora una mirada a lo que est ocurriendo aqu%. 5rimero, la join de las tablas
S855L3(6 # S(LLS&
S+SNO 1 S+SNAME 1 SE+PNO
88888889888888888988888888
1 1 S%$"C 1 1
1 1 S%$"C 1 ?
? 1 Jn#, 1 =
: 1 AD!%, 1 1
: 1 AD!%, 1 :
= 1 B*!E# 1 ?
= 1 B*!E# 1 :
= 1 B*!E# 1 =
$4ora particionamos las tuplas en grupos reuniendo todas las tuplas que tiene el mismo
atributo en S.S-/ # S.S-$;(&
S+SNO 1 S+SNAME 1 SE+PNO
88888889888888888988888888
1 1 S%$"C 1 1
1 ?
88888888888888888888888888
? 1 Jn#, 1 =
88888888888888888888888888
: 1 AD!%, 1 1
1 :
88888888888888888888888888
= 1 B*!E# 1 ?
1 :
1 =
65
Prof. : Cesar Arce J.
(n nuestro ejemplo, obtenemos cuatro grupos # a4ora podemos aplicar el operador
agregado C/8-1 para cada grupo, obteniendo el resultado total de la consulta dada
anteriormente.
-'tese que para el resultado de una consulta utilizando @6/85 *C # operadores
agregados para dar sentido a los atributos agrupados, debemos primero obtener la lista
objetivo. Los dems atributos que no aparecen en la clausula @6/85 *C se
seleccionarn utilizando una funci'n agregada. 5or otro lado, no se pueden utilizar
funciones agregadas en atributos que aparecen en la clausula @6/85 *C.
Having
La clausula "$?3-@ trabaja de forma mu# parecida a la clausula <"(6(, # se utiliza
para considerar s'lo aquellos grupos que satisfagan la cualificaci'n dada en la misma.
Las e2presiones permitidas en la clausula "$?3-@ deben involucrar funcionen
agregadas. Cada e2presi'n que utilice s'lo atributos planos deber recogerse en la
clausula <"(6(. 5or otro lado, toda e2presi'n que involucre funciones agregadas debe
aparecer en la clausula "$?3-@.
E$e&'o 7. 3a4)!"
Si queremos solamente los proveedores que venden ms de un art%culo, utilizaremos la
consulta&
SELECT S+SNO4 S+SNAME4 COUNT(SE+PNO)
FROM SUPPLIER S4 SELLS SE
WHERE S+SNO - SE+SNO
GROUP BY S+SNO4 S+SNAME
HAVING COUNT(SE+PNO) 7 16
# obtendremos&
SNO 1 SNAME 1 COUNT
888889888888898888888
1 1 S%$"C 1 ?
: 1 AD!%, 1 ?
= 1 B*!E# 1 :
Subconsultas
(n las clausulas <"(6( # "$?3-@ se permite el uso de subconsultas (subselects en
cualquier lugar donde se espere un valor. (n este caso, el valor debe derivar de la
evaluaci'n previa de la subconsulta. (l uso de subconsultas ampl%a el poder e2presivo
de SQL.
E$e&'o 8. S#5seec%
Si queremos conocer los art%culos que tienen ma#or precio que el art%culo llamado
D1ornillosD, utilizaremos la consulta&
66
Prof. : Cesar Arce J.
SELECT /
FROM PART
WHERE PRICE 7 (SELECT PRICE FROM PART
WHERE PNAME-@T'n$**,@)6
(l resultado ser&
PNO 1 PNAME 1 PRICE
8888898888888888888988888888
: 1 C#'';, 1 1<
= 1 L#>!, 1 ?<
Cuando revisamos la consulta anterior, podemos ver la palabra clave S(L(C1 dos
veces. La primera al principio de la consulta E a la que nos referiremos como la
S(L(C1 e2terna E # la segunda en la clausula <"(6(, donde empieza una consulta
anidada E nos referiremos a ella como la S(L(C1 interna. 5ara cada tupla de la
S(L(C1 e2terna, la S(L(C1 interna deber ser evaluada. 1ras cada evaluaci'n,
conoceremos el precio de la tupla llamada D1ornillosD, # podremos c4equear si el precio
de la tupla actual es ma#or.
Si queremos conocer todos los proveedores que no venden ning0n art%culo (por ejemplo,
para poderlos eliminar de la base de datos, utilizaremos&
SELECT /
FROM SUPPLIER S
WHERE NOT EXISTS
(SELECT / FROM SELLS SE
WHERE SE+SNO - S+SNO)6
(n nuestro ejemplo, obtendremos un resultado vac%o, porque cada proveedor vende al
menos un art%culo. -'tese que utilizamos S.S-/ de la S(L(C1 e2terna en la clausula
<"(6( de la S(L(C1 interna. Como 4emos descrito antes, la subconsulta se eval0a
para cada tupla de la consulta e2terna, es decir, el valor de S.S-/ se toma siempre de la
tupla actual de la S(L(C1 e2terna.
Unin, Interseccin, Ecepcin
(stas operaciones calculan la uni'n, la intersecci'n # la diferencia de la teor%a de
conjuntos de las tuplas derivadas de dos subconsultas.
E$e&'o 9. -!)o!0 6!%ersec%0 E7ce'%
La siguiente consulta es un ejemplo de 8-3/-&
SELECT S+SNO4 S+SNAME4 S+CITY
FROM SUPPLIER S
WHERE S+SNAME - @Jn#,@
UNION
SELECT S+SNO4 S+SNAME4 S+CITY
FROM SUPPLIER S
WHERE S+SNAME - @AD!%,@6
67
Prof. : Cesar Arce J.
=ar el resultado&
SNO 1 SNAME 1 CITY
8888898888888988888888
? 1 Jn#, 1 P!'$,
: 1 AD!%, 1 V$#nn!
$qu% tenemos un ejemplo para 3-1(6S(C1&
SELECT S+SNO4 S+SNAME4 S+CITY
FROM SUPPLIER S
WHERE S+SNO 7 1
INTERSECT
SELECT S+SNO4 S+SNAME4 S+CITY
FROM SUPPLIER S
WHERE S+SNO 7 ?6
que dar como resultado&
SNO 1 SNAME 1 CITY
8888898888888988888888
? 1 Jn#, 1 P!'$,
L! Gn$(! "&H*! D#>&#*"! H' !%I!, H!'"#, D# *! (n,&*"! #, *!
Gn$(! J&# "$#n# KSNO-?K+
.inalmente, un ejemplo de (AC(51&
SELECT S+SNO4 S+SNAME4 S+CITY
FROM SUPPLIER S
WHERE S+SNO 7 1
EXCEPT
SELECT S+SNO4 S+SNAME4 S+CITY
FROM SUPPLIER S
WHERE S+SNO 7 :6
que dar como resultado&
SNO 1 SNAME 1 CITY
8888898888888988888888
? 1 Jn#, 1 P!'$,
: 1 AD!%, 1 V$#nn!
Def)!)c)*! 2e Da%os
(l lenguaje SQL inclu#e un conjunto de comandos para definici'n de datos.
68
Prof. : Cesar Arce J.
Create !able
(l comando fundamental para definir datos es el que crea una nueva relaci'n (una nueva
tabla. La sinta2is del comando C6($1( 1$*L( es&
CREATE TABLE table)name
(name)of)attr)* t,pe)of)attr)*
04 name)of)attr)- t,pe)of)attr)-
04 +++22)6

E$e&'o 10. Creac)*! 2e #!a %a5a
5ara crear las tablas definidas en La Base de Datos de Proveedores y Artculos se
utilizaron las siguientes instrucciones de SQL&
CREATE TABLE SUPPLIER
(SNO INTEGER4
SNAME VARCHAR(?.)4
CITY VARCHAR(?.))6
CREATE TABLE PART
(PNO INTEGER4
PNAME VARCHAR(?.)4
PRICE DECIMAL(= 4 ?))6
CREATE TABLE SELLS
(SNO INTEGER4
PNO INTEGER)6
!ipos de "atos en S#$
$ continuaci'n sigue una lista de algunos tipos de datos soportados por SQL&
3-1(@(6& entero binario con signo de palabra completa (,1 bits de precisi'n.
S;$LL3-1& entero binario con signo de media palabra (1F bits de precisi'n.
=(C3;$L (pG,.H& n0mero decimal con signo de p d%gitos de precisi'n,
asumiendo . a la derec4a para el punto decimal. (1F I p I .q I 7. Si . se omite,
se asume que vale 7.
.L/$1& num!rico con signo de doble palabra # coma flotante.
C"$6(n& cadena de caracteres de longitud fija, de longitud n.
?$6C"$6(n& cadena de caracteres de longitud variable, de longitud m2ima
n.
Create Inde
Se utilizan los %ndices para acelerar el acceso a una relaci'n. Si una relaci'n R tiene un
%ndice en el atributo A podremos recuperar todas la tuplas t que tienen t(A J a en un
69
Prof. : Cesar Arce J.
tiempo apro2imadamente proporcional al n0mero de tales tuplas t ms que en un
tiempo proporcional al tamaKo de R.
5ara crear un %ndice en SQL se utiliza el comando C6($1( 3-=(A. La sinta2is es&
CREATE INDEX index)name
ON table)name ( name)of)attribute )6

E$e&'o 11. Crea%e 6!2e7
5ara crear un %ndice llamado 3 sobre el atributo S-$;( de la relaci'n S855L3(6,
utilizaremos la siguiente instrucci'n&
CREATE INDEX I
ON SUPPLIER (SNAME)6

(l %ndice creado se mantiene automticamente. es decir, cada vez que una nueva tupla
se inserte en la relaci'n S855L3(6, se adaptar el %ndice 3. -'tese que el 0nico cambio
que un usuario puede percibir cuando se crea un %ndice es un incremento en la
velocidad.
Create %ie&
Se puede ver una vista como una tabla virtual, es decir, una tabla que no e2iste
fsicamente en la base de datos, pero aparece al usuario como si e2istiese. 5or contra,
cuando 4ablamos de una tabla base, 4a# realmente un equivalente almacenado para
cada fila en la tabla en alg0n sitio del almacenamiento f%sico.
Las vistas no tienen datos almacenados propios, distinguibles # f%sicamente
almacenados. (n su lugar, el sistema almacena la definici'n de la vista (es decir, las
reglas para acceder a las tablas base f%sicamente almacenadas para materializar la vista
en alg0n lugar de los catlogos del sistema (vea Syste !atalogs. 5ara una discusi'n
de las diferentes t!cnicas para implementar vistas, refi!rase a SIM98.
(n SQL se utiliza el comando C,EA8E 96E: para definir una vista. La sinta2is es&
CREATE VIEW vie/)name
AS select)stmt

donde select)stmt es una instrucci'n select vlida, como se defini' en Select. -'tese
que select)stmt no se ejecuta cuando se crea la vista. Simplemente se almacena en los
catlogos del sistema # se ejecuta cada vez que se realiza una consulta contra la vista.
Sea la siguiente definici'n de una vista (utilizamos de nuevo las tablas de La Base de
Datos de Proveedores y Artculos &
CREATE VIEW LnDnFS&HH*$#',
AS SELECT S+SNAME4 P+PNAME
FROM SUPPLIER S4 PART P4 SELLS SE
70
Prof. : Cesar Arce J.
WHERE S+SNO - SE+SNO AND
P+PNO - SE+PNO AND
S+CITY - @LnDn@6

$4ora podemos utilizar esta relacin virtual LnDnFS&HH*$#', como si se tratase de
otra tabla base&
SELECT /
FROM LnDnFS&HH*$#',
WHERE P+PNAME - @T'n$**,@6

Lo cual nos devolver la siguiente tabla&
SNAME 1 PNAME
888888898888888888
S%$"C 1 T'n$**,

5ara calcular este resultado, el sistema de base de datos 4a realizado previamente un
acceso oculto a las tablas de la base S855L3(6, S(LLS # 5$61. "ace esto ejecutando
la consulta dada en la definici'n de la vista contra aquellas tablas base. 1ras eso, las
cualificaciones adicionales (dadas en la consulta contra la vista se podrn aplicar para
obtener la tabla resultante.
"rop !able, "rop Inde, "rop %ie&
Se utiliza el comando =6/5 1$*L( para eliminar una tabla (inclu#endo todas las
tuplas almacenadas en ella&
DROP TABLE table)name6

5ara eliminar la tabla S855L3(6, utilizaremos la instrucci'n&
DROP TABLE SUPPLIER6

Se utiliza el comando =6/5 3-=(A para eliminar un %ndice&
DROP INDEX index)name6

.inalmente, eliminaremos una vista dada utilizando el comando =6/5 ?3(<&
DROP VIEW vie/)name6

Ma!)'#ac)*! 2e Da%os
71
Prof. : Cesar Arce J.
Insert Into
8na vez que se crea una tabla (vea !reate "able, puede ser llenada con tuplas mediante
el comando 6;SE,8 6;8O. La sinta2is es&
INSERT INTO table)name (name)of)attr)*
04 name)of)attr)- 04+++22)
VALUES (val)attr)*
04 val)attr)- 04 +++22)6

5ara insertar la primera tupla en la relaci'n S855L3(6 (de La Base de Datos de
Proveedores y Artculos utilizamos la siguiente instrucci'n&
INSERT INTO SUPPLIER (SNO4 SNAME4 CITY)
VALUES (14 @S%$"C@4 @LnDn@)6

5ara insertar la primera tupla en la relaci'n S(LLS, utilizamos&
INSERT INTO SELLS (SNO4 PNO)
VALUES (14 1)6

Update
5ara cambiar uno o ms valores de atributos de tuplas en una relaci'n, se utiliza el
comando 85=$1(. La sinta2is es&
UPDATE table)name
SET name)of)attr)* - value)*
04 +++ 04 name)of)attr)+ - value)+22
WHERE condition6

5ara cambiar el valor del atributo 563C( en el art%culo D1ornillosD de la relaci'n 5$61,
utilizamos&
UPDATE PART
SET PRICE - 1<
WHERE PNAME - @T'n$**,@6

(l nuevo valor del atributo 563C( de la tupla cu#o nombre es D1ornillosD es a4ora 1F.
"elete
5ara borrar una tupla de una tabla particular, utilizamos el comando =(L(1( .6/;.
La sinta2is es&
DELETE FROM table)name
WHERE condition6

72
Prof. : Cesar Arce J.
5ara borrar el proveedor llamado DSmit4D de la tabla S855L3(6, utilizamos la siguiente
instrucci'n&
DELETE FROM SUPPLIER
WHERE SNAME - @S%$"C@6

S(s%e& Ca%ao"s
(n todo sistema de base de datos SQL se emplean catlogos de sistema para mantener
el control de qu! tablas, vistas, %ndices, etc estn definidas en la base de datos. (stos
catlogos del sistema se pueden investigar como si de cualquier otra relaci'n normal se
tratase. 5or ejemplo, 4a# un catlogo utilizado para la definici'n de vistas. (ste catlogo
almacena la consulta de la definici'n de la vista. Siempre que se 4ace una consulta
contra la vista, el sistema toma primero la consulta de definicin de la vista del catlogo
# materializa la vista antes de proceder con la consulta del usuario (vea SIM98 para
obtener una descripci'n ms detallada. =ir%jase a!"# para obtener ms informaci'n
sobre los catlogos del sistema.
SQL E&5e5)2o
(n esta secci'n revisaremos como se puede embeber SQL en un lenguaje de 4ost (p.e.
C. "a# dos razones principales por las que podr%amos querer utilizar SQLdesde un
lenguaje de 4ost&
"a# consultas que no se pueden formular utilizando SQL puro (por ejemplo, las
consultas recursivas. 5ara ser capaz de realizar esas consultas necesitamos un
lenguaje de 4ost de ma#or poder e2presivo que SQL.
Simplemente queremos acceder a una base de datos desde una aplicaci'n que
est escrita en el lenguaje del 4ost (p.e. un sistema de reserva de billetes con una
interface grfica escrita en C, # la informaci'n sobre los billetes est almacenada
en una base de datos que puede accederse utilizando SQL embebido.
8n programa que utiliza SQL embebido en un lenguaje de 4ost consiste en
instrucciones del lenguaje del 4ost e instrucciones de S$% embebido ((SQL. Cada
instrucci'n de (SQL empieza con las palabras claves E<EC SQL. Las instrucciones
(SQL se transforman en instrucciones del lenguaje del 4ost mediante un precompilador
(que 4abitualmente inserta llamadas a rutinas de librer%as que ejecutan los variados
comandos de SQL.
Cuando vemos los ejemplos de Select observamos que el resultado de las consultas es
algo mu# pr'2imo a un conjunto de tuplas. La ma#or%a de los lenguajes de 4ost no estn
diseKados para operar con conjuntos, de modo que necesitamos un mecanismo para
acceder a cada tupla 0nica del conjunto de tuplas devueltas por una instrucci'n
S(L(C1. (ste mecanismo puede ser proporcionado declarando un cursor. 1ras ello,
podemos utilizar el comando .(1C" para recuperar una tupla # apuntar el cursor 4acia
la siguiente tupla.
73
Prof. : Cesar Arce J.

También podría gustarte