Está en la página 1de 105

Captulo I.

Comandos, clusulas, operadores y funciones de


agregado

A modo de pequea introduccin

El motor de base de datos Microsoft Jet proporciona un modelo


relacional basado en el Lenguaje de Consulta Estructurado (SQL)
estndar, con pequeas diferencias existentes con respecto al
lenguaje SQL de ANSI, utilizndose fundamentalmente para
ejecutar consultas de manipulacin y definicin de datos
mediante los objetos correspondientes de las bibliotecas de DAO
y ADO, bien para recuperar un conjunto de registros de la base
de datos, bien para disear o modificar directamente la
estructura de una base de datos Microsoft Jet.

El Lenguaje de Consulta Estructurado es un lenguaje de


programacin de bases de datos que tiene como antecedente al
lenguaje Sequel, motivo por el cual sus iniciales se continen
pronunciando como sequel en lugar de pronunciarlas letra a
letra.

Los orgenes del SQL se remotan a comienzos de la dcada de


los 70, cuando el doctor norteamericano E. F. Codd cre el
modelo de bases de datos relacionales, evolucionando desde
entonces hasta alcanzar el modelo estndar y normalizado en el
que se ha convertido en la actualdad, modelo este que se
encuentra implementado en un amplio abnico de bases de
datos relacionales existentes en el mercado, que aunque
presentan algunas variaciones respecto al estndar ANSI que
define la norma (incluyendo la versin SQL para el motor
Microsoft Jet), existe una gran cohesin en lo que concierne a la
estructura y funcionamiento general del lenguaje utilizado por
los diferentes fabricantes de bases de datos relacionales.

Los componentes de SQL

El lenguaje SQL se compone de una serie de comandos,


clusulas, operadores y funciones de agregado 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 DDL


Comando Descripcin
ADD USER Agrega uno o varios usuarios a un grupo de SLO ADO
trabajo.
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.
DROP PROCEDURE Elimina un procedimiento almacenado. SLO ADO
DROP TABLE Elimina una tabla.
DROP USER Elimina uno o varios usuarios, o quita uno o SLO ADO
varios usuarios de un grupo
de trabajo.
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 Elimina 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.

Tabla3. 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.

Operadores lgicos

Los operadores lgicos se utilizan para evaluar expresiones,


generalmente dentro de una clusula WHERE.

Tabla4. Operadores lgicos


Operador Descripcin
AND Es el y 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.

Ejemplos

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.

Tabla5. Operadores de comparacin


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.

Ejemplos

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'
Funciones de agregado

Las funciones de agregado se utilizan dentro de una clusula


SELECT en grupos de registros para devolver un nico valor que
se aplica a un grupo de registros.

Tabla6. Funciones de agregado


Funcin de agregado 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.

Ejemplos

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

Captulo II. Tipos de datos del lenguaje SQL del motor


Microsoft Jet

Contenido

Tipos de datos del motor Microsoft Jet


Datos carcter
Datos numricos
Datos enteros
El tipo de dato Autonumrico
Datos decimales
Datos aproximados
Datos monetarios
Datos de fecha y hora
Datos binarios
Datos para objetos OLE
Datos BOOLEAN
Datos GUID
Tipos de datos del motor Microsoft Jet

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 Jet Sinnimos SQL Server SQL ANSI


