Sie sind auf Seite 1von 22

CURSO DE SQL

CAPTULO 51

ndice de contenido
TRABAJAR CON TABLAS................................................................................................................2
DESEO UNA TABLA A MEDIDA.............................................................................................2
CREAR UNA TABLA.....................................................................................................................2
LA CLUSULA CONSTRAINT............................................................................................3
UNA PEQUEA ACLARACIN (PARA NO TENER QUE RASCARNOS LA
CABEZA).............................................................................................................................3
DEFINIR UN CAMPO QUE NO ADMITE DUPLICADOS: UNIQUE..............................3
DEFINIR UN CAMPO COMO CLAVE PRINCIPAL: PRIMARY KEY.............................4
DEFINIR UN CAMPO COMO REQUERIDO: NOT NULL...............................................5
DEFINIR UN CAMPO COMO AUTONUMRICO Y DEFINIR SU INTERVALO DE
INCREMENTO......................................................................................................................6
COMBINAR DEFINICIN DE PROPIEDADES................................................................8
DEFINIR UNA CLAVE EXTERNA: FOREING KEY.........................................................8
BORRAR UNA TABLA................................................................................................................10
CREAR NDICES (con CREATE INDEX)..................................................................................10
NDICES CON REGISTROS DUPLICADOS.........................................................................11
PROHIBIR VALORES NULOS EN EL NDICE...............................................................12
IGNORAR VALORES NULOS EN EL NDICE................................................................13
NDICE CON REGISTROS NO DUPLICADOS....................................................................14
CREAR UN NDICE CON CLAVE PRIMARIA................................................................15
ELIMINAR NDICES...................................................................................................................15
MODIFICAR UNA TABLA..........................................................................................................15
AADIR CAMPOS..................................................................................................................16
BORRAR CAMPOS.................................................................................................................16
CREAR NDICES (con ALTER TABLE)................................................................................17
CREAR UNA CLAVE PRINCIPAL....................................................................................17
CREAR UNA CLAVE EXTERNA......................................................................................17
MODIFICAR EL TIPO DE RELACIN........................................................................18
AADIR UNA REGLA DE VALIDACIN............................................................................20
ELIMINAR NDICES..............................................................................................................20
PARA FINALIZAR EL CAPTULO (Y EL CURSO!)....................................................................21

La BD donde estn los ejemplos de este captulo os la podis bajar aqu.

Vistame en http://siliconproject.com.ar/neckkito/

TRABAJAR CON TABLAS


DESEO UNA TABLA A MEDIDA
Con lo explicado en los captulos anteriores tenemos un
amplio abanico para seleccionar datos, filtrarlos, re-filtrarlos
y volverlos a filtrar... todo sea por obtener la informacin tal
y como nosotros queremos. Y, por supuesto, ya sabemos
como actualizar datos en registros, anexarlos, eliminarlos...
Como siempre, seguiremos con nuestra eterna BD de ejemplo.
Veremos en este captulo cmo podemos crearnos una tabla con SQL, definiendo sus campos,
cmo podemos definir tambin algunas de sus propiedades, cmo podemos crear claves
primarias, claves externas... Y tambin veremos cmo podemos modificar tablas: modificar o
eliminar columnas, eliminar ndices...
En definitiva, aprenderemos a crearnos una tabla a medida.

CREAR UNA TABLA


La forma ms simple de crear una tabla la podemos ver en la siguiente estructura:
CREATE TABLE nomTabla (nomCampo1 tipoCampo (longitudCampo),..., nomCampoN
tipoCampo (longitudCampo))
teniendo en cuenta que utilizaremos <longitudCampo> en aquellos campos en los que tenga
sentido determinar una longitud. Si no indicamos la longitud el campo adoptar el valor por
defecto de Access.
Por ejemplo, vamos a crear la tabla TProductos con tres campos: [CodProd] (de tipo texto y de
longitud 5), [DescrProd] (de tipo texto y de longitud 25) e [ImportProd] (de tipo moneda).
Nuestro cdigo quedara de la siguiente manera2:

Private Sub cmdCreaTProductos_Click()


On Error GoTo sol_err
Dim miSql As String
miSql = "CREATE TABLE TProductos (CodProd STRING (5), DescripProd STRING (25)," _
& " ImportProd CURRENCY)"

Creo_tabla:
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha creado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3010 Then
DoCmd.DeleteObject acTable, "TProductos"
2

Algunos de los cdigos que se utilizarn llevan control de errores. El error 3010 se produce cuando la tabla ya existe. Por eso, si
salta dicho error, el cdigo borra la tabla existente y vuelve a crearla de nuevo en funcin de lo declarado en la SQL.

Vistame en http://siliconproject.com.ar/neckkito/

Resume Creo_tabla

Else
MsgBox "Se ha producido el error " & Err.Number & " " & Err.Description
Resume Salida
End If
End Sub

