bases de datos en visual basic

Anuncio
BASES DE DATOS EN VISUAL
BASIC
ACCESS + SQL
by Damián Sottosanti
Ultima actualización: 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"
Después creamos una tabla en vista diseño
Ingresen los mismos datos q ven a continuación, ya q estos son los datos (la tabla) q vamos a
usar para programar.
Guarden la tabla con el nombre "Tabla1"
Ahora ingresamos 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 versión
anterior de la base de 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 versión.
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 versión 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
Ya estamos listos para aplicar SQL...
SENTENCIAS DE SELECCIÓN O CONSULTAS
ACTUALIZAR LOS DATOS
SENTENCIAS DE SELECCIÓN O CONSULTAS
Bien, SQL permite realizar consultas mediante sentencias de selección "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 cláusulas: 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 quería tomar de la tabla1 los campos nombre y edad (no el apellido). En
este caso la sentencia SQL quedaría:
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. También 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 número de registros con valores no nulos en el campo nombre.
Pero si usamos COUNT(*), nos devuelve el número 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 expresión 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 expresión 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 más alto de los contenidos en una expresión 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 cuántos 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 selección de ciertos registros. Veamos un ejemplo:
Antes q nada nuestra sentencia SELECT quedaría 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 instrucción decimos q: seleccione (SELECT) todos los campos (*) de (FROM) tabla1 q
cumplan la condición (WHERE) edad < 30
GROUP BY
Esta cláusula 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, expresión2, ..., expresiónN.
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 cláusula WHERE especifica condiciones para la selección 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 según 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
'sentencia1 debe coincidir
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
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 debería ser con la selección de dos tablas
diferentes.
ORDER BY
Para ordenar los resultados utilizamos ORDER BY. Cuando omitimos esta cláusula, 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, número_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 condición (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 sección 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 condición anterior solo q se agrego una condición 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 solución sería:
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 búsqueda 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
Descargar