BINARY VARBINARY, BINARY, VARBINARY BIT, BIT
BINARY VARYING VARYING
BIT LOGICAL, BIT No admitido
LOGICAL1, YESNO
TINYINT INTEGER1, BYTE TINYINT No admitido
COUNTER AUTOINCREMENT, No admitido
IDENTITY
MONEY CURRENCY MONEY No admitido
DATETIME DATE, TIME, DATETIME DATE, TIME,
TIMESTAMP TIMESTAMP
UNIQUEIDENTIFIER GUID UNIQUEIDENTIFIER No admitido
DECIMAL NUMERIC, DEC DECIMAL DECIMAL
REAL SINGLE, FLOAT4, REAL REAL
IEEESINGLE
FLOAT DOUBLE, FLOAT8, FLOAT DOUBLE
IEEEDOUBLE, PRECISION,
NUMBER FLOAT
SMALLINT SHORT, INTEGER2 SMALLINT SMALLINT
INTEGER LONG, INT, INTEGER INTEGER
INTEGER4
IMAGE LONGBINARY, IMAGE No admitido
GENERAL,
OLEOBJECT
TEXT LONGTEXT, TEXT No admitido
LONGCHAR,
MEMO, NOTE,
NTEXT
CHAR TEXT (n), CHAR, VARCHAR, CHARACTER,
ALPHANUMERIC, NCHAR, NVARCHAR CHARACTER
CHARACTER, VARYING,
STRING, NATIONAL
VARCHAR, CHARACTER,
NCHAR, NATIONAL
CHARACTER CHARACTER
VARYING, VARYING
NATIONAL CHAR,
NATIONAL
CHARACTER,
NATIONAL
CHARACTER
VARYING,
NATIONAL CHAR
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, nation Para datos carcter de longitud fija de hasta 255 caracteres.
al char, national character 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 Para datos carcter de longitud variable de hasta 255
varying, national char caracteres. Si no se especifica el nmero de carcteres, el
varying, national character tamao del campo ser de 255 caracteres. El tamao de
varying, string, text almacenamiento en bytes ser el doble del tamao real. Si
(n),varchar 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, not Para datos carcter de longitud variable de hasta un
e, ntext, text 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
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 Texto, 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 numricos

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 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.
smallint, short, integer2 Para valores enteros cortos en el intervalo de -32.768 a 3
integer, long, int, integer4 Para valores enteros largos en el rango de -2.147.483.648
counter, autoincrement, identity Para valores en el mismo rango que los tipos de datos en
se puede definir en la tabla un campo Autonumrico.

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.

El tipo de dato Autonumrico

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 Autonumrico 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 Autonumrico,
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 Autonumrico 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 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 Autonumrico, 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 Autonumrico. 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.

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:

0 e p 28

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 aproximados
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 p
negativos, y entre 1,401298E-45 y 3,402823E38 para va
float, double, float8, ieeedouble, number Para valores de datos aproximados de coma flotante de p
para valores negativos, y entre 4,94065645841247E-324

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 en lugar de 1.234,5678 .
Datos de fecha y hora

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
almacenamiento es de n bytes. Apropiado cuando todos l
varbinary, binary varying Para datos binarios de longitud variable de hasta 510 byt
bytes.El tamao de almacenamiento es de n bytes. Aprop

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.

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 objetos OLE

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 BOOLEAN

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.

Datos GUID

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


CoCreateGuid, donde puede encontrar un ejemplo en el
siguiente artculo de la Base del Conocimiento: Cmo Usar la
API CoCreateGUID para Generar un GUID con VB.
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

Captulo III. Cmo crear, modificar, copiar y eliminar tablas


Por Enrique Martnez Montejo
[Microsoft Most Valuable Professional - Visual Basic]
ltima revisin: 11/06/2004
Contenido

Introduccin
Crear una tabla
Modificar la estructura de una tabla
Aadir nuevos campos a la tabla
Modificar el tipo de dato de un campo
Eliminar un campo de la tabla
Copiar una tabla
Eliminar una tabla

Introduccin

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.

Sintaxis

CREATE TABLE tabla (


campo1 tipo [(tamao)] [WITH COMPRESSION | WITH COMP] [NOT NULL |
NULL] [DEFAULT valorDefecto1] [ndice1]
[, campo2 tipo [(tamao)] [WITH COMPRESSION | WITH COMP] [NOT NULL |
NULL] [DEFAULT valorDefecto2] [ndice2]
[, ...]]
[,CONSTRAINT ndice_mltiples_campos[,...]]
)

Parmetro 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 cr
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 t
WITH COMPRESSION | WITH COMP Atributo opcional que implica comprimir a caracteres de un solo
MEMO, as como por sus sinnimos. Se puede utilizar cualquiera
SLO ADO el supuesto de que se especifique este atributo.
NOT NULL | NULL De utilizarse significa que el campo es requerido, por lo que se ex
defecto es NULL.
DEFAULT Establece el valor por defecto que tendr el campo para los nuevo
SLO ADO la declaracin del campo. El valor por defecto indicado deber co
ndice1, ndice2 Una clusula CONSTRAINT que define un ndice de un solo cam
ndice_mltiples_campos Una clusula CONSTRAINT que define un ndice de mltiples c

