Mostrando las entradas con la etiqueta Base de Datos. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Base de Datos. Mostrar todas las entradas

miércoles, 11 de marzo de 2009

/el trabajo es salud



En el sitio de la Asociación de Ingenieros del Uruguay, se publicó este llamado para estudiantes avanzados de Ing. en Computación.

REQUISITOS:

* Estudiante avanzado de Ingeniería en Computación.
* Experiencia en bases de datos relacionales, lenguajes de programación y análisis de requerimientos.
* Se valorará haber aprobado Base de Datos y Taller de Programación, así como los conocimientos de GNU/Linux.
* Buen nivel de inglés.

Tareas principales:

* Análisis y relevamiento de requisitos junto al cliente.
* Diseño e implementación de aplicaciones
* Realización de pruebas y tareas de verificación de productos.
* Documentación


Enviar Currículum Vitae a: rrhhceibal@latu.org.uy hasta el 16 de marzo inclusive, haciendo mención a la referencia correspondiente.

Mas datos, aqui.






jueves, 6 de noviembre de 2008

/declaración de variables en Firebird



Estoy usando Firebird como motor de base de datos (open source, liviana, rápida, y considerablemente completa).

Situación: estaba creando procedimientos almacenados y disparadores, en ellos necesitaba declarar variables locales.
Cuando compilo el script, me sale error en la declaración de la variable. Leo la documentación que provee el sitio, y para mi sorpresa estaba respetando la sintaxis.
Para aislar el error, comenté el resto, y en efecto, la parte conflictiva estaba en la declaración de variables.

La documentación consultada fue: Developers Guide, Embedded SQL, Language Reference.

En un foro me dan la respuesta, la documentación tiene impresiciones, la declaración de la variable debe ir antes del cuerpo del procedimiento/disparador, o sea antes del BEGIN:

Este es un ejemplo del código correcto y que funciona:


CREATE OR ALTER trigger pacientes_bi0 for pacientes
active before insert position 0
AS
DECLARE VARIABLE clave_pac INTEGER; /* Aqui debe ir antes del BEGIN*/
begin
if (new.cod_pac is Null) then
begin
EXECUTE PROCEDURE getcodpac 'Pacientes' RETURNING_VALUES :clave_pac;
new.cod_pac = clave_pac + 1;
end
/* Trigger text */
end



NOTA: No solo ya viene con Ubuntu, es además sumamente popular en Brasil, Italia y y otros países europeos, especialmente entre los desarrolladores Delphi, permite embeber la base de datos en un sólo archivo .DLL junto con su aplicación.





sábado, 1 de noviembre de 2008

/resolviendo problemas en delphi



Expongo aqui algunos problemas a los que me enfenté desarrollando en Delphi 7, movida principalmente porque la información en español es prácticamente nula.

Desconozco si estos problemas fueron solucionados en las versiones posteriores.


Herencia visual

Haciendo un framework para una aplicación, estoy en la siguiente situación. El Form padre tiene un dbgrid (grilla orientada a datos provenientes de alguna sentencia SQL).
Este form es una clase base, prácticamente una clase abstracta donde se definen sus controles y eventos de manera virtual.
La grilla no tiene definido los campos porque no sabe qué tabla será mostrada, éstos campos se definirán en el formulario hijo que es donde se ejecuta la sentencia SQL.

En el formulario hijo conecto el dbgrid con la fuente de datos usando ClientDataSets. Decido borrar uno de los campos, no me interesa que se vea. Lo hago desde el visor de propiedades del objeto dbgrid de la clase heredada:

y me sale el siguiente error:

"Selection contains a component introduced in an ancestro form which cannot be deleted"



Lo raro es que los campos no estaban definidos en el Form padre, pertenecen al form heredado, tendría que poder borrarlos. El lío parece estar por lo que pude ver en cómo maneja Delphi la clase TCollection (en este caso la de los campos), por lo menos hasta esa versión.

La solución la encontré modificando a mano, el archivo .dfm. Es un archivo de texto, fácilmente editable, donde Delphi guarda el código de las clases de los componentes visuales que hay en un form.
Lo que está marcado en azul, es lo que borré, luego grabé los cambios y voilá.


Puede pasar que deban reiniciar Delphi, quizás porque en mi caso no me di cuenta que estaba conectada a la base de datos, entonces al ejecutarlo sin salir aparecía otro error. Reiniciando se soluciona.


ClientDatasets

El dataSetprovider del clientDataSet estaba unido a una ibquery, componente que tiene la consulta con parámetros. Base de datos: Firebird.
De todos modos no importa el motor de base de datos, lo que importa es como deben estar ligados los parámetros de ClientDataSet y el ibquery que realiza la consulta.

ibquery.Sql :=
'Select campo1, campo 2 From Tabla where campo1 = :campo1 or campo2 = :campo2'

Mi idea inicial era cambiar el SQL asignando diferentes valores a los parámetros segun un criterio de búsqueda (por un parámetro u otro).
Los parámetros de ambos componentes se definieron en tiempo de diseño.

