Você está na página 1de 7

Manual de VFP y MysQL

III Campos BLOB

INTRODUCCIN Sigo igual que en las anteriores, no se me ocurre nada. HERRAMIENTAS UTILIZADAS: A excepcin del VFP, el software utilizado se puede encontrar en www.mysql.org VFP 7.0 MySQL 4.0.17 MySQL Connector / ODBC 3.51 MDAC 2.1 o posterior (normalmente instalado junto con Windows)

REQUISITOS PREVIOS Haber creado la base de datos y las tablas de los artculos anteriores Tener conocimientos de OLEDB

EMPEZAMOS Hemos estado utilizando la tecnologa SQL-PassThrough durante las entregas anteriores pero, para el manejo de campos Binary Large OBjects (BLOB) utilizaremos OLEDB. CONECTNDONOS CON MySQL UTILIZANDO OLEDB Cadena de conexin: por no ser el tema de ste artculo slo explicar los parmetros necesario en ella: Ejemplo de cadena de conexin (todo en una sola lnea)
DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost; DATABASE=vfp_db; UID=root; PWD='

Parmetro DRIVER SERVER DATABASE UID PWD

Descripcin Es el nombre del driver utilizado para realizar la conexin Nombre del servidor o IP Base de datos a la que nos queremos conectar Nombre de usuario Password del usuario

Denny Infante Jurez denny_infante@hotmail.com

Manual de VFP y MysQL


III Campos BLOB Probando la conexin
LOCAL ADOCnx, lRet, oRs, CnxStr ADOCnx = CREATEOBJECT('ADODB.Connection') ADOCnx.CursorLocation = 3 &&adUseClient CnxStr = 'DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;' +; 'DATABASE=vfp_db;UID=root; PWD=' lRet = ADOCnx.Open(CnxStr, "", "") IF ADOCnx.State = 1 THEN oRs = ADOCnx.Execute('SELECT * FROM InnoClientes') IF TYPE('oRs') = 'O' THEN IF oRs.RecordCount > 0 THEN oRs.MoveFirst DO WHILE NOT oRs.Eof ?oRs.Fields[1].Value oRs.MoveNext ENDDO ELSE ?'No se obtuvieron registros de la consulta' ENDIF ELSE ?'Error en la consulta' ENDIF ADOCnx.Close() ELSE ?'ERROR: No se logr conectar con la base de datos' ENDIF

CREANDO LA TABLA PARA ALMACENAR ARCHIVOS Hasta aqu se supone que ya logramos conectarnos con MySQL ahora crearemos la tabla con un campo BLOB (ver manual de MySQL para mayor informacin); la estructura de la tabla es: Campo IDBlob Imagen Tipo Campo entero autonumrico MEDIUMBLOB

