Вы находитесь на странице: 1из 10

CURSO DE SQL

CAPTULO 41

ndice de contenido
LAS CONSULTAS DE ACCIN........................................................................................................2
TRES Y... ACCIN!......................................................................................................................2
CONSULTA DE DATOS ANEXADOS..........................................................................................3
ANEXAR EN UNA TABLA EXISTENTE (un nico registro).................................................3
ANEXAR EN UNA TABLA EXISTENTE (todos los registros / conjunto de registros)...........4
ANEXAR HACIA UNA BD EXTERNA...................................................................................5
ANEXAR DESDE UNA BD EXTERNA..................................................................................6
CONSULTA DE ACTUALIZACIN.............................................................................................6
CONSULTA DE ELIMINACIN...................................................................................................7
CONSULTA PARA BSQUEDA DE REGISTROS DUPLICADOS............................................8
CONSULTAS PARAMETRIZADAS..................................................................................................9
PROCEDURES..................................................................................................................................10
PARA FINALIZAR ESTE CAPTULO.............................................................................................10

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

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

LAS CONSULTAS DE ACCIN


TRES Y... ACCIN!
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.
Sin embargo, hay ms cosas que seleccionar datos,
verdad?
En este cuarto captulo vamos a ver cmo ejecutar lo que se denominan consultas de accin.
Veamos un par de cosas comunes que aplicaremos a lo largo de todo este documento.
Las consultas de accin operan sobre los datos; es decir, los cambian, los actualizan, los
eliminan, los crean (en una nueva tabla, por ejemplo). Y, por ese motivo, son peligrosas.
Un error en alguna de nuestras consultas y nuestros datos... pluf.
Por este motivo nuestro amigo Access nos advierte y vuelve a advertir antes de ejecutar una
consulta de estas caractersticas. Es decir, que si yo intento ejecutar, por ejemplo, una consulta
para borrar registros (de lo ms cool en cuanto a peligrosidad ) me encontrar con lo
siguiente:

Estas advertencias estn muy bien cuando no sabemos bien lo que hacemos, pero, y cundo
lo tenemos ms que claro? Pues dichos warnings se convierten en algo de lo ms incmodo
(pueden llegar a salirnos tres warnings seguidos, a veces). Click, y click, y click para conseguir
ejecutar la consulta...
Lo anterior podemos evitarlo en nuestro cdigo VB para Access aadiendo dos lneas de
cdigo: una antes de la ejecucin de la consulta y otra a continuacin de la ejecucin de la
consulta. Lo escribiramos de la siguiente manera:

DoCmd.SetWarnings False
'Ejecucin de la consulta
DoCmd.SetWarnings True

Con estas dos lneas se acabaron los avisos de Access... aunque si nos hemos equivocado...
Houston, tenemos un problema.
Importante: es vital que volvamos a activar la aparicin de warnings a travs del
<DoCmd.SetWarnings True>. Ello es as porque la inhabilitacin de los avisos (a travs del
2

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

<DoCmd.SetWarnings False>) no se limita a deshabilitar los avisos para ese procedimiento en


concreto que estemos programando, sino que los deshabilita en general. Y ello implica que si
se produce algn error en cualquier parte Access no nos avisar, con lo que nuestro cdigo no
funcionar, o no
funcionar bien, y no sabremos por qu. Tened cuidado con
olvidarse de
volver a habilitar los avisos.
Nosotros, en los cdigos que veamos de ejemplo,
utilizaremos la desactivacin/activacin de los warnings.
Pero si queris hacer la prueba de ejecutar algunas
consultas de accin sin el SetWarnings os invito a ello,
simplemente para que podis ver qu mensajes de
advertencia nos lanza Access.
Ms cosas... Las consultas de accin se ejecutan directamente a travs del cdigo. Por ello
veris que ya no nos har falta recurrir al cdigo de mdlProcesos que utilizbamos hasta
ahora. Es decir, no nos ser necesario crearnos la consulta para poder ver los resultados.
La ejecucin de una consulta SQL, utilizando nuestro cdigo VB, se ejecutar a travs de
DoCmd.RunSQL <nombreSQL>

Nota: tened en cuenta que tambin podramos utilizar:


CurrentDb.Execute <nombreSQL>
En general (ojo, en general, aunque hay excepciones) no debera darnos problemas utilizar
una sintaxis u otra al operar con consultas de seleccin o de accin.
Como siempre (pero por si acaso lo repito), los ejemplos de este captulo se basarn en la
tabla que creamos en el captulo 1.
Y, ahora s, vamos a echar una ojeada a las consultas de accin en SQL.

CONSULTA DE DATOS ANEXADOS