Nota: es posible que, tras ejecutar el cdigo, no nos aparezca TProductos en la ventana de
base de datos o en el panel de navegacin (segn la versin de Access que utilicemos). Si
seleccionamos cualquier tabla que tengamos en la BD y pulsamos 'F5' se producir una
actualizacin y nuestra tabla aparecer como por arte de magia

LA CLUSULA CONSTRAINT
Para establecer limitaciones o definiciones en nuestros campos debemos utilizar la clusula
CONSTRAINT. Avanzaremos que tambin la podemos utilizar para establecer relaciones con
otra tabla.
Podemos utilizar CONSTRAINT de dos maneras:

Para realizar la limitacin en un slo campo


Para realizar la limitacin en un grupo de campos

A continuacin veremos algunas restricciones que podemos aplicar en nuestros campos

UNA PEQUEA ACLARACIN (PARA NO TENER QUE RASCARNOS LA CABEZA)


En los siguientes cdigos que veremos podris observar cmo yo estoy utilizando CONSTRAINT
para sentar las propiedades de los campos. Sin embargo, segn en qu casos, podemos obviar
la estructura de CONSTRAINT y escribir directamente la propiedad que queremos que adopte
el campo creado.
Por eso, en los cdigos, os indicar en color gris, como comentario de cdigo, cmo sera la
SQL con esta utilizacin directa de las definiciones de las propiedades.
En definitiva, que mataremos dos pjaros de un tiro
Lo importante es que lo veis escrito de una manera u otra seamos capaces de entender qu
dice la SQL

DEFINIR UN CAMPO QUE NO ADMITE DUPLICADOS: UNIQUE


Vamos a borrar nuestra tabla TProductos para volverla a crear, pero esta vez la crearemos
haciendo que [CodProd] no admita duplicados. Para conseguir tal propsito utilizamos la
propiedad UNIQUE.
Nuestro cdigo nos quedara as:

Vistame en http://siliconproject.com.ar/neckkito/


Private Sub cmdUnique_Click()
On Error GoTo sol_err
Dim miSql As String
miSql = "CREATE TABLE TProductos (CodProd STRING (5) CONSTRAINT miIndice UNIQUE," _
& " DescripProd STRING (25), ImportProd CURRENCY)"
'----------Asignacin directa-----' miSql = "CREATE TABLE TProductos (CodProd STRING UNIQUE, DescripProd STRING (25)," _
'
& "ImportProd CURRENCY)"
'----------------------------------

Creo_tabla:
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha creado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3010 Then
DoCmd.DeleteObject acTable, "TProductos"
Resume Creo_tabla
Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description
Resume Salida
End If
End Sub

Fijaos que:

Defino el campo (nombre-tipo-longitud)


Restrinjo el campo (CONSTRAINT)
Indico que es un ndice (miIndice) -ojo: podemos emplear la palabra que queramosIndico la propiedad (UNIQUE)

Es decir:

CodProd STRING (5) CONSTRAINT miIndice UNIQUE

DEFINIR UN CAMPO COMO CLAVE PRINCIPAL: PRIMARY KEY


Al igual que hemos indicado que queramos un campo sin duplicados, podemos indicar que
queremos una clave principal.
Por ejemplo, nuestro cdigo de producto ser la clave principal.
Nuestro cdigo quedara as:
4

Vistame en http://siliconproject.com.ar/neckkito/


Private Sub cmdPrimaryKey_Click()
On Error GoTo sol_err
Dim miSql As String
miSql = "CREATE TABLE TProductos (CodProd STRING (5) CONSTRAINT miClave PRIMARY KEY," _
& " DescripProd STRING (25), ImportProd CURRENCY)"

'----------Asignacin directa-----'
'

miSql = "CREATE TABLE TProductos (CodProd STRING (5) PRIMARY KEY," _


& " DescripProd STRING (25), ImportProd CURRENCY)"

'---------------------------------Creo_tabla:
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha creado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3010 Then
DoCmd.DeleteObject acTable, "TProductos"
Resume Creo_tabla
Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description
Resume Salida
End If
End Sub

Si os fijis, la sistemtica es muy similar en la definicin de la propiedad sin duplicados:


[CodProd] de tipo TEXTO y longitud 5 Restringido - ser mi clave, que ser clave principal
CodProd

STRING

(5)

CONSTRAINT

miClave

PRIMARY KEY

DEFINIR UN CAMPO COMO REQUERIDO: NOT NULL


Para definir un campo como requerido debemos utilizar la propiedad NOT NULL.
En nuestra tabla TProductos definiremos una clave principal ([CodProd]) y exigiremos que se
deba rellenar el campo [DescripProd].
El cdigo sera:

Vistame en http://siliconproject.com.ar/neckkito/


