Simulando DLookup fuera de Access (I).
Para todos aquellos que empezamos en bases de datos con Access y que programamos aplicaciones con VBA, las funciones DCount, DMax y similares nos resultan de lo más útiles para obtener valores puntuales de una base de datos sin tener que recuperar explícitamente un recordset. La más útil de todas probablemente sea DLookup. La sintaxis resumida de DLookup es la siguiente (para una más detallada explicación se puede consultar la propia ayuda de Access):
Y nos devuelve el valor del campo correspondiente de la tabla indicada, en el primer registro que cumpla la condición opcionalmente pasada como parámetro.
Pues bien, como ya he comentado en posts anteriores, la base de datos con la que actualmente estoy trabajando es MySQL, y por desgracia esta función tan útil no existe de manera predeterminada en MySQL. No obstante, ello no quiere decir que no podamos utilizar algo similar, sí que podemos, aunque vamos a tener que programar un poco antes. He aquí el código:
# Author: Albert Mata (www.albertmata.net)
# Date: 20080527
# Description: MySQL procedure and function to simulate Microsoft
# Access function DLookup.
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# Creates an auxiliar table to store the value.
#--------------------------------------------------------------------
DROP PROCEDURE IF EXISTS PreDLookupAux;
DELIMITER //
CREATE PROCEDURE PreDLookup(campo VARCHAR(7),
tabla VARCHAR(14),
condicion VARCHAR(250))
BEGIN
DROP TABLE IF EXISTS tbl_dlookupaux;
CREATE TABLE tbl_dlookupaux (tbl_res VARCHAR(250));
SET @query = CONCAT('INSERT INTO tbl_dlookupaux SELECT ',
campo, ' FROM ', tabla, ' WHERE ',
IF(ISNULL(condicion),'TRUE',condicion),
' LIMIT 1');
PREPARE running FROM @query;
EXECUTE running;
DEALLOCATE PREPARE running;
END
//
DELIMITER ;
#--------------------------------------------------------------------
# Gets the value from auxiliar table created before.
#--------------------------------------------------------------------
DROP FUNCTION IF EXISTS DLookup;
DELIMITER //
CREATE FUNCTION DLookup() RETURNS VARCHAR(250)
BEGIN
DECLARE aux VARCHAR(250);
SET aux := (SELECT tbl_res FROM tbl_dlookupaux);
RETURN aux;
END
//
DELIMITER ;
Hay unas cuantas cosas que explicar:
1) Hasta la versión 5.0.45 de MySQL (la última GA cuando escribo esto y por tanto la de uso recomendado) las stored functions no permiten hacer ciertas cosas que harían mucho más fácil crear el DLookup en un solo paso, por eso se tiene que crear en un doble paso.
2) En el primer paso creamos una tabla auxiliar con un único campo y le insertamos un único registro con el valor que sale de la combinación campo-tabla-condicion que le hemos pasado. En el segundo paso nos devuelve ese valor que hemos almacenado temporalmente en la tabla auxiliar.
3) He puesto una longitud de 7 caracteres para el nombre del campo y de 14 para el de la tabla porque son las longitudes que tienen siempre mis nombres de campos y tablas, no obstante se puede modificar al gusto.
4) En cambio en tipo de campo de salida he puesto VARCHAR(250) por intentar ser algo genérico. Con esta definición nos devolverá sin problemas fechas y números, pero hay que tener en cuenta esta definición por si se utiliza DLookup con tipos de datos que no tengan cabida en un genérico VARCHAR(250).
5) Si no se desea pasar ningúna condición se puede establecer a cadena vacía ('') o bien a NULL, pero una stored function de MySQL no permite poner argumentos como de introducción opcional.
Veámoslo en funcionamiento. Tengo una tabla cty_nicecities con esta estructura:
| cty_id | cty_nam | cty_cou |
+--------+-----------+---------+
| 1 | Paris | France |
| 2 | Rome | Italy |
| 3 | Frankfurt | Germany |
| 4 | Dortmund | Germany |
| 5 | Milan | Italy |
+--------+-----------+---------+
Y puedo utilizar mi DLookup particular de esta manera:
SELECT DLookUp();
Para obtener:
| DLookup() |
+-----------+
| Dortmund |
+-----------+
Y otro ejemplo, si pongo:
SELECT DLookUp();
Obtengo:
| DLookup() |
+-----------+
| Rome |
+-----------+
Funciona aceptablemente bien y nos puede resultar muy útil cuando queramos utilizar la función DLookup en MySQL, sin embargo no es una solución idonea. Quizá cuando MySQL elimine las restricciones comentadas anteriormente se pueda crear una mejor solución. Por lo pronto en el próximo post subiré una solución infinitamente más elegante y potente para hacer lo mismo sólo que en lugar de hacerlo desde el lado del servidor MySQL lo haremos desde el lado de una aplicación programada en .NET.
En el siguiente post hay una versión distinta más breve y elegante del DLookup en MySQL.
Tags: Access, bases de datos, dcount, dlookup, dmax, MySQL, stored function, stored procedure, VBA