ANEXAR EN UNA TABLA EXISTENTE (un nico registro)


La instruccin SQL que nos permite realizar este tipo de consultas es INSERT INTO... VALUES
Su estructura sera la siguiente:
INSERT INTO nomTabla(nomCampo1, , nomCampoN) VALUES (valor1, , valorN)
Para desarrollar el ejemplo vamos a hacer un copiar-pegar manual de la tabla TClientes (pero
slo la estructura, no los datos). Para ello copiamos dicha tabla y antes de pegarla con el
nombre de TClientes2 seleccionamos la opcin de pegado Estructura solamente.
Supongamos que queremos insertar un nuevo cliente cuyos datos son:

Nombre (NomCli): Sopas La Morsa

NIF (NIFCli): B251234546

Poblacin (PoblCli): Almera


Nuestro cdigo debera quedar, en consecuencia, escrito de la siguiente manera:

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


Private Sub cmdDatosAnexados1_Click()
Dim miSql As String
miSql = "INSERT INTO TClientes2(NomCli,NIFCli,PoblCli)" _
& " VALUES ('Sopas La Morsa','B25123456','Almera')"

DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexin
vbInformation, "OK"
End Sub

realizada

correctamente",

Incluyo el MsgBox al final porque si no es frustrante no saber si las cosas han ido bien o no, o
dudar de si se ha realizado el proceso o no.
Fcil, verdad?

ANEXAR EN UNA TABLA EXISTENTE (todos los registros / conjunto de


registros)
Como probablemente nos ha ido bien con un solo registro vamos a pelearnos con un
grupito de registros. Lo que haremos ser seleccionar todos los registros de una tabla
TClientes a nuestra nueva tabla TClientes2.
Le estructura difiere ligeramente de la anterior, siendo, en general, la siguiente:
INSERT INTO <TablaDestino>
SELECT * FROM <TablaOrigen>
Nuestro cdigo nos debera quedar:

Private Sub cmdDatosAnexadosTodos_Click()


Dim miSql As String
miSql = "INSERT INTO TClientes2 SELECT * FROM TClientes"
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexin realizada correctamente", vbInformation, "OK"
End Sub

Si lo que queremos no son todos los registros sino un conjunto de registros simplemente
deberamos aadir un WHERE a nuestra SQL.
Para que quede ms claro, por si acaso, por ejemplo anexaremos a esta tabla los registros de
los clientes cuyo CIF empiece por A.
El cdigo sera:
4

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


Private Sub cmdDatosAnexadosAlgunos_Click()
Dim miSql As String
miSql = "INSERT INTO TClientes2 SELECT * FROM TClientes" _
& " WHERE TClientes.NIFCli LIKE 'A*'"

DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexin realizada correctamente", vbInformation,
"OK"
End Sub

ANEXAR HACIA UNA BD EXTERNA


Para realizar este ejemplo vamos a crearnos una nueva BD en el mismo directorio donde
tenemos nuestra BD de ejemplo, y la guardaremos como TablaExterna.mdb (o .accdb).
Crearemos una tabla, que llamaremos TClientesExt, con la siguiente estructura:

Como podemos intuir, vamos a anexar en esta tabla los datos de nuestra tabla TClientes (slo
los campos con el nombre y el NIF).
La estructura de este tipo de exportacin sera la siguiente:
INSERT INTO <tablaDestino> IN '<rutaBDExterna>'
SELECT nomTabla.nomCampo1,...,nomTabla.nomCampoN FROM nomTabla
Es decir, que nuestro cdigo en la BD de ejemplo debera ser el siguiente:

Private Sub cmdDatosAnexadosHaciaBDExterrna_Click()


Dim rutaBDExt As String, miSql As String
rutaBDExt = Application.CurrentProject.Path & "\TablaExterna.mdb"
miSql = "INSERT INTO TClientesExt IN '" & rutaBDExt & "'" _
& " SELECT TClientes.NomCli, TClientes.NIFCli FROM TClientes"
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexin realizada correctamente", vbInformation, "OK"
End Sub

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

Tened en cuenta que los nombres de campos deben ser idnticos. Si no lo fueran el cdigo
nos dira que no se
que se explica a

encuentra el campo XXX. Esto es vlido tambin para el apartado


continuacin.

ANEXAR DESDE UNA BD EXTERNA


Podemos realizar la misma operacin, pero al revs. Es
decir, introducir valores de una tabla externa en una tabla
de nuestra BD.
La estructura de la SQL sera la siguiente:
INSERT INTO <nomTabla>
SELECT * FROM <nomTablaExt> IN '<rutaBDExterna>'
Es decir, que nuestro cdigo nos debera quedar as, si queremos anexar los registros de
TClientesExt en TClientes2:

Private Sub cmdDatosAnexadosDesdeBDExterna_Click()


Dim rutaBDExt As String, miSql As String
rutaBDExt = Application.CurrentProject.Path & "\TablaExterna.mdb"
miSql = "INSERT INTO TClientes2" _
& " SELECT * FROM TClientesExt IN '" & rutaBDExt & "'"
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Anexin realizada correctamente", vbInformation, "OK"
End Sub

CONSULTA DE ACTUALIZACIN
Para realizar las consultas de actualizacin utilizaremos la instruccin UPDATE. La estructura de
una consulta de actualizacin es:
UPDATE nomTabla
SET nomCampo1 = <nuevoValor>,..., nomCampoN = <nuevoValor>
Es muy usual utilizar WHERE con este tipo de consultas para indicar qu registros son los que
deben ser utilizados. La clusula WHERE se sita al final. Es decir:
UPDATE nomTabla
SET nomCampo1 = <nuevoValor>,..., nomCampoN = <nuevoValor>
WHERE <condicin>

Es importante acordarse del WHERE, porque si no la consulta de actualizacin afectar a


TODOS

los

registros,

la

accin

NO

se

podr

deshacer.

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

Recordamos

nuestros

DoCmd.SetWarnings? Hay que utilizarlos con mucho cuidado!


Supongamos que queremos cambiar las poblaciones porque
nos hemos equivocado. Donde pusimos Valencia debera
ser Castelln. Nuestra consulta sera:

Private Sub cmdActualizaTClientes_Click()


Dim miSql As String
miSql = "UPDATE TClientes SET PoblCli = 'Castelln'" _
& " WHERE PoblCli='Valencia'"

DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Actualizacin realizada correctamente", vbInformation, "OK"
End Sub

Recordad que tambin podemos realizar clculos para actualizar datos. Por ejemplo, el da que
metimos los datos en nuestra BD no estbamos muy inspirados y al dar de alta las ventas no
nos dimos cuenta que las metamos impuestos incluidos. Lgicamente haba que almacenar
los datos con impuestos excluidos.
Si, por ejemplo, habamos aplicado una tasa del 18%, nuestra consulta de actualizacin
debera ser:

Private Sub cmdActualizaTVentas_Click()


Dim miSql As String
miSql = "UPDATE TVentas SET ImpVta = ImpVta/1.18"
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Actualizacin realizada correctamente", vbInformation, "OK"
End Sub

Efectivamente, en este caso necesitaba que se actualizaran todos los registros, por lo que he
omitido el uso de WHERE

CONSULTA DE ELIMINACIN
Las instruccin que nos define una consulta de eliminacin es DELETE.
El uso de DELETE, personalmente, me recuerda a la figura de asesino a sueldo: realiza el
trabajo de limpieza de una manera rpida, eficaz y sin dejar huellas
Su estructura es:
DELETE FROM nomTabla
7

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

Y, si queremos ser un poco selectivos (es decir, no realizar una matanza masiva), utilizamos
WHERE
DELETE FROM nomTabla WHERE <condicin>
Al igual que lo que comentbamos en las consultas de
actualizacin, una vez ejecutada la instruccin DELETE no
hay vuelta atrs, as que debemos proceder con mucho
cuidado.
En nuestra BD de ejemplo debemos tener por ah una tabla llamada TClientes2. Vamos a
eliminar todos los clientes que tengan, en su nombre, alguna relacin con la carne.
Nuestra SQL sera la siguiente:

Private Sub cmdEliminaDeTClientes2_Click()


Dim miSql As String
miSql = "DELETE FROM TClientes2 WHERE nomCli LIKE 'Carn*'" _
& " OR nomCli LIKE 'Crn*'"
DoCmd.SetWarnings False
DoCmd.RunSQL miSql
DoCmd.SetWarnings True
MsgBox "Eliminacin realizada correctamente", vbInformation, "OK"
End Sub

CONSULTA PARA BSQUEDA DE REGISTROS DUPLICADOS


Esta consulta resulta un poco enrevesada, y mi recomendacin, ya que tenemos Access, es
crear este tipo de consulta utilizando el asistente, bsicamente por comodidad (despus
podemos situar la consulta en vista SQL y reciclar el cdigo ).
Dicho lo anterior vamos a ver cmo podemos confeccionar dicha SQL, pero antes, en nuestra
tabla TClientes2, vamos crear un nuevo registro con el nombre duplicado de un cliente, pero
con distinto NIF.
La estructura de la SQL sera:
SELECT nomTabla.nomCampo1,..., nomTabla.nomCampoN FROM nomTabla
WHERE <nomTabla.campoABuscar> IN
(SELECT <campoABuscar> FROM nomTabla AS <alias>
GROUP BY <campoABuscar> HAVING Count(*)>1)
ORDER BY <nomTabla.campoABuscar>
El cdigo que nos hara lo anterior es:

Private Sub cmdDuplicados_Click()


Dim miSql As String, nomQuery As String
nomQuery = "CDuplicados"
8

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

Call eliminaConsulta(nomQuery)

miSql
&"
&"
&"

= "SELECT TClientes2.NomCli, TClientes2.NIFCli FROM TClientes2" _


WHERE TClientes2.NomCli IN (SELECT NomCli FROM TClientes2 AS SubCons" _
GROUP BY NomCli HAVING Count(*)>1)" _
ORDER BY TClientes2.NomCli"

Call creaConsulta(nomQuery, miSql)


DoCmd.OpenQuery nomQuery
End Sub

CONSULTAS PARAMETRIZADAS
Podemos construir consultas en las cuales se solicite informacin al usuario para, a
continuacin, mostrar los datos deseados. Esta solicitud de informacin se realiza a travs de
lo que denominamos parmetros.
Y para ello utilizamos la declaracin PARAMETERS, que tiene la siguiente estructura:
PARAMETERS nomParametro1 <tipoDato>, , nomParametroN <tipoDato>;
<ESTRUCTURA DE LA CONSULTA QUE QUERAMOS EJECUTAR>
Supongamos que queremos saber las ventas que se han producido en nuestra empresa, pero a
veces necesitamos los datos con anterioridad a una fecha y dependiendo de un determinado
volumen de ventas.
Nuestros parmetros, en este caso, seran la fecha y el importe. Ms all la consulta sera una
simple consulta de seleccin.
Ergo nuestro cdigo podra ser el siguiente:

Private Sub cmdCParametrizada_Click()


Dim miSql As String, nomSql As String
nomSql = "FiltroVentas"
Call eliminaConsulta(nomSql)
miSql = "PARAMETERS FechaMax Date, ImportMin Currency;" _
& " SELECT * FROM TVentas WHERE TVentas.FechVta<=FechaMax" _
& " AND TVentas.ImpVta>=ImportMin"
Call creaConsulta(nomSql, miSql)
DoCmd.OpenQuery nomSql
End Sub

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

Fijaos que separamos los parmetros de la consulta utilizando punto y coma (;). Ojo: no hay
que olvidarse de ese punto y coma porque si no obtendremos error en los parmetros de la
SQL.

PROCEDURES
La clusula PROCEDURE, segn Access, <<define un
nombre y parmetros opcionales para una consulta>>.
Como siempre, la ayuda de Access a veces se pasa con la
explicacin . A eso debemos aadir que esta clusula ha
quedado obsoleta, debindose utilizar (siempre segn
Access) la instruccin PROCEDURE.
No la voy a explicar porque, sinceramente, no tengo mucha idea de cmo hacerlo. En primer
lugar porque no la he utilizado nunca; en segundo lugar porque soy incapaz de encontrar un
ejemplo prctico para aplicar a nuestra BD de ejemplo, dado que al combinarla con VB esta
instruccin pierde un poco el sentido (siempre desde mi punto de vista).
Si adems os digo que en todos los manuales o tutoriales de SQL que he visto, al hablar de
PROCEDURE, se dice que no es comn, es muy poco comn, es muy poco utilizada, y
comentarios similares... pues creo que tampoco nos perdemos gran cosa.
En la ayuda de Access hay un ejemplo de cmo programar una SQL utilizando la
clusula/instruccin PROCEDURE. Si alguien quiere echarle un vistazo invitado est a ello.
En definitiva, que as sabris que existe esto que llaman PROCEDURE, y por eso lo dejo,
como mnimo, apuntado.

PARA FINALIZAR ESTE CAPTULO


Este captulo cierra un primer ciclo con SQL, dado que hasta el momento (es decir, desde el
captulo 1) hemos estado operando con los datos de las tablas y creando estructuras de
consultas (como consulta-objeto de Access, quiero decir).
Desde mi punto de vista lo que hemos aprendido hasta el momento nos amplia nuestras
posibilidades de operar con Access, dado que SQL, combinado con VBA, nos permite realizar
acciones que con slo las herramientas de Access quiz se hiciera complicado resolver, o quiz
nos sometiera a la utilizacin de procedimientos que, sin ser malos, pueden ser optimizados.
En el prximo captulo comenzaremos un nuevo ciclo: ya no operaremos con datos, sino que
trabajaremos con el alma mter de Access: las tablas y su estructura.
Espero que lo aprendido hasta ahora os haya podido ser til.
Suerte!

10

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

Вам также может понравиться