Sei sulla pagina 1di 12

BASES DE DATOS EN VISUAL BASIC

ACCESS + SQL
by Damin Sottosanti
Ultima actualizacin: 03-08-2004

CREAMOS LA BASE DE DATOS EN ACCESS


Abrimos Access y elegimos "Crear una nueva base de datos usando" "Base de datos de Access en blanco"

Lo guardamos, por ejemplo, en "mis documentos", con el nombre "db1.mdb" Despus creamos una tabla en vista diseo

Ingresen los mismos datos q ven a continuacin, ya q estos son los datos (la tabla) q vamos a usar para programar.

Guarden la tabla con el nombre "Tabla1"

Ahora ingresamos los datos en la tabla:

Y ahora lo mas importante. Para no tener inconvenientes de compatibilidad vamos a hacer lo siguiente: "Herramientas -> Utilidades de las base de datos -> Convertir base de datos -> A una versin anterior de la base dee datos de Access..."

Guardamos con el nombre "base1.mdb" Esta base de datos llamada "base1.mdb" es la q vamos a usar en Visual Basic. No usaremos la otra (db1) por motivos de compatibilidad. En definitiva, ambas bases de datos son iguales, solo cambia la versin.

AHORA TRABAJAMOS EN VISUAL BASIC

Cuando creamos el proyecto lo primero q debemos hacer para trabajar con nuestra base de datos es la "referencia al motor de bases de datos de Microsoft". Para esto desde Visual Basic vamos al menu Proyecto -> Referencia y seleccionamos Microsoft DAO 3.51 Object Library (si tenes otra versin igual tiene q funcionar). Ahora para ver lo q estamos haciendo cuando ejecutamos, vamos a agregar una ListBox (llamada List1) en nuestro formulario. A partir de ahora es todo codigo. Creamos las variables en la parte General del formulario: Dim BDD as DataBase 'Objeto para manejar la base de datos Dim TBL as RecordSet 'Objeto para manejar la Tabla Es importante q tengan en cuenta lo q maneja cada objeto. Dijimos q el objeto BDD maneja la base de datos. Entonces podemos cargarla alli de la siguiente manera: Set BDD = OpenDatabase("c:\mis documentos\base1.mdb") 'Abre la base de datos Bueno, ahora q tenemos abierta la base de datos, vamos a realizar unas consultas utilizando ordenes SQL. Por lo tanto podriamos declarar una variable para almacenar nuestra sentencia SQL. Dim SQL As String

SENTENCIAS DE SELECCIN O CONSULTAS


Bien, SQL permite realizar consultas mediante sentencias de seleccin "SELECT". Lo q hace esta sentencia SELECT es tomar datos de una base de datos para devolverlos a quien se lo pidi (en nuestro caso quien se lo pide es el objeto TBL). SELECT consta de seis clusulas: las dos primeras obligatorias (SELECT y FROM) y las otras opcionales (WHERE, GROUP BY, HAVING, UNION, ORDER BY). SELECT y FROM FUNCIONES DE AGRUPAMIENTO WHERE GROUP BY HAVING UNION ORDER BY CONSULTAS A MAS DE UNA TABLA

SELECT y FROM
Veamos, con un ejemplo, como funciona:

SQL = "SELECT * FROM tabla1" Set TBL = BDD.OpenRecordset(SQL) 'TBL almacena todos los valores de la tabla Nuestra orden SQL es: seleccionar (SELECT) todos los campos (*) de (FROM) la tabla1. Ahora vamos a mostrar en la lista lo q almacenamos. TBL.MoveFirst 'nos posicionamos en el primer registro de la tabla Do Until TBL.EOF ''La propiedad EOF se pone TRUE cuando se a llegado al final de la tabla List1.AddItem TBL("nombre") TBL.MoveNext 'pasamos al siguiente registro Loop De esta manera, al ejecutar, nos debe aparecer en la lista todos los nombres de la tabla. Si queremos mostrar "nombre" "apellido": TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") TBL.MoveNext Loop Si queremos listar "nombre" "apellido" tiene "edad": TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") & " tiene " & TBL("edad") TBL.MoveNext Loop Qu sucede si solo quera tomar de la tabla1 los campos nombre y edad (no el apellido). En este caso la sentencia SQL quedara: SQL = "SELECT nombre,edad FROM tabla1" Por lo tanto el formato de la sentencia SELECT hasta ahora es: SELECT campo1,campo2,...,campoN FROM nombre_de_la_tabla NOTA: si ya terminamos de trabajar con la tabla y con la base de datos las podemos cerrar de la siguiente manera: TBL.Close 'cierra tabla BDD.Close 'cierra base de datos

