Crear una conexión a mySQL
Este ejemplo muestra como conectarse a una base de datos mySQL y trabajar en ella mediante SQL pass through.
Primero creamos el string de conexión a la misma, aquí damos dos ejemplos, con la base de datos en nuestro disco local y con una base de datos remota y en un puerto diferente.
En este ejemplo estamos usando una práctica llamada DSN-less es decir no usamos el administrador de orígenes de ODBC para conectarnos.
Es una práctica bastante usada y nos independizamos si el usuario creo la conexión ODBC en su puesto de trabajo o no.
Para crear una conexión a mySQL deberá tener instalado el driver ODBC correspondiente, este se puede descargar del siguiente link: http://www.mysql.com/products/connector/odbc
lcStringCnxRemoto = "DRIVER={MySQL ODBC 3.51 Driver};" + ; "SERVER=200.1.1.1;" + ; "PORT=3333;" + ; "UID=booking;" + ; "PWD=booking;" + ; "DATABASE=booking;" + ; "OPTIONS=131329;" lcStringCnxLocal = "DRIVER={MySQL ODBC 3.51 Driver};" + ; "SERVER=localhost;" + ; "UID=root;" + ; "PWD=clave;" + ; "DATABASE=booking;" + ; "OPTIONS=131329;" SQLSETPROP(0,"DispLogin" , 3 ) lnHandle = SQLSTRINGCONNECT(lcStringCnxLocal)
Interpretando el string de conexión
- DRIVER indica que estamos usando el driver mySQL instalado. En este ejemplo la versión 3.51
- SERVER indica donde está la base de datos mySQL, presentamos dos ejemplos para trabajar localmente y remoto. En el caso que sea remotopodemos especificar un número IP o el nombre de un servidor.
- PORT especifica donde está instalado el mySQL, muchas veces los administradores de red cambian este puerto (que por defecto es el 3306 por otro).
- UID es el nombre de login con el cual accederemos.
- PWD es nuestra clave.
- DATABASE es el nombre del schema de mySQL en que trabajaremos. en este ejemplo el schema booking.
- OPTIONS esta opción especifica como mySQL debería trabajar. Si no se usa nos podemos conectar sin problemas. Se utiliza en caso particulares.
Accediendo a los datos
Vamos a probar nuestro string de conexión.
SQLSETPROP(0,"DispLogin" , 3 ) lnHandle = SQLSTRINGCONNECT(lcStringCnxLocal) IF lnHandle > 0 cmd = SQLEXEC(lnHandle,"select QuantityRooms from roomtype","cur_roomtype") IF cmd > 0 BROWSE ELSE AERROR(laErr) MESSAGEBOX("No se pudo conectar a mySQL. Error: " + CHR(13) + laErr[2]) ENDIF USE IN cur_roomtype SQLDISCONNECT(lnHandle) ELSE AERROR(laErr) MESSAGEBOX("No se pudo conectar a mySQL. Error: " + CHR(13) + laErr[2]) ENDIFSi nuestra conexión fue satisfactoria, la variable lnHandle fue mayor que cero, comenzamos a hacer operaciones SQL contra la base de datos.
En este ejemplo simplemente hacemos un select que nos devuelve la columna QuantityRooms de la tabla RoomType. El resultado lo guardamos enun cursor llamado cur_roomtype.
Creando sentencias SQL más complejas
El comando SQLEXEC() tiene como segundo parámetro la sentencia SQL. Esta, si es muy compleja la podemos guardar en una variabley si esta es mayor de 255 caracteres (límite de VFP para las variables de tipo string) podemos usar el comando TEXT y además queda mas elegante en nuestro código
TEXT TO lcSQLcommand NOSHOW SELECT Inventory.inventoryid, Inventory.date, Inventory.roomtypeid, Inventory.sold, Roomtype.descrip, Roomtype.rooms FROM inventory Inventory INNER JOIN roomtype Roomtype ON Inventory.roomtypeid = Roomtype.roomTypeID ORDER BY Inventory.date DESC ENDTEXT cmd = SQLEXEC(lnHandle,lcSQLcommand)Nótese que no usa la coma para separar concatenar los comandos. Dentro del bloque TEXT ... ENDTEXT podemos escribir como queramos.
Un punto muy importante es que si nuestra base de datos mySQL reside en un server Linux o Unix esta será case-sensitive, o sea, las distinguirá mayúsculas de minúsculas. No es lo mismo SELECT roomtype que SELECT RoomType. Esto generará un error dependiendo como hayamos creado nuestro schema.
Pasando parámetros a nuestra consulta
La manera mas sencilla de pasar parámetros es definiendo una variable, asignándole un valor previo a la ejecución de la consulta y asignándole un signo de interrogación delante.
nValor = 12 cmd = SQLEXEC(lnHandle,"select QuantityRooms from roomtype where roomtypeid = ?nValor","cur_roomtype")Llamando un procedimiento almacenado
SQLEXEC(lnHandle, "call myStoreProcedure(@param1)")Usando vistas remotas a mySQL
El primer paso es crear la conexión en nuestro contenedor de base de base datos de VFP.
Como string de conexión usamos el mismo con el que comenzamos estos ejemplos.
Verificamos que la conexión sea correcta y comenzamos a crear una vista remota.
Una vez que seleccionamos en nuestro contenedor de VFP crear una vista remota, seleccionamos la conexión creada en el paso anterior.
Automáticamente VFP nos pedirá que agreguemos tablas a al diseñador de vistas.
Un punto importante es que debe estar marcado el checkbox "All User Tables", de lo contrario el driver de mySQL nos devolverá un error como que la tabla seleccionada no existe.
Algunas consideraciones importantes
Cuando diseñemos en mySQL nuestro schema de datos, es importante crear un usuario que no sea root para acceder al mismo y darle los privilegios necesarios para trabajar sobre el schema.
root es el usuario con máximos privilegios sobre la base de datos (ídem que el usuario sa en SQL Server) y no es recomendable trabajar con él y menos si se accede en forma remota.
Si nuestro motor mySQL reside en un server Linux (o Unix) tener consideración con los nombres de las tablas y columnas, estos distinguen mayúsculas de las minúsculas.
No existe una estandarización en el lenguaje de los motores de base de datos, por lo cual si en SQL Server usaban la cláusula SELECT TOP 10 FROM miTabla ... para obtener solo 10 registros de una consulta, esta generará un error en mySQL.
mySQL usa la cláusula LIMIT 10. Es muy importante que lean la ayuda sobre cláusulas y funciones y estas no queden "hard-coded" en el código y puedan parametrizarse en el sistema, así si pasan de mySQL a ORACLE o a SQL Server, cambien la capa de datos y no deban tocar su código.
Ricardo Fynn
No me funciona con VFP 6.0
ResponderBorrarSOLO ES PARA VFP9
BorrarTodo bien. Pero cómo podemos evitar "fijar" la cadena de conexión en el código. ¿Cómo se puede usar un archivo externo editable para guardar los datos de conexión y evitar compilarla dentro del código?
ResponderBorrarHay un error ya de por sí en el blog. Las variables NO ESTÁN limitadas a 255 caracteres en Visual FoxPro. Son las sentencias VFP las que están limiitadas a esa cantidad de caracteres. Si no, sería imposible, por ejemplo, tener una variable lcCadena con el contenido de un campo memo.
BorrarCon respecto a tu pregunta... yo particularmente uso un archivo de texto de inicio, en donde fijo las variables esas. Pero también otra opción sería que las tengas en una tabla libre de configuración de tu sistema. ;)
Entonces, supongamos que vos tenés una tabla libre "conexion.dbf". Tenés los campos siguientes:
driver c(200), servidor c(30), puerto i, usuario c(30), password c(30), basedatos c(30), opciones c(20)
Por dar un ejemplo eh...
Entonces ahí hacés:
lcStringCnxRemoto = "DRIVER=" + ALLTRIM(conexion.driver) + ";" + ;
"SERVER=" + ALLTRIM(conexion.servidor) + ";" + ;
"PORT=" + ALLTRIM(STR(conexion.puerto)) + ";" + ;
"UID=" + ALLTRIM(conexion.usuario) + ";" + ;
"PWD=" + ALLTRIM(conexion.password) + ";" + ;
"DATABASE=" + ALLTRIM(conexion.basedatos) + ";" + ;
"OPTIONS=" + ALLTRIM(conexion.opciones) + ";"
En el caso de puerto, primero convierto el valor entero en una cadena (con STR()) y después hago el ALLTRIM.
Y listo, ahí no lo tenés hard-coded sino en una tabla que podés manejar a tu antojo.
Abrazo!
Jose Merino, grabalo en un archivo binario ejemplo un .txt
BorrarRegresé después de algún tiempo y encontré tu brillante respuesta. Muchas gracias amigo.
BorrarMuy buena la solución gracias por compartir
ResponderBorrarEn mi caso, tengo un archivo de texto con extensión INI, lo que en principio me planteó un problema de seguridad. A nadie le gustaría dejar su usuario y su password tan abiertos, verdad? entonces los encripté con blowfish... y listo
ResponderBorrarEste comentario ha sido eliminado por el autor.
ResponderBorrarComo hacemos con concurrencia de datos?
ResponderBorrarEspero aun este en vigencia, tengo un problema tengo Mysql en un servidor UBUNTU, todo funciona excepto cuando la tabla es demaciado drande se sale de la aplicacion almomento de hacer una consulta, no se como solucionar este problema , me podria ayudar...?
ResponderBorrarMuchas gracias por tu aporte.
ResponderBorrar