Private Sub cmdNotNull_Click()
On Error GoTo sol_err
Dim miSql As String
miSql = "CREATE TABLE TProductos (CodProd STRING (5) CONSTRAINT miClave PRIMARY KEY," _
& " DescripProd STRING (25) CONSTRAINT miNoNulo NOT NULL, ImportProd CURRENCY)"
'----------Asignacin directa-----' miSql = "CREATE TABLE TProductos (CodProd STRING (5) PRIMARY KEY," _
'
& " DescripProd STRING (25) NOT NULL, ImportProd CURRENCY)"
'----------------------------------

Creo_tabla:
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha creado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3010 Then
DoCmd.DeleteObject acTable, "TProductos"
Resume Creo_tabla
Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description
Resume Salida
End If
End Sub

No creo que haga ya falta insistir en la estructura del CONSTRAINT...NOT NULL, verdad?

DEFINIR UN CAMPO COMO AUTONUMRICO Y DEFINIR SU INTERVALO DE


INCREMENTO
Vamos a aadir a nuestra tabla TProductos un [IdProd] autonumrico, que ser clave principal,
y que, en lugar de tener el incremento predeterminado de una unidad, va a tener un
incremento de tres unidades.
Si recordamos lo visto en el captulo 1 de este curso sabremos que para definir un
autonumrico debemos definir su tipo como COUNTER / AUTOINCREMENT
Por intuicin ya deberamos saber, pues, cmo podra ser nuestra SQL, aunque tiene un
pequeo truco. Sera la que aparece en el siguiente cdigo:

Vistame en http://siliconproject.com.ar/neckkito/


Private Sub cmdAutonumerico_Click()
On Error GoTo sol_err
Dim miSql As String
miSql = "CREATE TABLE TProductos (IdProd AUTOINCREMENT(1,3) CONSTRAINT miClave PRIMARY KEY," _
& " CodProd STRING (5), DescripProd STRING (25), ImportProd CURRENCY)"

'----------Asignacin directa-----' miSql = "CREATE TABLE TProductos (IdProd AUTOINCREMENT(1,3) PRIMARY KEY," _
'
& " CodProd STRING (5), DescripProd STRING (25), ImportProd CURRENCY)"
'----------------------------------

Creo_tabla:
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha creado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3010 Then
DoCmd.DeleteObject acTable, "TProductos"
Resume Creo_tabla
Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description
Resume Salida
End If
End Sub

Si nos fijamos hemos definido el tipo de campo [IdProd] como AUTOINCREMENT (si
hubiramos utilizado COUNTER funcionara exactamente igual), y, entre parntesis, le hemos
pasado dos valores. Supongo que alguien se preguntar: Y qu significan?.
Pues (1,3) significa que:
1 El primer registro que se introduzca empezar por 1. Si hubiramos puesto 15 el primer
registro hubiera tenido un [IdProd] igual a 15
3 Los incrementos se producirn de 3 en 3.
Es decir, que la introduccin de registros nos quedara as:

Vistame en http://siliconproject.com.ar/neckkito/

COMBINAR DEFINICIN DE PROPIEDADES


Como apunte final a lo explicado hasta ahora debo deciros
que las anteriores propiedades pueden combinarse en una
misma SQL (por si haba alguna duda).
Por ejemplo, para crear la tabla TProductos con un
autonumrico que sea clave principal, con un campo
[CodProd] que sea a la vez un campo sin duplicados y de
introduccin obligatoria y con [DescripProd] que sea un
campo de introduccin obligatoria podramos utilizar el
siguiente cdigo3:

Private Sub cmdTProductosCombinado_Click()


On Error GoTo sol_err
Dim miSql As String
miSql = "CREATE TABLE TProductos (IdProd COUNTER (1,5) CONSTRAINT miClave PRIMARY KEY," _
& " CodProd STRING (5) CONSTRAINT miIndice UNIQUE NOT NULL," _
& " DescripProd STRING (25) CONSTRAINT miIndice2 UNIQUE, ImportProd CURRENCY)"
'----------Asignacin directa-----' miSql = "CREATE TABLE TProductos (IdProd COUNTER (1,5) PRIMARY KEY," _
'
& " CodProd STRING (5)UNIQUE NOT NULL, DescripProd STRING (25) UNIQUE," _
'
& " ImportProd CURRENCY)"
'----------------------------------

Creo_tabla:
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha creado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3010 Then
DoCmd.DeleteObject acTable, "TProductos"
Resume Creo_tabla
Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description
Resume Salida
End If
End Sub

Como podis observar el proceso es tan simple como aadir la definicin de las propiedades
una tras otra.

DEFINIR UNA CLAVE EXTERNA: FOREING KEY


Por si alguien anda ligeramente perdido, y de una manera rpida, diremos que una clave
externa es una clave de relacin con otra tabla.
Por ejemplo,

Recordad que, en SQL, para un campo autonumrico AUTOINCREMENT y COUNTER son sinnimos. En el ejemplo anterior he
utilizado AUTOINCREMENT, y en el ejemplo que sigue he utilizado COUNTER.

Vistame en http://siliconproject.com.ar/neckkito/

Si nos fijamos en la tabla TPedidos diramos que:

Id es la clave principal
NumMes es la clave externa, porque nos relaciona la tabla con una tabla externa, que
es TMeses.

Clarificados conceptos vamos a realizar con SQL lo que yo he realizado manualmente en


Access.
La estructura para crear una clave externa es la siguiente:
CONSTRAINT
miClaveExt
FOREIGN
nomTablaExterna (nomCampoExterno)

KEY

(nomCampoInterno)

REFERENCES

Es decir, que nuestro cdigo4 quedara as.

Private Sub cmdForeingKey_Click()


Dim miSql As String
miSql = "CREATE TABLE TPedidos (Id LONG CONSTRAINT miClave PRIMARY KEY," _
& " NumMes LONG, Cliente STRING (25), ImpPedido CURRENCY," _
& " CONSTRAINT miClaveExt FOREIGN KEY (NumMes) REFERENCES TMeses)"

CurrentDb.Execute miSql
MsgBox "La tabla 'TPedidos' se ha creado correctamente", vbInformation, "OK"
End Sub

Fijaos en un detalle: en TPedidos el campo se llama [NumMes]; en TMeses el campo tambin


se llama [NumMes]. Es por ello por lo que he podido obviar el nombre del campo en
<REFERENCES TMeses (NumMes)>, y simplemente he escrito <REFERENCES TMeses>.
Para eliminar toda duda la SQL, con nombres de campo diferentes, nos debera haber quedado
as:

miSql = "CREATE TABLE TPedidos (Id LONG CONSTRAINT miClave PRIMARY KEY," _
& " NumMes2 LONG, Cliente STRING (25), ImpPedido CURRENCY," _
& " CONSTRAINT miClaveExt FOREIGN KEY (NumMes2) REFERENCES TMeses (NumMes))"

Por qu el cdigo no lleva control de errores? Porque desde el momento en que establecemos relaciones no podemos borrar la
tabla porque Access no nos dejar: nos dir que no se puede borrar la tabla porque existen relaciones entre tablas. El proceso
sera, pues, primero eliminar la relacin y despus borrar la tabla. Como an no sabemos cmo eliminar relaciones (pero lo
veremos en breve!) omito el control de errores, por ahora.

Vistame en http://siliconproject.com.ar/neckkito/

BORRAR UNA TABLA


As como podemos crear una tabla con SQL tambin la
podemos borrar. Para ello utilizaremos la instruccin DROP.
El procedimiento es sencillo, y corresponde a la siguiente
estructura:
DROP TABLE nomTabla
Supongamos que queremos eliminar la tabla TProductos. El
cdigo que nos realizara lo anterior sera5:

Private Sub cmdBorraTProductos_Click()


On Error GoTo sol_err
Dim miSql As String
miSql = "DROP TABLE TProductos"
CurrentDb.Execute miSql
MsgBox "La tabla 'TProductos' se ha eliminado correctamente", vbInformation, "OK"
Salida:
Exit Sub
sol_err:
If Err.Number = 3376 Then
MsgBox "La tabla 'TProductos' no se puede eliminar porque no existe", _
vbCritical, "TABLA INEXISTENTE"
Else
MsgBox "Se ha producido el error " & Err.Number & " - " & Err.Description
End If
Resume Salida
End Sub

Como vemos en el cdigo, si la tabla no existiera nos saltara el error 3376. El cdigo gestiona
dicho error a travs del control de errores.

CREAR NDICES (con CREATE INDEX)


Segn nuestro amigo Access, un ndice <<especifica el orden de los registros a los que se
tiene acceso desde las tablas de la base de datos y si se aceptan o no los registros duplicados,
lo que proporciona un acceso a los datos eficaz>>
As pues, podemos, con ayuda de SQL, crear un ndice (o varios) en una tabla.
Vamos a crearnos la tabla TProductos con el cdigo para crear una BD ms simple que hemos
aprendido prcticamente a principio de este captulo; es decir, TProductos slo con los campos
(sin ningn tipo de restricciones).
Si seguimos la definicin expuesta anteriormente podemos fijarnos en que dice <<... y si se
aceptan o no los registros duplicados...>>.
Vamos a empezar a trabajar suponiendo que s se aceptan registros duplicados. El objetivo es
crear un ndice sobre los campos [CodProd] y [DescripProd] (lo que nos lleva a concluir que
5

Revisad la nota 4

10

Vistame en http://siliconproject.com.ar/neckkito/

podemos crear un ndice sobre uno o ms campos, verdad? ).

NDICES CON REGISTROS


DUPLICADOS
La estructura ms simple para crear un ndice de las
caractersticas que acabamos de mencionar sera:
CREATE INDEX miInidice ON nomTabla (nomCampo1,
, nomCampoN)
Ergo nuestro cdigo sera:

Private Sub cmdCreaIndice_Click()


Dim miSql As String
miSql = "CREATE INDEX miIndice ON TProductos (CodProd,DescripProd)"
CurrentDb.Execute miSql
MsgBox "ndices creados satisfactoriamente", vbInformation, "OK"
End Sub

