RSS

SQLite Articulo en PDF

martes, 12 de abril de 2011

Hola Amigos , aqui les traemos una pequeño articulo de SQLite
SQLite

Concatenación - UNION - uso de LIKE - Nombre de columnas con espacios

lunes, 6 de abril de 2009


CONCATENACIÓN DE CAMPOS

Es posible unir dos o mas cadenas usando un operador de concatenación. El estandar de SQL dice que se deberia usar ||, pero hay muchas diferencias entre los principales proveedores.

SELECT codigo || nombre
FROM departamentos


UNION. Uso de UNION para armar una unica vista con diferentes tablas.
Para crear una vista con datos provenientes de diferentes tablas, debe usar sentencias SELECT separadas por la palabra reservada UNION.
Asegurese de que se enumeraron la misma cantidad de columnas en cada una de las sentencias SELECT.

SELECT nombre FROM Clientes
UNION
SELECT nombre FROM Empleados
UNION
SELECT nombre from artistas


LIKE. Uso del comando LIKE en una sentencia SELECT.
El comando LIKE permite el uso de caracteres comodines:
% Se usa para reemplazar una cadena
_ Se usa para reemplazar un solo caracter.

En el siguiente ejemplo se listan los paises que comienzan con Z. El país Zambia se ajusta al criterio de elección, ya que 'ambia' se iguala con %.

SELECT nombre
FROM paises
WHERE nombre LIKE 'Z%'

BUSQUEDA EN TEXTO COMPLETO
El método "Fuerza bruta" consiste en usar el operador LIKE en cualquiera de los campos a ser inspeccionados.
Esto sería relativamente caro, pero lo suficientemente bueno en la mayoria de los casos. El término a buscar debe escribirse entre dos caracteres comodines y rodeado por comillas simples.
Se deberia construir la cadena literal en algun lenguaje de script - ¡No olvidar las comillas simples!

SELECT nombre FROM gisq.cia
WHERE nombre LIKE '%el%'


FUNCIONES DE AGREGADO. Mostrar un nombre de columna para una funcion de agregado
Cuando uno de los resultados a devolver es calculado (por ejemplo una suma) el nombre de la columna se asignará arbitrariamente. Es posible especificar uno particular, del siguiente modo:

SELECT region, SUM(poblacion) AS Poblacion
FROM cia GROUP BY region


NOMBRES DE COLUMNAS CON ESPACIOS.
Es posible definir nombre de columnas con espacios y estas pueden ser accedidas en las consultas. Por ejemplo:

CREATE TABLE MonstruoEspacial("Balance de cuenta" INT);
INSERT INTO MonstruoEspacial VALUES (42);
SELECT "Balance de cuenta" FROM MonstruoEspacial

traduccido por Monica Galarza

EQUI-JOIN (inner join) - SELF JOIN

Saludos, a los integrantes de la comunidad, con este post iniciamos una serie de articulos mediante los cuales acercaremos material traducido desde sitios en inglés.
Comenzaremos este proyecto poniendo a disposición la traducción del contenido en el sitio SQLzoo.net.
Las traducciones no son literales, en algunos casos se han interpretados los textos a fin de poder proveer una mejor explicación de los ejemplos contenidos.
Si desean que se traduzca el contenido de algun otro sitio, seran bienvenidas sus sugerencias.
Bueno manos a la obra ...

Como usar un EQUI_JOIN (inner join) para relacionar dos tablas con el mismo nombre

Supongamos que tenemos una tabla empleados en donde guardamos los datos de los empleados y de los jefes de departamento.
Queremos armar una consulta que muestre el identificador de empleado, nombre del empleado, identificador de su jefe, nombre de su jefe y el departamento al que pertenece su jefe.
Para esto, deberemos relacionar la tabla empleados consigo misma mediante un "self join".
A cada copia de la tabla le asignamos un "alias", en este caso usamos e para los empleados y j para los jefes y a partir de alli podemos tratarlas como tablas diferentes.

Por defecto la unión obtenida es interna (inner join), esto significa que Ruben (Un empleado sin jefe) no se muestra en los resultados.

CREATE TABLE empleados( id_empleado INTEGER PRIMARY KEY,
nbre_empleado VARCHAR(10),

id_dpto VARCHAR(10),

id_jefe INTEGER REFERENCES empleados
);


INSERT INTO empleados VALUES (1,'Ruben','Ing',NULL);
INSERT INTO empleados VALUES (2,'Juan','SoC',1);
INSERT INTO empleados VALUES (3,'Andres','SoC',2);
INSERT INTO empleados VALUES (4,'Alicia','SoC',2);

SELECT e.nombre as empleado, j.nombre as jefe, j.id_dpto as dpto_jefe FROM empleados e, empleados j WHERE e.jefe_id = j.empleado_id

Traducido por Monica Galarza

FISL 10 - Edicion Especial -

viernes, 27 de marzo de 2009