Comentarios

La instruccin CREATE TABLE se utiliza como argumento del


mtodo Execute de un objeto Database abierto (biblioteca de
DAO) o de un objeto Connection (biblioteca de ADO), as como
por el mtodo ExecuteNonQuery de un objeto OleDbConnection
del espacio de nombre System.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 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 y 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.

Ejemplos

1. 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 ""JAN"", " & _
"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


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

2. 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
.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

3. 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 HKLM\Software\Microsoft\Jet\4.0\Engines\Text, 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 Schema.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 Schema.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
Microsoft Jet no pudo encontrar el objeto 'NOMBRE#TXT',
por lo que deber de poner especial atencin si el archivo
Schema.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 Schema.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 Schema.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 Schema.ini en
los siguientes supuestos:
Accedamos a datos de longitud fija.
El archivo de texto contenga tipos de datos DateTime,
Currency o Decimal.
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
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:

Trabajar con los datos de un archivo de texto

4. 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 Data Source, 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 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 General, 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 Field 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 Type del objeto
Field ser TEXT 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) ' No es un nombre vli
CREATE TABLE [Hoja1$] (Campo1 INTEGER) ' No es un nombre vli
CREATE TABLE [Hoja1] (Campo1 INTEGER) ' S es correcto el nomb

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

Private Sub Button1_Click(sender As Object,


e As EventArgs) Handles Button1.Click

Try
' Configuramos y abrimos la conexin.
'
Using cnn As New OleDbConnection( _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Libro1.xls;" & _
"Extended Properties='Excel 8.0;HDR=Yes;'")

cnn.Open()

Dim cmd As OleDbCommand = cnn.CreateCommand()

' Creamos la consulta SQL.


'
cmd.CommandText = _
"CREATE TABLE Clientes(" & _
"IdCliente INTEGER," & _
"Nombre TEXT (50)," & _
"NIF TEXT (9)," & _
"Domicilio TEXT (30)," & _
"CodPostal INTEGER," & _
"Localidad TEXT (30)," & _
"[Fecha Alta] DATETIME," & _
"Notas TEXT)"

' Ejecutamos el comando.


'
cmd.ExecuteNonQuery()