FUNCIONES DE AGRUPAMIENTO
Las funciones de agrupamiento son: DISTINCT: Dijimos q si usabamos el * nos seleccionaba todos los campos. Tambin hay un operador llamado DISTINCT, ste elimina las filas o registros duplicados del resultado de la consulta. Esto se ve bien en el siguiente ejemplo:

SQL = "SELECT DISTINCT edad FROM tabla1" 'almacena todas las edades sin repetirlas Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("edad") TBL.MoveNext Loop COUNT: Este operador nos devuelve la cantidad de valores en una columna. Por ejemplo, COUNT(nombre) devolver el nmero de registros con valores no nulos en el campo nombre. Pero si usamos COUNT(*), nos devuelve el nmero de registros incluyendo aquellos registros con valores nulos. SQL = "SELECT COUNT(*) FROM tabla1" 'para saber la cantidad de registros (incluye los nulos) Set TBL = BDD.OpenRecordset(SQL) List1.AddItem TBL("expr1000") 'expr1000 es el name del item de TBL q almacena el resultado del operador de agrupamiento SUM: Devuelve la suma total de los valores de una expresin de columna o campo NUMERICA (si no es numerica les da error!) . Por ejemplo, SUM(edad) devolver la sumatoria de las edades. SQL = "SELECT SUM(edad) FROM tabla1" 'sumatoria de las edades Set TBL = BDD.OpenRecordset(SQL) List1.AddItem TBL("expr1000") AVG: Devuelve el promedio de los valores de una expresin de columna. Por ejemplo, AVG(edad) devolver el promedio de las edades. Esto seria dividir SUM(edad)/COUNT(edad). SQL = "SELECT AVG(edad) FROM tabla1" MAX: Devuelve el valor ms alto de los contenidos en una expresin de columna. Si hacemos: SQL = "SELECT MAX(edad) FROM tabla1" Nos dir la edad mas alta. MIN: Si hay un MAX, por q no puede haber un MIN? ya se habran dado cuenta lo q hace. Entonces, si SQL = "SELECT MIN(edad) FROM tabla1" Nos dir la edad mas baja. EJEMPLO: quiero saber cuntos registro tengo, cual es la menor edad y cual es el promedio de todas las edades Dim BDD As Database Dim TBL As Recordset Dim SQL As String Set BDD = OpenDatabase("c:\mis documentos\base1.mdb") SQL = "SELECT COUNT(*), MIN(edad), AVG(edad) FROM tabla1" Set TBL = BDD.OpenRecordset(SQL) List1.AddItem "total de reg: " & TBL("expr1000") List1.AddItem "MINIMA EDAD: " & TBL("expr1001") List1.AddItem "PROMEDIO EDADES: " & TBL("expr1002") TBL.Close BDD.Close

WHERE
Con WHERE indicamos condiciones para la seleccin de ciertos registros. Veamos un ejemplo: Antes q nada nuestra sentencia SELECT quedara asi: SELECT campo1,campo2,...,campoN FROM nombre_de_la_tabla WHERE condicion1 AND condicion2 AND ... AND condicionN Dim BDD As Database Dim TBL As Recordset Dim SQL As String Set BDD = OpenDatabase("c:\mis documentos\base1.mdb") SQL = "SELECT * FROM tabla1 WHERE edad < 30" Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("edad") TBL.MoveNext Loop TBL.Close BDD.Close Con esta instruccin decimos q: seleccione (SELECT) todos los campos (*) de (FROM) tabla1 q cumplan la condicin (WHERE) edad < 30

GROUP BY
Esta clusula se utiliza para agrupar segun lo q especifiquemos. Por ejemplo, podemos listar todos los datos de nuestra tabla1, pero agrupados por edad. SQL = "SELECT edad, nombre, apellido FROM tabla1 GROUP BY edad,nombre, apellido" Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") & " tiene " & TBL("edad") TBL.MoveNext Loop Entonces el formato es: GROUP BY expresion1, expresin2, ..., expresinN. IMPORTANTE: Todas las expresiones deben coincidir con lo q pusimos en SELECT. Por lo tanto lo siguiente no funciona: SQL = "SELECT * FROM tabla1 GROUP BY edad,nombre, apellido" 'no se puede agrupar mediante los campos seleccionados con *

SQL = "SELECT edad FROM tabla1 GROUP BY apellido" SQL = "SELECT nombre, apellido, edad FROM tabla1 GROUP BY edad"