Alguien podra pensar: Y qu hemos conseguido con lo anterior?. OK. En la tabla TProductos
yo he introducido varios registros, de la manera siguiente:

Si ahora cierro la tabla y la vuelvo a abrir me encuentro con lo siguiente:

Conclusin: que al haber convertido en ndices los dos campos se produce, automticamente,
una ordenacin de la siguiente manera:

Primero, se ordena [CodProd], en este caso alfabticamente


Segundo, se ordena [DescripProd], en este caso alfabticamente.

Lo vemos?
Pues ahora vamos a cambiar la ordenacin del ndice sobre el campo [DescripProd].
11

Vistame en http://siliconproject.com.ar/neckkito/

Aprovecharemos para ver cmo declaro explcitamente tambin la ordenacin sobre el campo
[CodProd]. Nuestro cdigo quedara as:

Private Sub cmdCreaIndice2_Click()


Dim miSql As String
miSql = "CREATE INDEX miIndice ON TProductos (CodProd ASC,DescripProd DESC)"

CurrentDb.Execute miSql
MsgBox "ndices creados satisfactoriamente", vbInformation, "OK"
End Sub

Y si abro la tabla TProductos (es necesario borrarla y volverla a crear antes de realizar el
proceso!) los resultados son los siguientes:

Como observamos, el campo [CodProd] muestra una ordenacin ascendente porque as lo


hemos indicado en la SQL, a travs de ASC, mientras que [DescripProd] muestra una
ordenacin descendente porque hemos indicado que as fuera a travs de DESC.
Es decir, que la estructura as sera:
CREATE INDEX miInidice ON nomTabla (nomCampo1 [ASC|DESC], , nomCampoN
[ASC|DESC])

PROHIBIR VALORES NULOS EN EL NDICE


Podra interesarnos que no se permitieran valores nulos en el ndice. En ese caso la estructura
de la SQL sera:
CREATE INDEX miInidice ON nomTabla (nomCampo1, , nomCampoN) WITH
DISALLOW NULL
En definitiva, que deberamos utilizar DISALLOW NULL
Nuestro cdigo sera:

12

Vistame en http://siliconproject.com.ar/neckkito/


Private Sub cmdCreaIndiceDisallowNull_Click()
Dim miSql As String
miSql = "CREATE INDEX miIndice ON TProductos (CodProd ASC,DescripProd DESC)" _
& " WITH DISALLOW NULL"

CurrentDb.Execute miSql
MsgBox "ndices creados satisfactoriamente", vbInformation, "OK"
End Sub

Si ahora escribo, en TProductos, lo siguiente:

dejando en blanco [CodProd], e intento ir a un nuevo registro, obtengo lo siguiente:

y no puedo aadir ms registros hasta que no introduzca informacin en el campo [CodProd].

IGNORAR VALORES NULOS EN EL NDICE


La estructura para esta SQL sera:
CREATE INDEX miInidice ON nomTabla (nomCampo1, , nomCampoN) WITH
IGNORE NULL
Es decir, que deberamos utilizar IGNORE NULL
Nuestro cdigo sera el siguiente:

Private Sub cmdCreaIndiceIgnoreNull_Click()


Dim miSql As String
miSql = "CREATE INDEX miIndice ON TProductos (CodProd ASC,DescripProd DESC)" _
& " WITH IGNORE NULL"

13

Vistame en http://siliconproject.com.ar/neckkito/

CurrentDb.Execute miSql
MsgBox "ndices
vbInformation, "OK"
End Sub

creados

satisfactoriamente",

La ordenacin de nuestra tabla se mostrara as:

NDICE CON REGISTROS NO DUPLICADOS


Podemos especificar que nuestro ndice no admita valores duplicados. Para ello la estructura de
la SQL sera:
CREATE UNIQUE INDEX miIndice ON nomTabla (nomCampo)
Por ejemplo, en TProductos queremos que el campo [CodProd] sea ndice sin duplicados.
Deberamos programar el siguiente cdigo:

Private Sub cmdCreaIndiceSinDuplicados_Click()


Dim miSql As String
miSql = "CREATE UNIQUE INDEX miIndice ON TProductos (CodProd)"
CurrentDb.Execute miSql
MsgBox "ndice creado satisfactoriamente", vbInformation, "OK"
End Sub

Lgicamente, si nuestro ndice no admite duplicados y es importante para nosotros (y nuestra


BD) lo ms lgico sera que no dejramos introducir valores nulos. En consecuencia
deberamos cambiar ligeramente la SQL, as:

Private Sub cmdCreaIndiceSinDuplicados2_Click()


Dim miSql As String
miSql = "CREATE UNIQUE INDEX miIndice ON TProductos (CodProd)" _
& " WITH DISALLOW NULL"
CurrentDb.Execute miSql
MsgBox "ndice creado satisfactoriamente", vbInformation, "OK"
End Sub