Se está acercando uno de los eventos de Software Libre más grandes del mundo, la decima edición del "Fórum Internacional de Software Livre" - FISL 10 -
Algunos de los panelista que pasaron por FISL fueron Ian Murdock -Debian - , Rasmus Lerdorf -PHP-, Richard Stallman -FSF- , Eric S. Raymond, JonmaddogHall -Linux.org-
Esta edicion Especial se realizara del 24 al 27 de junio de 2009, en Porto Alegre, Rio Grande do Sul, Brasil.
SQLite Latino no se podia quedar fuera de este importante evento, por ello invitamos a la comunidad a visitar el web site del FISL , a traves del banner que esta en el sitio..
un Abrazo Gerardo Antonio

Adelantos del nuevo e-Book de SQLite por El Tribuno

lunes, 23 de febrero de 2009


Hoy 23 de Febrero del 2009 apareció en la portada de uno de los más reconocidos periódicos reconocidos en el noroeste Argentino como es El Tribuno, una entrevista al sr. Gerardo Cabero, integrante fundador de la comunidad SQLite – Latino, dando a conocer algunos adelantos de los proyectos que ya están encaminados y en edición para toda la comunidad, se trata de un eBook para conocer SQLite a fondo, llamado "La Cocina de SQLite".

Desde ya están invitados a leer esta entrevista, sin dejar de agradecer tanto al Periódico El Tribuno como así también a su periodista Fernando Quiros, por el apoyo a este proyecto y la difusión del mismo.

Para más información les dejamos el blog de Fernando Quiros contando más detalles

+ colaboradores

lunes, 16 de febrero de 2009

Bienvenido, Welcome, Welkon, Benvenuto, Witamy, ect..


En esta oportunidad queremos anunciar al llegada de dos nuevos colaboradores que pasana a formara parte de la comunidad asi como tambien darle la bienvenida formal a Marcos Mansilla.

@Marcos Mansilla (Marcos Mansilla - Arg)
@Monica Galarza (monica- Arg)
@Alejandro Sandoval (estepario - Chile)


Un Fuerte Abrazo A TODOS!!! BIENVENIDOS!!!



Entrevista a Daniel Maldonado de SQLite-Latino

sábado, 14 de febrero de 2009


Esta entrevista fue realizada hace algun tiempo, por el Sr. Franco Rivero de la Revista TuxInfo .
www.tuxinfo.com.ar , desde ya Agrademos que nos dejen publicar dicha Entrevista....

Estuvimos con el Sr. Daniel Maldonado, quien junto con Gerardo Cabero están llevando adelante este interesante proyecto desde hace unos meses.

Franco Rivero: FR
Daniel Maldonado: DM

FR: Daniel, contanos un poco de que se trata este nuevo proyecto

DM:SQLite-Latino trata de dar a conocer esta excelente herramienta para el desarrollo de aplicaciones ya sea consideradas de complejidad media como así también los de grandes proyectos o sistemas.
Queremos hacer llegar a toda la gente de habla hispana la información referida a SQLite,
con respecto a sus características, ventajas, compatibilidad con diversos Lenguajes de Programación y demás curiosidades de lo que hemos denominado como el Pseudo Motor de Bases de Datos SQLite.

FR:Para los que no saben de que hablamos ¿Qué es SQLite?