HAVING
Asi como la clusula WHERE especifica condiciones para la seleccin de registros, HAVING especifica condiciones para el agrupamiento (GROUP BY). Por lo tanto HAVING funciona solo si se especifica un GROUP BY. SQL = "SELECT edad, nombre, apellido FROM tabla1 GROUP BY edad,nombre, apellido HAVING edad<30" Con este ejemplo agrupamos segn la edad, pero solo los q su campo edad es menos a 30.

UNION
Con este operador lo q hacemos es juntar dos resultados de dos sentencias SELECT diferentes. El resultado de la union son todos los registros devueltos en ambas sentencias, y los registros repetidos se omiten a no ser q utilicemos la palabra ALL. La forma es: SELECT sentencia1 UNION ALL SELECT sentencia2 con sentencia2 veamos q sucede si hacemos lo siguiente SQL = "SELECT * FROM tabla1 UNION SELECT * FROM tabla1" Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") & " tiene " & TBL("edad") TBL.MoveNext Loop En este caso unimos la tabla1 con la misma tabla1, por lo tanto todos los resultados son repetidos y se omiten. Veamos q pasa con ALL SQL = "SELECT * FROM tabla1 UNION ALL SELECT * FROM tabla1" Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") & " tiene " & TBL("edad") TBL.MoveNext Loop 'sentencia1 debe coincidir

Otra vez todos los datos se repiten pero en este caso le decimos q no omita ninguno, por lo tanto cada valor de la tabla1 estar repetido dos veces. Hacer esto no tiene sentido, es decir q la union debera ser con la seleccin de dos tablas diferentes.

ORDER BY
Para ordenar los resultados utilizamos ORDER BY. Cuando omitimos esta clusula, los resultados se ordenan por el primer campo que sea clave en el ndice que se haya utilizado. Veamos las siguientes sentencias: SQL = "SELECT * FROM tabla1 ORDER BY edad ASC" ' ordenado por edad en forma ascendente SQL = "SELECT * FROM tabla1 ORDER BY edad" ' ordenado por edad, por defecto lo ordena en forma ascendente SQL = "SELECT * FROM tabla1 ORDER BY edad DESC" ' ordenado por edad en forma descendente SQL = "SELECT * FROM tabla1 ORDER BY 1" 'ordenado por el primer campo de la tabla SQL = "SELECT nombre, apellido, edad FROM tabla1 ORDER BY 3,2,1" 'ordenado por edad, apellido y nombre Entonces podemos indicar el nombre_de_campo, nmero_de_campo y si es ASCendente o DESCendente.

CONSULTAS A MAS DE UNA TABLA


Supongamos q tenemos una base de datos con dos tablas llamadas tabla1 y tabla2. Tabla1 tiene como campos nombre, apellido y edad. Mientras q la tabla2 tiene nombre y email. Bien, por ejemplo yo podria querer los emails de las personas q estan en ambas tablas, esto es q el nombre de la tabla1 tiene q ser igual al nombre de la tabla2. Veamos como lo indicamos... SQL = "SELECT tabla1.nombre,email FROM tabla1,tabla2 WHERE tabla1.nombre=tabla2.nombre" Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("email") TBL.MoveNext Loop

Nuestra sentencia SQL quedo as: 1- Indicamos los campos a seleccionar (SELECT). Observar q el campo nombre aparece en las dos tablas, por lo tanto debemos indicar de q tabla los voy a seleccionar (tabla1.nombre). Por el contrario el campo email solo aparece en la tabla2, por lo tanto no hace falta indicarle de q tabla lo queremos ya q es obvio de cual va a ser. 2- Despues indicamos cuales tablas van a ser consultadas (FROM). Le indicamos q tabla1, tabla2. El orden es importante porq de cada registro de la primer tabla se efectua una busqueda en la segunda. 3- por ultimo indicamos la condicin (WHERE). Decimos q el campo nombre de la tabla1 debe ser igual al de la tabla2. Ahora vamos a ver el mismo ejemplo pero usando ALIAS. Un alias es un nombre temporal q le asignamos a una tabla. Por ejemplo a la tabla1 la podemos llamar t1 y a la tabla2 t2. De esta manera es mas facil escribir t1 q tabla1. SQL = "SELECT t1.nombre,email FROM tabla1 t1,tabla2 t2 WHERE t1.nombre=t2.nombre" En el FROM escribimos nombre_tabla alias_tabla. En el resto de la sentencia usamos el alias en vez de el nombre. Ahora, supongamos q tenemos una tercer tabla q contiene nombre y telefono como campos. Queremos consultar los campos nombre, email y telefonos. SQL = "SELECT t1.nombre,email,telefono FROM tabla1 t1,tabla2 t2, tabla3 t3 WHERE t1.nombre = t2.nombre AND t1.nombre = t3.nombre" Lo importante de estas consultas es el orden en q se escriben las tablas luego del FROM, ya q esto va a influir en la velocidad de la consulta. Para terminar la seccin de consultas vamos a ver las SELECT ANIDADAS. Esto es una SELECT dentro de otra. Es muy simple. Veamos un ejemplo. SQL = "SELECT t1.nombre,email,telefono FROM tabla1 t1,tabla2 t2, tabla3 t3 WHERE t1.nombre = t2.nombre AND t1.nombre = t3.nombre AND (SELECT COUNT(*) FROM tabla1)< 100" Es la misma condicin anterior solo q se agrego una condicin mas: (SELECT COUNT(*) FROM tabla1)< 100, esto es, q la tabla1 tenga menos de 100 registros. Entonces cuando insertamos una nueva SELECT dentro de otra, debemos ponerla entre parentesis