Porque MEDIUMBLOB, por el tamao de almacenamiento 16777215 bytes (ver manual de MySQL para ver capacidad de otros tipos de campos BLOB) La cadena que utilizaremos para la creacin de la tabla en la base de datos:
CREATE TABLE IF NOT EXISTS BlobTable PRIMARY KEY, Imagen MEDIUMBLOB) (IDBlob INT NOT NULL AUTO_INCREMENT

Denny Infante Jurez denny_infante@hotmail.com

Manual de VFP y MysQL


III Campos BLOB Creando la tabla con un campo BLOB
LOCAL lcError lcError = .F. ON ERROR lcError = .T. *!* Conectndonos con la base de datos LOCAL ADOCnx, lRet, oRs, CnxStr ADOCnx = CREATEOBJECT('ADODB.Connection') ADOCnx.CursorLocation = 3 &&adUseClient CnxStr = 'DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;' +; 'DATABASE=vfp_db;UID=root; PWD=' lRet = ADOCnx.Open(CnxStr, "", "") *!* Si no nos logramos conectar IF ADOCnx.State <> 1 OR lcError THEN ?'ERROR: No se logr la conexin con la base de datos' ON ERROR ADOCnx.Close() RETURN .F. ENDIF *!* Sentencia para crear la tabla LOCAL lcSQLCreateTable lcSQLCreateTable = 'CREATE TABLE IF NOT EXISTS BlobTable ' +; '(IDBlob INT NOT NULL AUTO_INCREMENT PRIMARY KEY, ' +; 'Imagen MEDIUMBLOB)' *!* *!* *!* Nota: con esta sentencia no esperamos que nos regrese ningn recordset as que asumiremos que si no ocurre un error la tabla ha sido creada correctamente

oRs = ADOCnx.Execute(lcSQLCreateTable) IF lcError THEN ?'ERROR: no se logr crear la tabla: ' + MESSAGE() ELSE ?'Tabla BlobTable creada!!' ENDIF ON ERROR ADOCnx.Close()

Denny Infante Jurez denny_infante@hotmail.com

Manual de VFP y MysQL


III Campos BLOB AGREGANDO INFORMACIN A LOS CAMPOS TIPO BLOB Para el manejo de campos tipo blob existen dos funciones AppendChunk y GetChunk ambas funciones pertenecen al objeto Recordset (para mayor informacin consultar la ayuda) Agregando el archivo a la tabla (AppendChunk) Hay dos formas de obtener la informacin del archivo, la primera utilizando FILETOSTR(Nombre del Archivo) y la segunda utilizando FREAD(hFile, Nombre del Archivo); cual utilizar; si se van por el lado ms fcil (usar FILETOSTR) tomando como referencia un archivo de 42kb este ocupar ms espacio en la tabla; el tamao de la tabla con un registro utilizando FILETOSTR es de 166 kb a diferencia de utilizar FREAD que es de 83 kb (la mitad de FILETOSTR)
LOCAL lcError lcError = .F. ON ERROR lcError = .T. *!* Conectndonos con la base de datos LOCAL ADOCnx, lRet, oRs, CnxStr ADOCnx = CREATEOBJECT('ADODB.Connection') ADOCnx.CursorLocation = 3 &&adUseClient CnxStr = 'DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;' +; 'DATABASE=vfp_db;UID=root; PWD=' lRet = ADOCnx.Open(CnxStr, "", "") *!* Si no nos logramos conectar IF ADOCnx.State <> 1 OR lcError THEN ?'ERROR: No se logr la conexin con la base de datos' ON ERROR ADOCnx.Close() RETURN .F. ENDIF *!* Cargamos el archivo que queremos guardar en la base de datos LOCAL lcImage *!* lcImage = FILETOSTR(GETFILE()) *!* ***************************************************************** *!* Del ejemplo de la ayuda de VFP *!* ***************************************************************** Local gnFileHandle,nSize,cString gnFileHandle = FOPEN("MDLogo.jpg") * Seek to end of file to determine the number of bytes in the file

Denny Infante Jurez denny_infante@hotmail.com

Manual de VFP y MysQL


III Campos BLOB
nSize = FSEEK(gnFileHandle, 0, 2) && Move pointer to EOF IF nSize <= 0 * If the file is empty, display an error message WAIT WINDOW "This file is empty!" NOWAIT ELSE * If file is not empty, the program stores its contents * in memory, then displays the text on the main Visual FoxPro window = FSEEK(gnFileHandle, 0, 0) && Move pointer to BOF lcImage = FREAD(gnFileHandle, nSize) * ? cString ENDIF = FCLOSE(gnFileHandle) && Close the file *!* ***************************************************************** *!* Creamos y abrimos un recordset, de preferencia sin registros; esto *!* se logra con la condicin WHERE oRs = CREATEOBJECT('ADODB.Recordset') oRs.Open("SELECT * FROM BlobTable WHERE 1 = 0", ADOCnx, 3, 3) *!* Agregamos un registro en blanco oRs.AddNew() *!* Cargamos los datos del archivo en el campo deseado (del tipo blob) *!* que de acuerdo con la estructura de la tabla es el segundo campo *!* pero como el arreglo de los campos est en base 0 entonces.. oRs.Fields(1).AppendChunk(lcImage) *!* Actualizamos la tabla y cerramos el recordset oRs.update() oRs.Close() IF lcError THEN ?'ERROR: no se logr agregar el archivo a la tabla ' ELSE ?'Archivo agregado!!' ENDIF ON ERROR ADOCnx.Close()

el archivo es muy largo se puede mandar en pedacitos; esto lo pueden logra con un ciclo; eso se los dejo a uds. Obteniendo el archivo de la tabla (GetChunk)
LOCAL lcError lcError = .F. ON ERROR lcError = .T. *!* Conectndonos con la base de datos LOCAL ADOCnx, lRet, oRs, CnxStr ADOCnx = CREATEOBJECT('ADODB.Connection')

Importante: el parmetro de la funcin AppendChunk es el contenido del archivo, cuando

Denny Infante Jurez denny_infante@hotmail.com

Manual de VFP y MysQL


III Campos BLOB
ADOCnx.CursorLocation = 3 &&adUseClient CnxStr = 'DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;' +; 'DATABASE=vfp_db;UID=root; PWD=' lRet = ADOCnx.Open(CnxStr, "", "") *!* Si no nos logramos conectar IF ADOCnx.State <> 1 OR lcError THEN ?'ERROR: No se logr la conexin con la base de datos' ON ERROR ADOCnx.Close() RETURN .F. ENDIF *!* Inicializamos las variables LOCAL lcImage lcImage = '' oRs = ADOCnx.Execute('SELECT * FROM BlobTable') IF TYPE('oRs') = 'O' THEN IF oRs.RecordCount > 0 THEN LOCAL lcChunkSize, lcChunkBuffer, lcImg lcChunkSize = oRs.Fields(1).ActualSize lcChunkBuffer = 0 lcImg = '' *!* Este ciclo nos ayuda a traer por partes el archivo y no en un *!* solo paso; esto es ms adecuado cuando el archivo es grande, *!* permite poner un indicador que muestre el porcentaje de avance, *!* y con el DOEVENTS ejecutar otras tareas mientras termina de *!* *!* descargarse el campo Do While lcChunkBuffer < lcChunkSize lcImg = oRs.Fields(1).GetChunk(100) lcImage = lcImage + lcImg lcChunkBuffer= lcChunkBuffer + 100 ENDDO *!* La siguiente lnea es necesaria para convertir el texto, que nos *!* lo regresa en formato UNICODE, al formato que necesitamos para *!* grabar el archivo lcImage = STRCONV(lcImage, 6) *!* Darle el nombre con el que queremos guardar el archivo *!* con todo y extensin LOCAL hFile hFile = FCREATE('MDLogo_from_MySQL.jpg') =FWRITE(hFile, lcImage) =FCLOSE(hFile) *!* STRTOFILE(lcImage, GETFILE()) ELSE ?'No se obtuvieron registros de la base de datos' ENDIF oRs.Close() ?'ERROR: No se logr crear el objeto Recordset' ENDIF

ELSE

Denny Infante Jurez denny_infante@hotmail.com

Manual de VFP y MysQL


III Campos BLOB

IF lcError THEN ?'ERROR: no se logr obtener el archivo a la tabla ' ELSE ?'Archivo grabado!!' ENDIF ON ERROR ADOCnx.Close()

COMENTARIOS ADICIONALES Recuerden que no se recomienda almacenar archivos en las tablas; lo que se recomienda es tener en la tabla la referencia al archivo, se que existen casos en el que es necesario tenerlos en la tabla para esas situaciones es que elabor el artculo. Espero que les sea de utilidad Denny Infante Jurez

Denny Infante Jurez denny_infante@hotmail.com