Cambiaba la sentencia SQL, pero no la cantidad de parámetros definidos (dos), ya que estos no cambiaban, solo variaba los que se usaban en la sentencia SQL:
Podría ser:
'Select campo1, campo 2 From Tabla where campo1 = :campo1'
o
'Select campo1, campo 2 From Tabla where campo2 = :campo2'

Cuando cambiaba el valor de los parámetros en tiempo de ejecución salía el siguiente error : "XSQLDA index out of range"

El código problemático era:

//asigno nuevo parámetro
cdsPacientes.params.ParamByName('CI').AsString := ci_pas;

//reabro para que realice la búsqueda con el
ibquery.sql := texto_sql;
cdsPacientes.Close;
cdsPacientes.Open;


Harta de buscar en internet, y como siempre en sitios en inglés, polacos o alemanes, que no se adaptaban a la situación que desencadenó mi problema, me avive siguiendo las sábanas de código que tiene Delphi.

El error estaba en que el ClientDataSet (que es 'alimentado' por los datos de la consulta ibquery), tenía mayor cantidad de parámetros definidos que los usados en la consulta SQL del ibquery. Deben tener la misma cantidad de parámetros. Si no hay concordancia entre los que usa el SQL y los definidos en el ClientDataSet, sale error.

Para mantener los parámetros, intenté poniendo valores inexistentes en los parámetros por los cuales no deseaba buscar. Pero no entiendo porqué ofrece problemas de filtrado. Decidí sencillamente omitir los parámetros, una pena porque pierdo cierto nivel de abstracción. La idea era modificar los parámetros sin tocar la sentencia SQL.






domingo, 31 de agosto de 2008

/backup y restore desde aplicación Delphi



Hace poco el requerimiento de una aplicación era restaurar/respaldar una base de datos MySQL desde una aplicación Delphi.

De las opciones open source como interfaz entre MySQL y Delphi, los componentes Zeos me parecen los mejores, pero no tienen implementada la opción de backup/restore.

Personalmente recomiendo, además, un administrador externo para estas tareas por la independencia de la base de datos respecto a la aplicación que la utiliza.
De hecho el que viene con el motor MySQL es muy eficiente y gratuito: http://www.mysql.com/products/tools/administrator/. Permite hacer respaldos automáticos (mediante script FTP), o bien de forma manual.
Alternativamente MySQL ya provee algunas características incorporadas para respaldos en cada versión: http://www.mysql.com/products/backup/.

En definitiva cubrí las tareas de respaldo/restauración en los dos frentes, desde la aplicación, y un administrador externo.


Componentes:

Hay componentes que pueden incorporarse a Delphi para realizar esta tarea.
MyDAC, no es gratuito, solo versión de prueba. (Y no lo probé, total, no se iba a comprar)
ZlawMySQLBackup, gratis, para Delphi 7 al menos, no pude conseguirlo, por lo que leí está en fase de prueba. Por lo tanto no es aconsejable para producción.
Aun así, por las características que describe parece interesante, aunque engorroso de instalar (si es que lo encuentran).
MySQL BackUp Component, probado para Delphi 5, funciona también para Delphi 7.

Desaconsejo cualquier copia desde un simple administrador de archivos, el administrador de la base de datos, sabe qué estructuras copiar, y como modificarlas en caso que sea necesario.

Programación:
Otra forma es hacerlo desde código, sin usar componentes, que es por la que opté (de momento). Simplemente por simplicidad.
(Doy por hecho que el path del motor está en la variable de entorno PATH del sistema)

Respaldo

procedure TFormBackUpRestore.btnBackUpClick(Sender: TObject);
begin
ShellExecute(handle,'open', 'cmd.exe',
Pchar('/c "C:\MySql\Bin\mysqldump.exe" -h localhost -R
-u username -ppassword databasename > mibackup.sql ')
,nil,
SW_SHOW );
end;

Restaurar (cambio el redireccionamiento "<")

procedure TFormBackUpRestore.btnRestoreClick(Sender: TObject);
begin
ShellExecute(handle,'open', 'cmd.exe',
Pchar('/c "C:\MySql\Bin\mysqldump.exe" -h localhost -R
-u username -ppassword databasename < mibackup.sql ')
,nil,
SW_SHOW );
end;


ShellExecute, de la unidad ShellAPI se sigue usando por motivos de compatibilidad, lo invocado corre como una aplicación (arquitectura de 16 bits) y no de proceso.
Pero funciona.

Para arquitectura de 32 bits, debería usarse CreateProcess (unidad WinAPI), pero hay que adaptar su sintaxis a Delphi, en el help el ejemplo aun viene para C, lo que muchas veces ahuyenta a los que programan en Delphi.
En Delphi Corner hay un ejemplo de CreateProcess.







sábado, 26 de mayo de 2007

/reparando SQL Express


Cuando instalé Visual Studio 2005, me di cuenta que ese motor de base de datos no quedó bien instalado:





Dado que había perdido muchas actualizaciones de Windows decidí buscar alguna relacionada con el tema, en este caso con este motor que quizás era al software que necesitaba.

La solución la encontré aqui, claro para eso desinstalé SQLExpress y lo reinstalé eligiendo la opción de SQL Express con servicios avanzados (traía unas actualizaciones). Listo, solucioné el problema.