14

Vistame en http://siliconproject.com.ar/neckkito/

CREAR UN NDICE CON CLAVE PRIMARIA


Si queremos crear un ndice asignando una clave principal
(ojo, slo puede existir un nico ndice que sea clave
principal) seguiremos la estructura que ya conocemos...
CREATE INDEX miIndice ON nomTabla (nomCampo)
WITH PRIMARY
aadiendo WITH PRIMARY y teniendo en cuenta que si el
campo es clave principal ya no debemos preocuparnos por
los valores nulos o los registros duplicados (la clave
principal no los admite por definicin).
Nuestro cdigo quedara as:

Private Sub cmdCreaIndicePrimary_Click()


Dim miSql As String
miSql = "CREATE INDEX miIndice ON TProductos (CodProd)" _
& " WITH PRIMARY"
CurrentDb.Execute miSql
MsgBox "ndice creado satisfactoriamente", vbInformation, "OK"
End Sub

Fcil, no?

ELIMINAR NDICES
Para eliminar un ndice debemos utilizar la estructura:
DROP INDEX nombreIndice ON nomTabla
Vamos a suponer que hemos creado el ndice miIndice sobre la tabla TProductos utilizando
cualquiera de los mtodos explicados anteriormente. Vamos a eliminar ese ndice a travs del
siguiente cdigo:

Private Sub cmdBorraIndice_Click()


Dim miSql As String
miSql = "DROP INDEX miIndice ON TProductos"
CurrentDb.Execute miSql
MsgBox "ndice eliminado correctamente", vbInformation, "OK"
End Sub

Y listo.

MODIFICAR UNA TABLA


Una vez creada ya la tabla, o teniendo una tabla existente, podemos modificar tanto campos
15

Vistame en http://siliconproject.com.ar/neckkito/

como ndices.
Como veremos, las diferentes operaciones tienen una
estructura muy similar. nicamente hay que saber
pronunciar las palabras mgicas para que el sortilegio
surja efecto
Veamos pues qu podemos hacerle a nuestra tabla.

AADIR CAMPOS
La estructura para aadir un campo sera:
ALTER TABLE nomTabla ADD COLUMN nomCampo tipoCampo
Supongamos que en nuestra tabla TMeses queremos aadir el campo [Estacion], de tipo texto
con una longitud mxima de 10 caracteres. Nuestro cdigo debera ser as:

Private Sub cmdModifAadeCampos_Click()


Dim miSql As String
miSql = "ALTER TABLE TMeses ADD COLUMN Estacion STRING(10)"
CurrentDb.Execute miSql
MsgBox "El campo se ha creado correctamente", vbInformation, "OK"
End Sub

BORRAR CAMPOS
Caramba! Nos hemos equivocado y debemos borrar el campo [Estacion] que acabamos de
crear. Cmo lo hacemos?
Pues la estructura de la SQL sera:
ALTER TABLE nomTabla DROP COLUMN nomCampo
Es decir, que escribiramos:

Private Sub cmdModifBorraCampos_Click()


Dim miSql As String
miSql = "ALTER TABLE TMeses DROP COLUMN Estacion"
CurrentDb.Execute miSql
MsgBox "El campo se ha borrado correctamente", vbInformation, "OK"
End Sub

De nuevo, fcil, no?

16

Vistame en http://siliconproject.com.ar/neckkito/

CREAR NDICES (con ALTER TABLE)


Al igual que hemos hecho con los campos podemos
modificar los ndices de las tablas. De hecho, si os fijis, es
como otro sistema paralelo a lo que comentbamos en
apartados anteriores utilizando, en aquel caso, CREATE
INDEX

CREAR UNA CLAVE PRINCIPAL


Vamos, manualmente, a eliminar la clave principal de la
tabla TMeses. Ahora la volveremos a crear, pero a travs de
SQL.
La estructura para realizar esto sera:
ALTER TABLE nomTabla ADD CONSTRAINT miClave PRIMARY KEY(nomCampo)
Es decir, siguiendo el ejemplo:

Private Sub cmdModifCreaClavePrincipal_Click()


Dim miSql As String
miSql = "ALTER TABLE TMeses ADD CONSTRAINT miClave PRIMARY KEY(NumMes)"

CurrentDb.Execute miSql
MsgBox "Clave principal creada correctamente", vbInformation, "OK"
End Sub

CREAR UNA CLAVE EXTERNA


Bueno... Ya hemos visto cmo crear una clave principal. Veamos cmo podemos crear una
clave externa.
Vamos a asegurarnos que creamos desde cero la tabla TPedidos, simple y llana (si ya la
tuviramos creada la borramos), eso s, con una clave principal. Para crearla podemos ejecutar
la siguiente SQL:

miSql = "CREATE TABLE TPedidos (Id LONG CONSTRAINT miClave PRIMARY KEY," _
& " NumMes LONG, Cliente STRING (25), ImpPedido CURRENCY)"

