miércoles, 11 de junio de 2014

¿Qué día me dijiste que teníamos la reunión? (Manejo de fechas en SQLite3)

Como dicen en la propia documentación de SQLite, en SQLite3 no existe el tipo de datos fecha.

Cito directamente de http://www.sqlite.org/datatype3.html


1.2 Date and Time Datatype

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

    TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
    REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
    INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.

Así que lo más conveniente es declarar el tipo de ese campo como TEXT (o números, también vale), almacenar las fechas en el formato ISO8601 (básicamente: 'YYYY-MM-DD HH:MM:SS'), así además se puede ordenar por ese campo simplemente ordenando como texto, y utilizar las funciones de fecha de SQLite3 para procesarlas.

Por ejemplo, para hacer una comparación:

 1 select * from tabla where julianday(f1) > julianday('2014-01-01 00:00:00')


 

UN EJEMPLO PRÁCTICO


Bien, hasta aquí la teoría. Vamos a probarlo. Para ello, voy a utilizar SQLite Expert Personal, donde he creado una base de datos y dentro de ella crearé una tabla con un campo fecha.

1. Creamos la tabla

 1 CREATE TABLE PERSONAS
 2 (
 3   ID         NUMBER(10)  NOT NULL,
 4   NOMBRE     VARCHAR(30),
 5   APE1       VARCHAR(30),
 6   APE2       VARCHAR(30),
 7   FNACIM     DATETEXT  
 8 );

El tipo de dato DATETEXT (línea 7) se corresponde internamente en SQLite Expert con WideString, pero en realidad debería valer cualquier tipo de datos de texto.

2. Insertamos unos cuantos datos de ejemplo

 1 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (1, 'MARIANO', 'RAJOY', 'ZAPATERO', '1965-05-20');
 2 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (2, 'JOSE LUIS', 'RAJOY', 'ZAPATERO', '1970-06-20');
 3 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (3, 'PETER', 'SCHWARZENEGGER', NULL, '1973-08-30');
 4 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (4, 'ARNOLD', 'LANDA', 'CLARK', '1982-08-30');

Antes de consultar nada, comprobamos que los datos se han insertado bien, yéndonos a la pestaña "Data" de SQLite Expert
Fig. 1. Los datos. Cuántos conocidos por aquí.


3. Hacemos una consulta 

En ésta, utilizamos la función "julianday" para comparar fechas

 1 SELECT * FROM PERSONAS WHERE julianday(FNACIM) > julianday('1970-07-01')


El resultado:
Fig. 2. Resultado de la consulta. Los más jovencitos del grupo


Bueno, parece que todo ha ido bien.

Además de juliandate, SQLite incorpora otras cuatro funciones para trabajar con fechas: date, time, datetime y strftime. Os recomiendo la lectura de la página donde se describen (enlace al final).

Una vez que se sabe esta forma de trabajar con las fechas en SQLite3, la cuestión parece una tontería, pero el hecho de que SQLite no tuviera un tipo de dato nativo para las fechas me ha hecho perder un buen rato. Espero que no le pase a quien lea esto.

¿Y tú, te has peleado con fechas en SQLite?

Más info:

SQLite. http://www.sqlite.org/

Funciones de fecha en SQLite. http://www.sqlite.org/lang_datefunc.html

SQLite Expert Personal. Un estupendo gestor de bases de datos SQLite. http://www.sqliteexpert.com/download.html

No hay comentarios:

Publicar un comentario