ORDENES PARA MODIFICAR DATOS


UPDATE INSERT INTO DELETE

UPDATE
Podemos cambiar los datos q queramos en la tabla q queramos mediante la orden UPDATE. Por ejemplo, en la tabla1, donde teniamos nombre, apellido y edad. Supongamos q queremos q todas las edades se pongan a 0 (cero). Private Sub Form_Load() Dim BDD As Database Dim TBL As Recordset

Dim SQL As String Set BDD = OpenDatabase("c:\mis documentos\base1.mdb") SQL = "UPDATE tabla1 SET edad = 0" BDD.Execute SQL SQL = "SELECT * FROM tabla1" Set TBL = BDD.OpenRecordset(SQL) TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") & " tiene " & TBL("edad") TBL.MoveNext Loop TBL.Close BDD.Close End Sub En este caso cambiamos la manera de trabajar, o mejor dicho, para la orden UPDATE trabajamos directamente sobre el objeto Database q almacena la base de datos donde queremos realizar el cambio. Para ejecutar una sentencia SQL podemos poner nombre_variable_database.Execute "sentencia_SQL" Veamos nuestra sentencia: actualizar (UPDATE) de la tabla1 las edades, ponerlas a cero (SET edad=0). Tambien podemos utilizar la orden WHERE para especificar algo mas preciso. Por ejemplo poner a cero las edades q sean mayores q 21. SQL = "UPDATE tabla1 SET edad = 0 WHERE edad>21"

INSERT INTO
Tambien podemos insertar nuevos registros. Para ello utilizamos la orden INSERT INTO. Veamos un ejemplo. En la tabla1 tengo los campos nombre, apellido y edad. Bien, ahora quiero agregar un nuevo nombre, apellido y edad. SQL = "INSERT INTO tabla1 (nombre,apellido,edad) VALUES('damian','sotto',22)" BDD.Execute SQL Bien, primero decimos insertar en la tabla1 (INSERT INTO tabla1) nuevos valores para los campos (nombre, apellido,edad) los valores son para el primer campo damian, para el segundo sotto y para el tercero 22. En VALUES se escriben los valores de los campos en el mismo orden en q se especificaron. Los caracteres van entre ' ' y las fechas entre {}. Si no especificamos valores entonces el campo queda vacio. Pero si o si debe haber un valor para poder crear un nuevo registro. Bueno, ya sabemos como actualizar datos y como agregar datos. Ahora nos falta como eliminar datos.

DELETE
Esta sentencia se utiliza para borrar los registros de una tabla. La sentencia es DELETE FROM nombre_tabla WHERE condiciones. SQL = "DELETE FROM tabla1 WHERE edad<21" BDD.Execute SQL Con esta sentencia borro todos los registros cuya edad sea menor a 21. Si no especifico un WHERE, se borran todos los registros, o sea, la tabla me queda vacia. SQL = "DELETE FROM tabla1" BDD.Execute SQL Ahora, si la tabla esta vacia, cuando hagamos una busqueda dentro de ella el programa va a dar error. Una solucin sera: SQL = "SELECT * FROM tabla1" Set TBL = BDD.OpenRecordset(SQL) If TBL.EOF Then ''EOF esta en verdaero si no hay datos MsgBox "No hay datos que coincidan con la bsqueda especificada" Exit Sub End If 'si llega hasta aca es porq hay datos TBL.MoveFirst Do Until TBL.EOF List1.AddItem TBL("nombre") & " " & TBL("apellido") & " tiene " & TBL("edad") TBL.MoveNext Loop TBL.Close BDD.Close