MessageBox.Show("Se ha creado la hoja de trabajo.", _


"CREATE TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)

' Insertamos dos filas.


'
cmd.CommandText = _
"INSERT INTO Clientes VALUES (" & _
"1,'Juan Lpez Prez','25222011J'," & _
"'C/. Bernab Soriano, 24 - 8 Izq.',23001,'JAN','28/04/1962',NULL)"

cmd.ExecuteNonQuery()
cmd.CommandText = _
"INSERT INTO Clientes VALUES (" & _
"2,'Flix Cuesta Rodrguez','25940103F'," & _
"'C/. Blas Infante, 35 - 7 A',23008,'JAN','21/08/1961','Esto es una
nota')"

cmd.ExecuteNonQuery()

MessageBox.Show("Se han insertado los dos registros.", _


"INSERT INTO", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
End Using

Catch ex As Exception
MessageBox.Show(ex.Message)

End Try

End Sub

Para ms informacin sobre el ISAM de Excel, consulte el


siguiente artculo tcnico:

Trabajar con ADO, DAO y Excel

Modificar 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
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.

Aadir nuevos 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 Text y Binary, 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 nombreTabla ADD COLUMN nombreCampo tipoDato [(tamao)]


[WITH COMPRESSION | WITH COMP]
[NOT NULL | NULL]
[DEFAULT valorDefecto]
[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""

Nota: 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 Autonumrico a la


tabla Alumnos 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

Modificar 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 Text y
Binary, o el valor por defecto del mismo, siendo su sintaxis la
siguiente:

ALTER TABLE nombreTabla ALTER COLUMN nombreCampo tipoDato [(tamao)]


[WITH COMPRESSION | WITH COMP]
[NOT NULL | NULL]
[DEFAULT valorDefecto]
[ndice]

Si solamente desea establecer o modificar el valor por defecto,


puede utilizar, si as lo desea, la siguiente sintaxis:

ALTER TABLE nombreTabla ALTER COLUMN nombreCampo SET


DEFAULT valorDefecto

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 Diseo 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: No 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 Text:

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: El campo es demasiado pequeo para aceptar
la cantidad de datos que intenta agregar. Intente 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 Autonumrico. 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)

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: Tipo de datos de campo no vlido.
El ejemplo anterior tambin nos puede servir para modificar el
valor de inicio o de incremento de un campo Autonumrico, 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.

Eliminar 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 nombreTabla DROP COLUMN nombreCampo

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.

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.

Sintaxis

Hay tres tipos de sintaxis diferente que puede utilizar,


dependiendo de dnde se encuentren el origen y el destino de
los datos:

1. El origen y el destino se encuentran en la misma base de


datos:

SELECT campo1[, campo2[, ...]] INTO nuevaTabla FROM origen [WHERE False]

2. 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 nuevaTabla IN baseDatosExterna FROM origen [WHERE False]

3. 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 nuevaTabla FROM origen IN baseDatosExterna [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 (MS Access, 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 ''[MS Access;DATABASE=Ruta
IN ''[MS Access;DATABASE=C:\Mis
base datos
documentos\Bd1.md;PWD=contrasea]
externa;PWD=contrasea]

Parmetro Descripcin
campo1, campo2 El nombre de los campos que se van a crear. Al menos debe
de crearse un campo.
nuevaTabla El nombre de la tabla que deseamos crear.
origen El nombre de la tabla de origen.
baseDatosExterna 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.
WHERE False Si se indica la clusula opcional WHERE False, slo se
copiar la estructura de la tabla indicada en el origen.
Tambin se puede especificar WHERE 1=0.

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 RecordsAffected del mtodo Execute del objeto
Connection de ADO, o leyendo el mtodo ExecuteNonQuery
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
'
MessageBox.Show(CInt(.ExecuteNonQuery()))
End With

Ejemplos

1. 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 Long
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

2. 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 Long
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

3. Por ltimo, vamos a crear un archivo de texto delimitado con


los datos de una tabla de Access 2007, utilizando ADO .NET:

' Importamos el siguiente espacio de nombre


'
Imports System.Data.OleDb
Private Sub Button1_Click(sender As Object,
e As EventArgs) Handles Button1.Click

Try
' Configuramos y abrimos la conexin con
base de la
' de datos de
Access.
'
Using cnn As New OleDbConnection( _
"Provider = Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Mis documentos\Database1.accdb")

cnn.Open()

' Creamos el objeto Command


'
Dim cmd As OleDbCommand = cnn.CreateCommand()

' Creamos la cadena SQL de creacin de tabla para el exportar


' los datos de dos campos de la tabla Clientes.
'
cmd.CommandText = "SELECT IdCliente, Nombre INTO Clientes#txt" &
_
" IN 'C:\Mis documentos' 'TEXT;HDR=Yes'" & _
" FROM Clientes"

' Ejecutamos la consulta.


'
cmd.ExecuteNonQuery()

MessageBox.Show("Se ha creado el archivo de texto.", _


"Exportar tabla", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
End Using

Catch ex As Exception
MessageBox.Show(ex.Message, _
"Error al crear el archivo de texto", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try

End Sub

Eliminar 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.

Sintaxis

DROP TABLE [nombre tabla]

Parmetro 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 Execute de un
objeto Database abierto (DAO) o de un objeto Connection (ADO),
al igual que por el mtodo ExecuteNonQuery 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 Clientes (parte 1) y Facturas (parte
varios), mediante la instruccin DROP TABLE no podemos
eliminar la tabla Clientes, lo que no impide que s podamos
eliminar la tabla Facturas. Para eliminar la tabla Clientes,
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.

Ejemplos

1. El siguiente ejemplo eliminar del disco el archivo Clientes.txt.


Ntese que si se tiene un archivo de configuracin de
esquema Schema.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]"

' Cierro la conexin


cnn.Close

2. 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

3. 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

Private Sub Button1_Click(sender As Object,


e As EventArgs) Handles Button1.Click

Try
' Configuramos y abrimos laconexin.
'
Using cnn As New OleDbConnection( _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Libro1.xls;" & _
"Extended Properties='Excel 8.0;HDR=Yes;'")

cnn.Open()

Dim cmd As OleDbCommand = cnn.CreateCommand()

' Creamos la consulta SQL.


'
cmd.CommandText = "DROP TABLE [Clientes]"

' Ejecutamos el comando.


'
cmd.ExecuteNonQuery()

MessageBox.Show("Se ha eliminado la hoja de trabajo.", _


"DROP TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
End Using

Catch ex As Exception
MessageBox.Show(ex.Message)

End Try

End Sub

Captulo IV. Cmo crear y eliminar los ndices de las tablas


Por Enrique Martnez Montejo
[Microsoft Most Valuable Professional - Visual Basic]
ltima revisin: 02/04/2004
Contenido

Introduccin
La clusula CONSTRAINT y la integridad referencial
Tabla principal y tabla externa
La integridad referencial
Cmo crear un ndice
Con la instruccin CREATE TABLE
Con la instruccin ALTER TABLE
Con la instruccin CREATE ... INDEX
Cmo eliminar un ndice
Con la instruccin ALTER TABLE
Con la instruccin DROP INDEX

Introduccin

Podemos definir el trmino ndice como el recurso necesario


para acelerar la bsqueda y ordenacin de los datos incluidos
en una tabla, utilizando para ello valores clave que pueden
exigir que 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.

La clusula CONSTRAINT y la integridad referencial

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 tablaExterna [(campoExterno1 [, campoExterno2])]
[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[, principaI2[, ...]]) |
UNIQUE (nico1[, nico2[, ...]]) |
FOREIGN KEY [NO INDEX] (ref1[,ref2[, ...]])
REFERENCES tablaExterna [(campoExterno1 [,campoExterno2 [, ...]])]
[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.

Argumento 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 l
nico1, nico2 El nombre del campo o de los campos que han sido designados para formar u
ref1, ref2 El nombre de un campo o de los campos de la clave externa a los que se hace
tablaExterna El nombre de la tabla externa que contiene el campo o los campos especifica
campoExterno1, campoExterno El nombre del campo o campos de tablaExterna especificados por ref1, ref2.
2 externa.

Son tres los tipos de ndices que se pueden crear mediante la


clusula CONSTRAINT:

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 Clientes_Facturas a la


tabla Facturas 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 Clientes_Facturas entre
el campo que conforma la clave principal de la tabla Clientes y el
campo NumClienteexterno de la tabla Facturas, por lo que el
motor Jet exigir que se cumpla la integridad referencial de los
datos.
Tabla principal y tabla externa

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 Clientes,
donde cada registro se identifica de manera nica mediante el
campo IdCliente, 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 Facturas de clientes, cuyo campo NumCliente est
referenciando a una clave externa existente en la tabla
deClientes, cuya clave principal estar formada por el
campo IdCliente.

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 Facturas puede contener una clave externa
llamada NumCliente (que no tiene por qu denominarse igual
que el nombre de un campo existente en la misma tabla), que
hace referencia a la clave principal llamada PrimaryKey formada
por el campo nico IdCliente de una hipottica tabla de Clientes.

CLIENTES FACTURAS
(Tabla (Tabla
principal) externa)
IdCliente IdFactura
Clave principal de la tabla, IdCliente Clave externa de la tabla,
denominada PrimaryKey denominada NumCliente

La integridad referencial

Podemos definir el trmino integridad referencial como


el conjunto de reglas que 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 laintegridad 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.

Con la instruccin CREATE TABLE

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 INTEGER,
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 ALTER TABLE

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 tablaExterna[(campoExterno1[,campoExterno2[,.
..]])]}

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

Con la instruccin CREATE...INDEX

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:

SI IGNORE NULL es y DISALLOW NULL es Entonces


True False Valor NUL
False False Valor NUL
True o False True Valor NUL

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.
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 ALTER TABLE

Para eliminar un ndice con la instruccin ALTER TABLE, utilice la


siguiente sintaxis:

ALTER TABLE nombreTabla DROP CONSTRAINT nombrendice

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 NumAlbaranes 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

Eliminar un ndice con la instruccin DROP INDEX

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 nombrendice ON nombreTabla

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 Facturas (tabla principal)
y Albaranes (tabla externa), as como las claves principales de
dichas tablas. La misma sintaxis SQL se puede utilizar tambin
con el mtodo Execute del objeto Connection(ADO) y del
objeto Database (DAO):

' Importamos el siguiente espacio de nombre


'
Imports System.Data.OleDb

Private Sub Button1_Click(sender As Object,


e As EventArgs) Handles Button1.Click

Try
' Configuramos y abrimos la conexin.
'
Using cnn As New OleDbConnection( _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Bd1.mdb")
cnn.Open()

Dim cmd As OleDbCommand = cnn.CreateCommand()

' Creo la cadena SQL para eliminar


relacin. la
'
cmd.CommandText = "ALTER TABLE Albaranes DROP CONSTRAINT
FacturasAlbaranes"

' Ejecutamos el comando.


'
cmd.ExecuteNonQuery()

MessageBox.Show("Se ha eliminado la relacin.", _


"ALTER TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)

' Creo la cadena SQL para eliminar la


principal. clave
'
cmd.CommandText = "ALTER TABLE Albaranes DROP CONSTRAINT
ClavePrincipal"
cmd.ExecuteNonQuery()

MessageBox.Show("Se ha eliminado la clave principal de la tabla


Albaranes.", _
"ALTER TABLE", MessageBoxButtons.OK, _
MessageBoxIcon.Information)

' Creo la cadena SQL para eliminar la segunda clave principal.


'
cmd.CommandText = "DROP INDEX ClavePrincipal ON FACTURAS"
cmd.ExecuteNonQuery()

MessageBox.Show("Se ha eliminado la clave principal de la tabla


Facturas", _
"DROP INDEX", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)

End Try

End Sub

Captulo V. Consultas de seleccin


Por Enrique Martnez Montejo
[Microsoft Most Valuable Professional - Visual Basic]
ltima revisin: 04/05/2004

Contenido

Introduccin
La instruccin SELECT
Consultas bsicas
Especificar el origen de los datos
Recuperar informacin de una base de datos
externa
Especificar un alias para el nombre de los
campos
Filtrado y ordenacin de los resuitados
Omitir registros duplicados: predicados
DISTINCT y DISTINCTROW
Seleccionar un nmero de registros: precidado
TOP
Criterios de seleccin
La clusula WHERE
El operador IN
El operador BETWEEN
El operador LIKE
El operador IS NULL
Agrupamiento de registros
Las funciones agregadas COUNT, MAX, MIN
y SUM
La clusula GROUP BY
La clusula HAVING
Ordenar los registros devueltos
La instruccin WITH OWNERACCESS OPTION

Introduccin

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 Lenguaje de Manipulacin de
Datos (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.

La instruccin SELECT

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_bsqueda
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 [].

Especificar el origen 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:

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.

Recuperar informacin de una base de datos externa

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 unatabla 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.

Especificar 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

Filtrado y 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 registros duplicados: predicados DISTINCT y
DISTINCTROW

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.

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 nmero de registros: predicado TOP

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 utilizada
para definir los datos que deseamos seleccionar o manipular.

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 DateValue, 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# * #19-3-2004#
#3/19/2004# #3-19-2004#
#2004/3/19# #2004-3-19#
#03/19/04# #03-19-04#
#19/03/2004# * #19-03-2004#
#03/19/2004# #03-19-2004#
#2004/03/19# #2004-03-19#

* 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#).

La clusula WHERE

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:

<expresin1> Operador <expresin2> Resultado


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
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')

El operador IN

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, ..., valorN)

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')

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')

El operador BETWEEN
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',")

El operador LIKE

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

Expresin se refiere al nombre del campo de la tabla que se


desea comparar. Modelo 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 comodn
Caracteres coincidentes SQL de
SQL de ANSI
Microsoft Jet
_ (signo de
Cualquier carcter ?
subrayado)
Cero o ms caracteres * %
Cualquier nmero #
Cualquier carcter que est
[listaCaracteres]
en listaCaracteres
Cualquier carcter que no est
[!listaCaracteres]
en listaCaracteres

En el argumento listaCaracteres 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 listaCaracteres 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.

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:

Modelo
Tipo de No
SQL SQL Coincidencia
coincidencia coincide
ANSI Jet
'aa', 'aCDa',
Varios caracteres 'a%a' 'a*a' 'ab', 'CDa'
'Abbbba'
Un carcter
'a[&]a' 'a&a' 'aaa'
especial
'ama',
Varios caracteres 'ma%' 'ma*' 'malo', 'maana'
'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
'[a-z]' 'b', 'j', 'k', 'z' '3', '$', 'ab'
caracteres
Fuera de un 'a', 'b', 'z',
'[!a-z]' '9', '&', '%'
rango '9a'
Distinto de un
'[!0-9]' 'A', 'a', '&', '%' '0', '1', '9'
dgito
a[!b-m] 'a[!b-
Combinada (*) 'An9', 'az0', 'a99' 'abc', 'aj0'
[!a-z]' m]#'

(*) 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, FIX: Jet 4.0 Treats "#" as Numeric
Wildcard Character, 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.).

El operador IS NULL

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 Null. Debe de 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

Agrupamiento de registros
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 funciones agregadas COUNT, MAX, MIN y SUM

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 Funciones
agregadas en el Captulo I de este manual.

COUNT

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.

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

MAX y MIN
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. Expresin 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'

SUM
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 GROUP BY

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 nombreTabla [WHERE criterio] GROUP
BY camposAgrupados

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:

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 HAVING

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 nombreTabla [WHERE criterio] GROUP


BY camposAgrupados HAVING nombreCampo = 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'

Ordenar los registros devueltos

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 WITH OWNERACCESS OPTION

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
encuentre el archivo de informacin de grupos de trabajo
(archivo System.mdw) 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 Admin desea crear una consulta


llamada Consulta_Empleados en una base de datos Microsoft
Access, para que todos aquellos usuarios que no tengan permiso
de lectura sobre la tabla Empleados, pueda consultar los datos
incluidos en dicha tabla base:

Nombre de la consulta:
Consulta_Empleados

Sintaxis:
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 objetoRecordset 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 Enrique podr leer los registros de la
tabla Empleados, 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.

Captulo VI. Consultas de accin


Por Enrique Martnez Montejo
[Microsoft Most Valuable Professional - Visual Basic]
ltima revisin: 11/06/2004

Contenido

Introduccin
Consulta de datos anexados: la instruccin INSERT
INTO
Consulta de insercin de un nico registro
Consulta de insercin de mltiples registros
Consulta de actualizacin: la instruccin UPDATE
Consulta de eliminacin: la instruccin DELETE

Introduccin
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 anexados: la instruccin INSERT


INTO

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 Autonumrico, 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 Autonumrico 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
parmetroRecordsAffected 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
.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 nico registro


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 campO2 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#)

Consulta de insercin de mltiples registros

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 (MS Access, 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


IN 'C:\Mis documentos\Bd1.mdb'
externa'

IN ''[MS IN ''[MS Access;DATABASE=C:\Mis


Access;DATABASE=Ruta
base datos documentos\Bd1.md;PWD=contras
externa;PWD=contrase ea]
a]

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\]

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 actualizacin: la instruccin UPDATE

Mediante la instruccin UPDATE podemos crear una consulta de


actualizacin para modificar el valor de los campos de una tabla
segn los criterios especificados en la consulta, siendo su
sintaxis la siguiente:

UPDATE nombreTabla 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 nombreTabla, 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 DELETE

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 Eliminar 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 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 Eliminar 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.

También podría gustarte