61 - Tipos de datos dinámicos en la definición de campos en SQLite

La mayoría de los motores de base de datos (SQLServer, MySQL, PostgreSQL, Oracle etc.) usan tipos de datos estáticos cuando definimos un campo de una tabla. Con el tipado estático es obligatorio especificar el tipo de dato del campo.

SQLite usa un sistema de tipo dinámico más general. En SQLite, el tipo de datos de un valor está asociado con el valor en sí mismo, no con su contenedor. El sistema de tipo dinámico de SQLite es retrocompatible con los sistemas de tipo estático más comunes de otros motores de base de datos en el sentido de que las sentencias de SQL que funcionan en bases de datos tipadas estáticamente deberían funcionar de la misma manera en SQLite. Sin embargo, el tipado dinámico en SQLite le permite hacer cosas que no son posibles en las bases de datos tradicionalmente rígidas.

Veamos como podemos definir campos de una tabla en SQLite sin indicar su tipo y luego guardar distintos tipos de datos en distintas filas.

Borramos la tabla "tabla1" si existe:

drop table if exists tabla1;

Creamos la tabla con la siguiente estructura:

create table tabla1(
	codigo integer primary key,
	campo1
);

Definimos una tabla llamada "tabla1" con 2 campos. Lo más importante hacer notar que el segundo campo llamado "campo1" no tiene indicado el tipo de dato.

La característica fundamental de SQLite que podemos guardar cualquier tipo de dato en "campo1", por ejemplo si insertamos estas filas:

insert into tabla1(campo1) values (1);
insert into tabla1(campo1) values (5.25);
insert into tabla1(campo1) values ('admin');
insert into tabla1(campo1) values (null);

Guardamos en "campo1" en el primer insert un valor "integer", en el segundo un "real", en el tercero un "text" y finalmente en la cuarta un "NULL".

Podemos emplear la función typeof de SQLite para averiguar que tipo de dato almacena una determinada celda de la tabla:

select codigo, campo1, typeof(campo1) from tabla1;

Tipado dinámico de SQLite

Campos que especifican el tipo de dato.

En SQLite lo más común es definir que tipo de dato se almacena en cada campo, pero inclusive si definimos su tipo podemos almacenar cualquier tipo de dato: integer, real, text, blob o null.

Borramos la tabla "personas" si existe:

drop table if exists personas;

Creamos la tabla "personas" con la siguiente estructura:

create table personas (
	nombre text,
	canthijos integer
);

Almacenamos una serie de filas en la tabla "personas":

insert into personas(nombre,canthijos) values('juan',2);
insert into personas(nombre,canthijos) values('ana',7);
insert into personas(nombre,canthijos) values('luis','no tiene');

Podemos observar que almacenamos en el campo "canthijos" en las dos primeras filas valores de tipo 'integer', pero en la tercer fila almacenamos un valor de tipo 'text'. No se genera un error debido a que SQLite utiliza un tipado dinámico inclusive aunque definamos dicho campo de tipo 'integer'.

Recuperemos todas las filas de la tabla:

select nombre, canthijos from personas;

Tipado dinámico de SQLite

Luego hay que tener en cuenta que hay funciones que solo son afectadas según el tipo de dato almacenado, por ejemplo si necesitamos sumar la cantidad de hijos de todas las personas:

select sum(canthijos) from personas;

El resultado es 9 y no se genera un error aunque haya una fila que tiene en dicho campo el valor 'no tiene'.

El tipado dinámico en los campos de una tabla es una característica propia de SQLite que no existe en otros gestores de base de datos.

Excepción de tipado dinámico en los campos 'integer primary key'

Hay una excepción en el tipado dinámico en SQLite para cuando definimos un campo de tipo 'integer' y lo definimos 'primary key'.

Borramos la tabla "articulos" si existe:

drop table if exists articulos;

Creamos la tabla "articulos" con la siguiente estructura:

create table articulos(
	codigo integer primary key,
	descripcion text,
	precio real
);

Intentamos almacenar un valor distinto a 'integer' en el campo codigo:

insert into articulos(codigo, descripcion, precio) values ('hola', 'papas', 12.5);

Se genera un error debido a que solo se permiten valores de tipo integer para los campos 'integer primary key':

Tipado estático integer primary key de SQLite