Vamos a crear una clave externa con el campo [NumMes] entre las tablas TMeses y TPedidos.
La estructura de dicha construccin sera:
ALTER
TABLE
nomTabla
ADD
CONSTRAINT
miClaveExt
FOREIGN
nomCampoInterno REFERECES nomTablaExterna(nomCampoExterno)
Es decir:

17

Vistame en http://siliconproject.com.ar/neckkito/

KEY


Private Sub cmdModifCreaClaveExterna_Click()
Dim miSql As String
miSql = "ALTER TABLE TPedidos ADD CONSTRAINT miClaveExt FOREIGN KEY (NumMes)" _
& " REFERENCES TMeses(NumMes)"

CurrentDb.Execute miSql
MsgBox "La clave externa se ha creado correctamente", vbInformation, "OK"
End Sub

Os recuerdo que para comprobar la efectividad de nuestro cdigo basta con abrir la ventana
relaciones y mostrar estas dos tablas: debera aparecernos la relacin.

MODIFICAR EL TIPO DE RELACIN


Sabemos (y si no lo sabemos lo aprenderemos aqu) que cuando creamos una relacin, al
exigir integridad referencial, podemos realizar dos operaciones:

Actualizar campos en cascada


Eliminar campos en cascada

Alguien se ha perdido? Espero que esta imagen sirva para refrescar memorias:

Tambin podemos definir estas dos propiedades de la relacin en nuestra SQL, realizando una
pequea modificacin en la estructura. Es decir:
ALTER
TABLE
nomTabla
ADD
CONSTRAINT
miClaveExt
FOREIGN
KEY
nomCampoInterno REFERECES nomTablaExterna(nomCampoExterno) [ON UPDATE
CASCADE | ON DELETE CASCADE]

18

Vistame en http://siliconproject.com.ar/neckkito/

Sin embargo, si intentamos ejecutar un cdigo utilizando


DoCmd.RunSQL o CurrentDb.Execute no hacemos ms que
obtener errores, o bien de la clusula CONSTRAINT o bien
de la propia instruccin SQL (y eso lo s por experiencia
propia... je, je...).
Qu pasa? Pues que el motor Jet de Access no es capaz de
ejecutar esos dos comandos (UPDATE y DELETE CASCADE).
Curioso, verdad?
La solucin pasa por utilizar una combinacin de SQL y
conexin ADO para que nuestro cdigo no falle ms que
una escopeta de feria. Es decir, que nuestros cdigos
deberan quedar de la siguiente manera, para actualizar
campos en cascada:

Private Sub cmdModifCreaClaveExterna_Click()


Dim miSql As String
miSql = "ALTER TABLE TPedidos ADD CONSTRAINT miClaveExt FOREIGN KEY (NumMes)" _
& " REFERENCES TMeses(NumMes) ON UPDATE CASCADE"

CurrentProject.Connection.Execute miSql
MsgBox "La clave externa se ha creado correctamente", vbInformation, "OK"
End Sub

Fijaos que ahora la orden de ejecucin pasa por CurrentProject.Connection.Execute


Para borrar campos en cascada tendramos:

Private Sub cmdModifCreaClaveExterna_Click()


Dim miSql As String
miSql = "ALTER TABLE TPedidos ADD CONSTRAINT miClaveExt FOREIGN KEY (NumMes)" _
& " REFERENCES TMeses(NumMes) ON DELETE CASCADE"

CurrentProject.Connection.Execute miSql
MsgBox "La clave externa se ha creado correctamente", vbInformation, "OK"
End Sub

Y, lgicamente, si queremos ambas acciones a la vez la SQL sera:

miSql = "ALTER TABLE TPedidos ADD CONSTRAINT miClaveExt FOREIGN KEY (NumMes)" _
& " REFERENCES TMeses(NumMes) ON UPDATE CASCADE ON DELETE CASCADE"

Importante: ON UPDATE CASCADE y ON DELETE CASCADE slo pueden ser aplicadas a la


clave externa. En otro caso obtendremos error.

19

Vistame en http://siliconproject.com.ar/neckkito/

AADIR UNA REGLA DE VALIDACIN


Podemos modificar el campo de una tabla para validar las
entradas de los usuarios. Para ello utilizaramos la
estructura:
ALTER
TABLE
nomTabla
ADD
CONSTRAINT
nomCampo CHECK (<reglaDeValidacion>)
Supongamos que queremos crear una regla de validacin
sobre el campo [ImpVta] en nuestra tabla TVentas, de
manera que el usuario no pueda introducir ventas
negativas. Ergo nuestra condicin ser que el importe de la
venta sea mayor o igual a cero.
Cul es el pero? En realidad ya no hay pero para nosotros. La caracterstica de esta
modificacin de las propiedades del campo es que su ejecucin pasa obligatoriamente por la
combinacin de SQL con una conexin ADO, como ya hemos visto en el apartado anterior.
Nuestro cdigo pues quedara as:

Private Sub cmdCreaReglaValidacion_Click()


Dim miSql As String
miSql = "ALTER TABLE TVentas ADD CONSTRAINT ImpVta CHECK (ImpVta>=0)"
CurrentProject.Connection.Execute miSql
MsgBox "Regla de validacin creada correctamente", vbInformation, "OK"
End Sub

Nota: si, una vez ejecutada la SQL, abrimos TVentas en vista diseo y sacamos las
propiedades del campo [ImpVta] veremos que no hay ninguna regla de validacin especificada.
Eso no debe preocuparnos: si intentamos escribir un registro con una venta en negativo nos
saltar un aviso de que ese valor no cumple con la regla de validacin.

ELIMINAR NDICES
El proceso de eliminar ndices sera muy parecido a lo que ya conocemos con ADD, pero
utilizando, en su lugar, DROP.
Ergo la estructura que deberamos utilizar sera:
ALTER TABLE nomTabla DROP CONSTRAINT nomIndice
Para practicar un poco eliminaremos, de manera manual, la clave principal de la tabla TMeses.
Una vez eliminada la clave principal de esa tabla la volvemos a crear a travs de una SQL,
dndole nombre al ndice
Eso ya deberamos saber cmo hacerlo, pero para refrescar memorias os indico aqu cmo
sera la SQL

20

Vistame en http://siliconproject.com.ar/neckkito/


miSql = "ALTER TABLE TMeses ADD CONSTRAINT miSuperClavePpal PRIMARY KEY(NumMes)"

Como podemos ver, mi ndice se llama miSuperClavePpal,


y este ser el que eliminemos.
Ahora s, ya podemos escribir el cdigo, que sera:

Private Sub cmdModifBorraIndices_Click()


Dim miSql As String
'Esta SQL crea una clave principal en TMeses.NumMes
'
miSql = "ALTER TABLE TMeses ADD CONSTRAINT miSuperClavePpal PRIMARY
KEY(NumMes)"
'-------------------------------------------------miSql = "ALTER TABLE TMeses DROP CONSTRAINT miSuperClavePpal"
CurrentDb.Execute miSql
MsgBox "Clave principal eliminada correctamente", vbInformation, "OK"
End Sub

Si abrimos, tras su ejecucin, la tabla TMeses, veremos que nuestra clave principal ha
desaparecido.

PARA FINALIZAR EL CAPTULO (Y EL CURSO!)


Y, como dira aquel, hasta aqu hemos llegado. Hemos hecho un viaje cultural al pas de
SQL, y hemos visto consultas de seleccin, consultas de accin, consultas para crear tablas,
modificarlas, trabajar con propiedades, con ndices...
Siguiendo el smil, hemos visto los principales monumentos en nuestro viaje, pero conocer
SQL a fondo... eso slo lo conseguiremos si nos quedamos a vivir en la ciudad.
Afortunadamente tenemos otros recursos, como la ayuda de Access, la referencia del
programador de MSDN, los foros especializados... Es decir, que con un poco de cabezonera
podemos encontrar (y profundizar) mucha informacin sobre SQL. Vamos, que aburrirnos no
nos vamos a aburrir.
Tampoco debemos perder de vista que este curso est orientado a trabajar en Access lo cual
nos implica, entre otras, dos cosas:
La primera, que hay que tener presente que SQL es utilizado en otros SGBD 6, y operaciones
que funcionan en unos no funcionan en otros. No nos volvamos excesivamente locos
probando y probando algo que no nos funciona sin cercionarnos de que, efectivamente, eso s
funciona en nuestro SGBD.
Segunda, que nuestro entorno de trabajo es Access, y, ms en concreto, Access y VBA para
6

SGBD: Sistema Gestor de Bases de Datos

21

Vistame en http://siliconproject.com.ar/neckkito/

Access. Eso nos da la ventaja de que podemos trabajar con muchas herramientas que se
complementan o se sustituyen unas a otras. Para clarificar lo que quiero decir, recordemos que
tenemos las consultas como objeto en Access, fcilmente manipulables a nivel visual.
Si tenemos problemas con la programacin de alguna SQL
quiz podramos plantearnos el utilizar una consulta-objeto
de Access para realizar la misma funcin, por ejemplo.
Quisiera tambin remarcar que existe una estrecha
simbiosis entre SQL y ADO, en la cual no hemos
profundizado en este curso porque eso excedera de las
pretensiones del manual. Sin embargo, creo que es
interesante dejarlo apuntado para aquellos que quieran
profundizar sobre el tema, porque, dadas las caractersticas
de ADO, no hablamos de hacer un viaje a otra ciudad,
sino ms bien de realizar un viaje a otro continente
Espero que este manual os haya sido de utilidad. Para quejas y dems poneos en contacto con
mi editor (Anda, pero si no tengo editor! :P).
Un saludo, y...
suerte!

22

Vistame en http://siliconproject.com.ar/neckkito/

Das könnte Ihnen auch gefallen