DM:: Según D. Richard Hipp )creador de SQLite(, SQLite son librerías escritas en C
que implementa un motor de base de datos para SQL92 empotrable, Wikipedia también comparte y adopta este concepto, pero según el organizador de
esta comunidad )Gerardo Antonio Cabero(, SQLite permite dar otro tipo de enfoque a las bases de datos, y dejar de ser librería para convertirse en Pseudo
Motor - Aparenta ser un motor pero no lo es un nuevo concepto tomado como válido y que lo utilizamos como premisa para la Comunidad SQLite - Latino.
En tal sentido, Gerardo Antonio Cabero dice:
“Siempre he pensado que hay que dar un nuevo enfoque al desarrollo de las Base de datos, dejando a un lado ese carácter de librería para convertirse en algo más complejo como un Pseudo Motor de Bases de Datos.” Te comento que yo he intentado hablar con D. Richard Hipp y le he comentado de las caracterásticas de SQLite y que el da un nuevo enfoque al desarrollo de las bases datos a través de lo que hemos denominado Pseudo Motor . pero no e Tenido Exito...
SQLite tiene varias funcionalidades, que se entiende como las de un Motor de Base de datos Ejemplo, y con la carencias de otras. Tal es el Caso de La
integridad referencial. (La que actualmente se puede Simular)

FR: ¿Cuáles son las expectativas del proyecto SQLite Latino América a corto y a largo plazo?
DM Básicamente las primeras expectativas de este proyecto es dar a conocer las cualidades más destacadas de SQLite a toda Latino América y de algún modo captar su atención y alentarlos a probar este nuevo concepto para el desarrollo no sólo de prototipos de sistemas sino también de sistemas de alta complejidad.
Además, dar un espacio para que los interesados formulen sus preguntas, dudas y de algún modo generar un espacio de debate de usuarios expertos como así también de novatos en un plano .Por eso los invitamos a que nos visiten y nos acompañen a aprender junto a ustedes.

FR: ¿Quienes llevan adelante el proyecto y con que idea se reunieron a trabajar?
DM: El proyecto comenzó de la mano de Gerardo, al comienzo de todo lo tenía un poco bandonado, hasta que nos conocimos en una charla que el dió, sobre SQLite en Jujuy en las II Jornadas de Software Libre y luego al volver a tener contacto nuevamente en las II Jornadas de Software Libre en Salta. De ese modo realizó, como Gerardo la llamó, “la propuesta Indecente” de ser un administrador y formar juntos y con más fuerza la Comunidad de SQLite Latino y de algún modo continuar colaborando con la comunidad de Software Libre.

FR: Por último, ¿Cómo pueden colaborar los interesados?
DM: Bueno a todos los interesados desde ya le agradecemos sus visitas a la comunidad http://sqlite-latino.blogspot.com, Otro modo de colaborar con este fin es ayudando a traducir la documentación, enviarnos sus Review de SQLite y el comportamiento con otros lenguajes de programación y fomentando el uso de SQLite en el desarrollo de sistemas.

Desde ya agradecemos a Daniel por su tiempo, y queremos ofrecerles desde Tuxinfo a todos los proyectos independientes un espacio para que puedan difundir su trabajo y sus pensamientos, desde nuestra revista alentamos los proyectos que tanto bien hacen a nuestra comunidad y sepan que aquí tienen un espacio para la difusión....
Realizado por : Franco Rivero
Revista: TuxInfo www.tuxinfo.com.ar

Uso de SQLite por Alejandro Sandoval

domingo, 25 de enero de 2009

Hola Comunidad de SQLite Latino, Feliz comienzo de año 2009. hace unos dias El Sr. Alejandro Sandoval nos envio un articulo relacionado con SQLite. Agradecemos su aporte, Asi tambien todo estan invitados a participar de SQLite Latino

Espero que sea de su agradao. Hasta la proxima
Uso de SQLite 

SQLite es un pequeño 'sistema' de base de datos: es una biblioteca que sobre un archivo almacena el esquema de la base de datos y los datos propiamente tal. En términos generales presenta un buen rendimiento, y está aconsejada para quienes requieren almacenar un volumen medio de datos en sus aplicaciones, utilizando un esquema relacional.En el caso de querer incluir la API SQLite en tu proyecto de programación, puedes incluir en tu programa C/C++ a sqlite.h, compilar a sqlite.c y listo.
Dentro de lo que podemos llamar una desventaja de SQLite es que no implementa la integridad referencial, es decir, no disponemos de claves foráneas (puedes declararlas, pero el intérprete ignorará tu declaración). De todas formas, SQLite si implementa triggers, así que hay algunas formas de implementar la integridad referencial de esa forma.
¿Un ejemplo? Pero con mucho gusto... de todas maneras, el ejemplo está pensado solo para mostrar las características de SQLite, así que no esperes un buen diseño ni nada por el estilo...
Por ejemplo, imagínese una pequeña empresa de buses que requiere almacenar información acerca de sus viajes. Para ello, supongamos que tenemos la tabla buses (con información de los buses), viaje (con los datos de un viaje) y pasajero (con los datos de un pasajero). Una propuesta entonces podría ser la siguiente:

create table buses(
  id integer primary key not null autoincrement,
  matricula text not null,
  ano integer not null,
  capacidad integer not null); 

create table pasajero(
  cedula text primary key not null,
  nacimiento date not null);

create table viaje(
  id_bus integer not null,
  cedula text not null);
Bueno, hay algunas cosas por explicar de acá:

SQLite implementa el incremento automático de un campo (autoincrement), el que perfectamente pude indicarse para el primary key.
Las claves foráneas, como ya mencioné, no están implementadas aún en SQLite, así que no las agrego.
La primary key de la tabla viaje será su OID.
SQLite, para almacenar una tupla en una tabla, utiliza el sistema de OID, es decir, asigna secretamente un identificador para cada tupla, que facilita su búsqueda en el arbol B (la estructura de datos usada por SQLite para almacenar los datos en archivo). No necesito declarar el OID, pero puedo consultarlo en cualquier tabla; pronto un ejemplo de eso.
Ahora, insertemos algunos datos, para hacer las pruebas.
insert into buses values(null, 'ABCD-01', 2008, 40);
insert into buses values(null, 'JANO-05', 2007, 27);
insert into buses values(null, 'INSQ-35', 2007, 20);
insert into pasajero values('123ASD-K', 1980-05-23);
insert into pasajero values('237QSD-3', 1970-03-28);
insert into pasajero values('135QTW-3', 1989-08-05);
Con esos datos, podemos ver en acción el sistema de los OID:
sqlite>select oid,* from buses;
1|1|ABCD-01|2008|40
2|2|JANO-05|2007|27
3|3|INSQ-35|2007|20

sqlite>select oid,* from pasajero;
1|123ASD-K|1980-05-23
2|135QTW-3|1989-08-05
3|237QSD-3|1970-03-28

Puede parecer extraño lo que ocurre con la tabla buses, puesto que ya existe su primary key, y esta se autoincrementa. Bien, pues de todas formas se genera un OID... pero cuando se define una primary key autoincrementable de tipo integer, el OID tendrá el mismo valor que dicha clave. No ocurre lo mismo en la tabla pasajero, puesto que su primary key es un texto, y no un entero. Nota también que en los campos que se autoincrementan, el siguiente valor se genera insertando un null.

Gracias a esta característica es que he definido la tabla viajes sin primary key: confío en el OID (lo que no es recomendado, por cierto).

Ahora, la parte artística: ¿y las claves foraneas? Como mencioné, para eso disponemos de los triggers...

create trigger fki_viaje_buses
before insert on viaje
for each row
begin
  select raise(rollback, 'Inserción en viaje viola restricción fki_viaje_buses')
  where (select id from buses where id=new.id_bus) is null;
end;

Luego de eso, intentemos insertar un viaje para un bus no válido:

sqlite> insert into viaje values(5, '123ASD-K');

SQL error: Inserción en viaje viola restricción fki_viaje_buses

El trigger para la actualización (update) es exactamente igual, pero en el caso de la eliminación tenemos un problema: si quiero eliminar un bus ¿qué hago con los viajes? Por como se definió la base de datos, no se pueden eliminar buses o pasajeros mientras hayan viajes, así que manos al trigger:

create trigger fkd_viaje buses
before delete on buses
for each row
  begin
    select raise(rollback, 'No se puede eliminar bus')
    where (select id_bus from viaje where old.id = id_bus) is not null;
end;
Ahora, si yo he insertado los siguientes datos de viaje
insert into viaje values(1, '135QTW-3');
insert into viaje values(1, '123ASD-K');
el trigger impedirá que eliminemos un bus, lo que generaría un estado inconsistente en la base de datos

sqlite> delete from buses where id = 1;
SQL Error: No se puede eliminar bus
 
Como se puede apreciar, SQLite es una alternativa interesante cuando se necesita un acceso a datos rápido y sencillo. Aunque me parece que SQLite es muy bueno, no me atrevería aún a usarlo en un entorno más de producción... aunque en la medida que lo voy usando, más me convence.

Autor: Alejandro Sandoval
Urls : http://esteparioprogramador.bligoo.com

:::NOTA COMPLEMENTARIA:::

Basándose en el ejemplo, el análisis es el siguiente: viaje es una tabla intermedia para la relación de muchos a muchos entre buses y pasajero. Por lo tanto, y siendo los campos de la tabla viaje claves foráneas, no puedo permitir la inserción de un viaje si el bus o el pasajero no existen: si lo permitiera, no tendría integridad referencial, dejando inconsistente la base de datos.

Por esa razón, se crean los triggers, y esa es la lógica que están siguiendo en este caso. Despedacemos el primer trigger pa que quede más claro:

create trigger fki_viaje_buses : Con eso, creo el famosillo trigger, y su nombre es fki_viaje_buses

before insert on viaje : Esto nos asegura la pega: el trigger será ejecutado antes de insertar en la tabla viaje. Eso te garantiza que la inserción no generará un estado inconsistente.

for each row : Está diciendo... puro traducir: repetir el trigger para cada fila insertada. Lo que se va a ejecutar está dentro del begin - end, por si acaso.

select raise(rollback, 'Inserción en viaje viola restricción fki_viaje_buses') 
 where (select id from buses where id=new.id_bus) is null;

Aquí está el detallito: le estamos diciendo que lance un error (y ejecute un rollback) cuando se cumpla la condición del where, es decir, si no hay ninguna tupla en la tabla buses que tenga un ID igual al ID del bus que está en la nueva tupla de viaje (la variablenew se ocupa para designar a la tupla que se intenta insertar). Como ves, es exáctamente lo que definimos en palabras antes de comenzar el análisis del problema.

La actualización es la misma situación, puesto que es en el fondo una inserción. De hecho, la única diferencia entre ambos triggers son los mensajes y el nombre.

La eliminación es ligeramente diferente, y pensemos en el caso de eliminar un bus. ¿Qué haré con los viajes asociados?

Las soluciones ahí son:

  • on delete set null: poner los id_bus de viaje en null (lo que en una tabla intermedia no es factible, puesto que las FK son PK además).
  • on delete cascade: si elimino un bus, elimino todos sus viajes.
  • on delete restrict: no puedo eliminar un bus mientras hayan viajes asociados.

El trigger implementado al respecto sigue la última filosofía: no te dejará eliminar un bus mientras hayan viajes registrados con ese bus. En ese esquema, la lógica es al revés: hago el rollback si HAY viajes con el mismo bus_id que tiene old.id (como imaginarás, oldindica la tupla a eliminar).

El tema de los triggers para simular las FK no es tan complejo... pero igual hay que dedicarle su tiempo (en mi caso, significó aprender triggers primero, porque era materia nueva). Aún así, creo que no me demoré mucho en aprender lo necesario.Espero que hayas quedado más claro. Si hay más dudas, pregunta nomás: yo feliz de ayudar dentro de lo que pueda.

Acceso a Bases de Datos SQLite desde Gambas

domingo, 14 de diciembre de 2008

Nuevamente volvemos a sumar más documentación integrando el pseudo motor de Bases de Datos SQLite y un lenguaje de programación visual que día a día esta atrapando a más programadores de plataformas libres como es Gambas.

En esta oportunidad les voy a dejar el enlace de la revista digital Tuxinfo Nº12 en la cual Pablo Mileti explica en 8 páginas como acceder y realizar consultas y actualizaciones integrando esta dos herramientas SQLite y Gambas y de alguna manera podemos complementar la información con lo que Marcos hace unas semanas atrás mostraba.


Integridad Referencial

La integridad referencial es una propiedad
deseable en las bases de datos. Gracias a la integridad referencial se garantiza que una entidad (fila o registro) siempre se relaciona con otras entidades válidas, es decir, que existen en la base de datos. Implica que en todo momento dichos datos sean correctos, sin repeticiones innecesarias, datos perdidos y relaciones mal resueltas.
Como es sabido por la los desarrolladores de SQLITE , la integridad referencial no esta implementada de forma mativa pero es posible realizar la emulacion de la misma atravez de los trigger.
Extraido de la Wikipedia : www.wikipedia.org
El Siguiente Ejemplo fue extradido de la wiki del "El Server" - http://www.elserver.com/wiki/
=========================================================
La tabla PELICULAS tiene dependencia de otras dos: GENERO y SOPORTE.

Los triggers antes de insert y antes de update on Peliculas tienen en cuenta estas dos dependencias.
Para antes de delete hacen falta dos triggers: uno en Genero y otro en Soporte.
Estos triggers impiden que se pueda borrar un genero o un soporte, si hay peliculas que lo están
usando.
El código deja claro lo que se haría si la dependencia fuera de más tablas,sólo habría que añadir más OR y los triggers on delete.
Si la dependencia fuera solo de una tabla,se quitaría un OR y el delete que sobre.

CREATE TABLE [genero] (
[id_gen] INTEGER PRIMARY KEY NOT NULL,
[nombreGen] VARCHAR(40) UNIQUE NOT NULL
);

CREATE TABLE [soporte] (
[id_sop] INTEGER NOT NULL PRIMARY KEY,
[nombreSop] VARCHAR(20) UNIQUE NOT NULL
);

CREATE TABLE [peliculas] (
[id_pel] INTEGER NOT NULL PRIMARY KEY,
[id_genero] INTEGER NOT NULL,
[id_soporte] INTEGER NOT NULL,
[nombrePel] VARCHAR(40) NOT NULL
);

CREATE TRIGGER film_pel_in before insert on peliculas
for each row
begin
select case
when
(
(new.id_soporte is not null)
and
(new.id_genero is not null)
and
(
((select id_sop from soporte where
id_sop =new.id_soporte) is null)
or
((select id_gen from genero where
id_gen = new.id_genero) is null)
)
)
then raise(abort,'violacion integridad')
end;
end;

CREATE TRIGGER film_pel_up before update on peliculas
for each row begin
select case
when
(
((select id_sop from soporte where
id_sop = new.id_soporte) is null)
or
((select id_gen from genero where
id_gen = new.id_genero) is null)
)
then raise(abort,'violacion integridad')
end;
end;

CREATE TRIGGER film_sop_de before delete on soporte

for each row begin
select case
when
((select id_soporte from peliculas
where id_soporte = old.id_sop) is not null)
then raise(abort,'violacion integridad')
end;
end;

CREATE TRIGGER film_gen_de before delete on genero
for each row begin
select case
when
((select id_genero from peliculas
where id_genero = old.id_gen) is not null)
then raise(abort,'violacion integridad')
end;
end;


Pequeña Consulta en SQLite3 utilizando el lenguaje C

lunes, 1 de diciembre de 2008

Hace algunas semanas hemos recivido , de parte de uno de los desarrolladores "Ricardo D. Quiroga" de la comunidad un ejemplo de como implementar SQLite en el Languaje C. A Quien Agradesemos el Envio de este miniComo..

Basado en el ejemplo posteado en http://www.sqlite.org/quickstart.html
Autor: Ricardo D. Quiroga -> l2radamanthys@gmail.com
El codigo fuente posteado aqui esta bajo licencia GPL2 (license.txt)
Codigo fuente Probado usando el Dev-C++ y el Compilador GCC 
#include
El autor no se hace responsable del daño que el mismo pudiese causar directa o indirectamente a tu computadora ,novia,, perro, Y/O SUEGRA ,ect. use el mismo bajo su propia responsabilidad.
Se Incluyen los siguientes archivos:
* libreria sqlite
- sqlite3.h
- libsqlite3.a
- sqlite3.dll

* codigo fuente
- main.c (Codigo fuente)
- main.c.html (vercion del codigo fuente para visualizar como html)
- test1.dev  (archivo de proyecto (solo para Dev-C++) )

Aunque fue el Codigo fue probado con el Dev-C++ usando el GCC el mismo tambien deveria poderse compilar usando cualquier otro ya que el mismo solo fue escrito en ANSI C

Sobre la BD:
Crear una BD con el nombre 'test.db'(o cambiar el nombre de la bd en el codigo fuente) a la cual luego se le agregara una tabla llamarla 'table1' y colocarle los camposo que ud eligan

Que hace el programa:
Conecxta una base de datos a SQLite realiza una pequeña consulta con SQLite en este ejemplo la consulta es la siguiente "select * from table1;" muestra los resultados en pantalla y cierra la bd.
/*****************************************************************************************
     
  ------  Una Simple consulta en SQLITE Usando C  ------       
         Probado con el Dev-C++ Usando el  GCC       
   Por Ricardo D. Quiroga  - l2radamanthys@gmail.com       
   Este ejemplo esta basado en el codigo posteado en http://www.sqlite.org/quickstart.html       
      Quitando los Comentarios son como 25 lineas       

*****************************************************************************************/

#include
#include
#include //libreria para trabajar con SQLite3

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
    for( int i=0; i
        printf("%s ", argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

int main(int argc, char **argv) {

    sqlite3 *db;    //variable que hara referencia a la Base de Datos que utilzaremos
    char *zErrMsg;  //string que almacenara el mensaje de error
    int rc;         //amacenara el resultado del llamado de las funciones de sqlite3.h
    
  /*****************************************************************************************
    Abrimos la base de Datos en nuestro caso la BD se llamara 'test.db'

    int sqlite3_open(
        const char *filename,   Nombre de la Base de Datos (UTF-8)
        sqlite3 **ppDb          Salida SQLite db handle
    );
    
    En caso de error la funcion sqlite3_open() devolvera un valor distinto de 0
    *****************************************************************************************/
    rc = sqlite3_open("test.db", &db);
    
 /*****************************************************************************************
    Mostramos el mensaje de error en caso de que no se pudiera abrir la Base de Datos
    *****************************************************************************************/
    if (rc) {
        fprintf(stderr, "No se pudo Abrir la base de Datos: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        exit(1);
    }
    
  /*****************************************************************************************
    Strings que alamcenaran las consulta que relizamos en la que Copiaremos la instrucion de
    SQLite que queremos ejecutar en la variable 'instrucion' en este caso una simple consulta
    a la Base de Datos
    *****************************************************************************************/
    char instrucion[1024]="";
sprintf(instrucion, "SELECT * FROM table1;");

 /*****************************************************************************************
    Ejecutamos la instrucion alamcenada en el string instrucion en SQLite3
    
    Esplicacion mas a fondo de la funcion 'sqlite3_exec()'
    
    int sqlite3_exec(
        sqlite3*,                                  Base de Datos Abierta
        const char *sql,                           Instrucion de SQl a evaluar
        int (*callback)(void*,int,char**,char**),  funcion (Callback) ver arrina
        void *,                                    1er agumento de la funcion Callback
        char **errmsg                              variable de mensaje de error (1)
    );
    
    si ocurrio un error durante la ejecucion de la instrucion la la funcion devolvera un valor
    diferente de la constante SQLITE_OK y el tipo de error sera devuelto en la variable errmsg(1)
    *****************************************************************************************/
    rc = sqlite3_exec(db, instrucion, callback, 0, &zErrMsg);
    
 /*****************************************************************************************
    En caso que ocurriera un error en la ejecucion de la instrucion SQL mostramos el mismo
    *****************************************************************************************/
    if ( rc!=SQLITE_OK ) 
    {
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
    }
    
  /*****************************************************************************************
    funcion para cerrar la Base de Datos ( Sin comentarios....)
    *****************************************************************************************/
    sqlite3_close(db); 
    
    printf("\n");
    system("PAUSE"); //pausamos la ejecucion del programa par aque no se cierre la consola

    return EXIT_SUCCESS;
} //fin del programa.....


Este programa fue desarrollado como ejemplo de uso de SQLite para SQLite-Latinoamerica 
Ricardo D. Quiroga

Mono + NHibernate + SQLite

martes, 4 de noviembre de 2008


Después de usar por tanto tiempo Gentle.NET, un ORM que ha sido discontinuado, he decidido al fin comenzar a estudiar NHibernate. Los ejemplos que dan en los manuales y páginas son para Windows (con MS .NET) y SQL Server. Trabajando en GNU/Linux, hice las pruebas con SQLite.

El problema es que el driver utilizado por NHibernate para esta base de datos utiliza un binding desactualizado. Además Mono trae una implementación mejor, que soporta el standard ADO.NET 2.0, que es Mono.Data.Sqlite, disponible a partir de la versión 1.2.4.

El post es especialmente útil para aquellos que quieran utilizar en GNU/Linux (yo uso Ubuntu Gutsy), con Mono, NHibernate y SQLite, utilizando el binding Mono.Data.Sqlite. Si bien puede parecer esto tan fácil como seguir el documento QuickStart y cambiar las opciones correspondientes, no lo es si se intenta utilizar SQLite. Por eso, en este post no voy a explicar todas las cosas, ya que no me interesa y se pueden aprender en la documentación, sino que voy a desarrollar un ejemplo muy sencillo y mostrar cómo utilizar SQLite, ya que hay que solucionar unos problemas no muy triviales.

Cabe aclarar que, si bien todavía no lo he probado, los archivos de mapeo (hbm.xml) y el schema SQL se pueden autogenerar.

Primero creo la tabla que almacenerá los objetos en un archivo llamado, por ejemplo, data.db.sql:

DROP TABLE IF EXISTS personas;

CREATE TABLE personas (
id integer PRIMARY KEY,
nombre varchar(20),
apellido varchar(20)
);

Para el ejemplo utilicé la última versión de SQLite. Para crear la base de datos en el archivo data.db, ejecutamos:

$ sqlite3 data.db <>

La clase de ejemplo (Persona.cs):

using System;

namespace PruebaNHibernate
{
public class Persona
{
private int id;
private string nombre;
private string apellido;

public Persona()
{
}

public int Id {
get { return id; }
set { this.id = value; }
}

public string Nombre {
get { return nombre; }
set { this.nombre = value; }
}

public string Apellido { get { return apellido; } set { this.apellido = value; } } } }

Luego hay que escribir el archivo de mapeo, que es un XML.
version="1.0" encoding="utf-8" ?>
xmlns="urn:nhibernate-mapping-2.2"
namespace="PruebaNHibernate" assembly="PruebaNHibernate">


name="Persona" table="personas">
name="Id" column="id" type="Int32">
class="increment" />
>

name="Nombre" column="nombre" />
name="Apellido" column="apellido" />
>
>

Este archivo se debe agregar como recurso en MonoDevelop.

Luego escribimos el archivo de configuración para nuestra aplicación (app.config):

<?xml version="1.0" encoding="utf-8" ?>
>
>
name="nhibernate"
type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />

>

>

key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"
/>


key="hibernate.dialect"
value="NHibernate.Dialect.SQLiteDialect"
/>


key="hibernate.connection.driver_class"
value="PruebaNHibernate.MonoDataSqliteDriver, PruebaNHibernate"
/>


key="hibernate.connection.connection_string"
value="Data Source=data.db,version=3"
/>


key="hibernate.query.substitutions"
value="true=1;false=0"
/>


key="hibernate.use_prox y_validator"
value="false"
/>

>
>

Nota: Debido a problemas con el hosting no puedo colocar, arriba, el string correcto en la última parte. La palabra prohibida “p r o x y” (sin espacios) tiene un espacio de más entre la “x” y la “y”. En fin, deshabilito en esas lineas la comprobación de clases p r o x y.

Luego en un archivo como Main.cs agrego código en el método principal Main para jugar con todo esto:

using System;
using NHibernate;
using NHibernate.Cfg;

namespace PruebaNHibernate
{
class MainClass
{
public static void Main (string[] args)
{
Configuration conf = new Configuration();
/* Con la siguiente línea leo todo los archivos con extensión
* hbm.xml embebidos como recurso en el assembly especificado */

conf.AddAssembly("PruebaNHibernate");

ISessionFactory sessionFactory = conf.BuildSessionFactory();

ISession s = sessionFactory.OpenSession();

ITransaction tx = s.BeginTransaction();

Persona p = new Persona();
p.Nombre = "Milton";
p.Apellido = "Pividori";
s.Save(p);
tx.Commit();

Console.WriteLine("p - Id: " + p.Id);
Console.WriteLine("p - Nombre: " + p.Nombre);
Console.WriteLine("p - Apellido: " + p.Apellido);
Console.WriteLine();

Persona p2 = (Persona)s.Load(typeof(Persona), p.Id);

Console.WriteLine("p2 - Id: " + p2.Id);
Console.WriteLine("p2 - Nombre: " + p2.Nombre);
Console.WriteLine("p2 - Apellido: " + p2.Apellido);
Console.WriteLine();

/* Verifico si son el mismo objeto p y p2, ya que estamos
* dentro de la misma sesión */

if (p == p2)
Console.WriteLine("p y p2 son el mismo objeto");

p2.Apellido = "Paduán";

s.Flush();

s.Close();
}
}
}

En el proyecto agregué estas referencias:

  • NHibernate.dll
  • System

Ahora vamos a lo que nos interesa. En el archivo app.config (que al compilar se traducirá a .exe.config en el directorio de salida), observemos estas lineas:


key="hibernate.connection.driver_class"
value="PruebaNHibernate.MonoDataSqliteDriver, PruebaNHibernate"
/>

NHibernate trae un driver para SQLite, como dije al principio, pero que utiliza un provider que fue discontinuado. Por lo tanto, para utilizar Mono.Data.Sqlite, cree una clase en mi assembly (PruebaNHibernate) con el nombre que se indica allí (MonoDataSqliteDriver):

using System;
using NHibernate.Driver;

namespace PruebaNHibernate
{
public class MonoDataSqliteDriver : ReflectionBasedDriver
{
public MonoDataSqliteDriver()
: base("Mono.Data.Sqlite",
"Mono.Data.Sqlite.SqliteConnection",
"Mono.Data.Sqlite.SqliteCommand")
{
}

public override bool UseNamedPrefixInSql
{
get { return true; }
}

public override bool UseNamedPrefixInParameter
{
get { return true; }
}

public override string NamedPrefix
{
get { return "@"; }
}

public override bool SupportsMultipleOpenReaders
{
get { return false; }
}
}
}

En el constructor de la misma le paso a mi clase padre los argumentos que necesita: nombre del assembly (en este caso “Mono.Data.Sqlite”), clase para crear la conexión y ejecutar comandos. Desconozco los detalles de SQLite, así que copié los métodos sobreescritos del driver viejo.

No pude hacer que NHibernate cargue el assembly “Mono.Data.Sqlite” desde el GAC, así que hay que copiarlo al directorio del ejecutable. Es necesario copiar otros archivos, como las dependencias de NHibernate y la base de datos (data.db). Se pueden bajar el proyecto completo para MonoDevelop aquí. El archivo obviamente no es un png, pero sino no lo puedo subir :)

Ahora bien, hay un problemita… el archivo System.Data.dll que viene con Mono 1.2.4 en Gutsy tiene un bug que hará que el ejemplo no funcione. El mismo ya fue solucionado en la versión 1.2.6. Así que, como workaround, pueden bajarse el paquete de Debian libmono-system-data2.0-cil correspondiente a la versión 1.2.6 de Mono y sobreeescribir ese archivo, que se ubica en /usr/lib/mono/gac/System.Data/2.0.0.0__b77a5c561934e089/. Reporté el problema en Ubuntu, así que quizá lo actualicen dentro de poco.

Con esto podremos utilizar SQLite con NHibernate, bajo Mono, con un binding actualizado.

Autor : Milton Pividori

FUENTE DEL ARTICULO : http://www.miltonpividori.com.ar/2007/12/30/mono-nhibernate-sqlite/


SQLite y Gambas2

domingo, 2 de noviembre de 2008

Gambas es otro de los tantos hacks recursivos que se usan, en si el significado es "Gambas Almost Means Basic", pensado como herramienta RAD y con Basic como lenguaje base, pero mejorado, vemos que tambien es multiprosito, en esta ocasión vamos a ver como hacer una conexión a una base de datos SQLite desde Gambas2.

Lo primero que debemos tener disponible para trabajar, ademas de SQLite, es Gambas2, en Debian y derivados:

#apt-get install gambas2

para otras distros podemos encontrar las fuentes en http://gambas.sourceforge.net/
la parte mas importante esta en saber cuales son las herramientas que nos provee el languaje, y los datos de conexión de almacenan en un solo botón, el codigo es el siguiente:

'Instanciamos un objeto de clase Connection
PRIVATE $hConn AS Connection

'Boton de conexión a la base de datos
PUBLIC SUB btnC
onnect_Click()

DIM sName AS String
DIM hTable AS Table

TRY $hConn.Close



sName = txtName.Text

IF sName <> "" THEN

'Asignamos valores a las pr
opiedades que vamos a usar
WITH $hConn

'Definimos el tipo de base de datos
.Type = "sqlite"


'Definimos el nombre del host
.Host = txtHost.Text

END WITH


'Asignamos el nombre de la conexion
$hConn.Name = sName

'Abrimos la
conexion para poder trabajar
$hConn.Open

'Habilitamos los otros formularios
frmDatabase.Enabled = TRUE
frmRequest.Enabled = TRUE

btnConnect.Enabled = FALSE
btnClose.Enabled
= TRUE
CATCH

Message.Error(DConv(Error.Text))
ENDIF

END
A continuación capturas de la aplicacion terminada y en diseño.



Antes de terminar debo aclarar que la base de datos debe estar creada, en caso contrario no se realiza la conexión, ademas se debe dar la ruta completa de la ubicación del archivo que contiene dicha base de datos. La aplicación completa para su descarga en el siquiente link:
Descarga