sql >> Base de Datos >  >> RDS >> SQLite

¿Qué tan flexibles/restrictivos son los tipos de columna de SQLite?

Los tipos de columnas de SQLite son flexibles (dinámicos), principalmente, parecen atender la adopción/adaptación de tipos de columnas rígidos utilizados por otros sistemas de administración de bases de datos.

¡Nota! esta respuesta NO recomienda el uso de tipos de columnas extraños y maravillosos.

1) En realidad, puede usar prácticamente cualquier nombre para un tipo de columna; sin embargo, existen algunas limitaciones.

2) El tipo de columna es el segundo valor en la definición de la columna, p. CREATE TABLE table (columnname columntype .....,....) , aunque puede omitirse intencionalmente o quizás sin darse cuenta Nota ver 5a)

3) La primera limitación es que mycolumn INTEGER PRIMARY KEY o mycolumn INTEGER PRIMARY KEY AUTOINCREMENT es un tipo de columna especial. La columna es un alias para rowid que es un identificador numérico único (AUTOINCREMENT impone una regla que el rowid debe ser mayor que el último ID de fila utilizado para la tabla, p. si una fila usa id (9223372036854775807), cualquier intento posterior de agregar una fila generará un error SQLITE FULL. ). Incremento automático de SQLite

4) Otras limitaciones son que el tipo de columna no debe confundir al analizador de SQLite. Por ejemplo, un tipo de columna PRIMARY, TABLE, INDEX generará una excepción de SQLite (error de sintaxis (código 1) ) p.ej. cuando se usa un tipo de columna de ÍNDICE entonces:-

android.database.sqlite.SQLiteException: near "INDEX": syntax error (code 1):

ocurre.

5) Un tipo de columna no es obligatorio, por ejemplo CREATE TABLE mytable (...,PRIMARY_COL,.... en cuyo caso un PRAGMA TABLE_INFO(tablename) no mostrará ningún tipo, p. (3ra Línea).

08-08 07:56:23.391 13097-13097/? D/TBL_INFO: Col=cid Value=8
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=name Value=PRIMARY_COL
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=type Value=
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=notnull Value=1
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=dflt_value Value=null
08-08 07:56:23.391 13097-13097/? D/ TBLINFO: Col=pk Value=0

5a) En algunos casos, SQLite Parser saltará a PALABRAS CLAVE válidas, p. CREATE TABLE mytable (mycolumn NOT NULL,... da como resultado NOT NULL siendo usado para indicar un NOT NULL columna y el tipo siendo tomado como ningún tipo (la table_info anterior fue en realidad de tal uso).

6) Un tipo no se limita a una sola palabra, p. VARYING CHARACTER(255) o THE BIG BAD WOLF se puede especificar como un tipo como se puede ver en este extracto de table_info :-

08-08 08:23:26.423 4799-4799/? D/   TBLINFO: Col=type Value=THE BIG BAD WOLF

¡La razón para usar tipos de columnas no estándar en SQLite!

En resumen, no Por esta razón, como se indicó al principio, la flexibilidad de los tipos de columnas parece ser principalmente para facilitar la adaptación de SQL desde otros sistemas de administración de bases de datos.

Los tipos de columna en sí mismos tienen poco efecto, ya que los datos se almacenarán de acuerdo con lo que SQLite determine como la clase de almacenamiento que se utilizará. Con la excepción de rowid (ver 3) arriba) cualquier columna puede contener valores de cualquier tipo.

Con la excepción de los datos almacenados como Blob, que deben recuperarse utilizando el cursor.getBlob y que cursor.getBlob no se puede usar para datos no almacenados como BLOB (getBlob no falla con datos almacenados como TEXTO), puede recuperar datos en gran medida (aunque no sea necesariamente útil) usando cualquiera de los cursores cursor.get???? métodos.

Aquí hay algunos ejemplos:-

Para una columna donde los datos long myINT = 556677888; se agrega (a través de ContentValues, por ejemplo, cv1.put(columnanme,myINT) );

Entonces:-

08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: Column=INTEGER_COL<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS INT >>556677888<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS LONG >>556677888<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS STRING >>556677888<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS DOUBLE >>5.56677888E8<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS FLOAT >>5.566779E8<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS SHORT >>15104<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:      Unable to handle with getBlob.

getShort no regresa al valor almacenado, getBlob no puede obtener el valor almacenado.

Para Double myREAL = 213456789.4528791134567890109643534276; :-

08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes: Column=REAL_COL<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS INT >>213456789<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS LONG >>213456789<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS STRING >>2.13457e+08<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS DOUBLE >>2.134567894528791E8<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS FLOAT >>2.1345678E8<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS SHORT >>6037<<
08-08 09:19:03.658 13575-13575/mjt.soqanda D/ColTypes:      Unable to handle with getBlob.

For String myTEXT = "The Lazy Quick Brown Fox Jumped Over the Fence or something like that.";

08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes: Column=TEXT_COL<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS INT >>0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS LONG >>0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS STRING >>The Lazy Quick Brown Fox Jumped Over the Fence or something like that.<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS DOUBLE >>0.0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS FLOAT >>0.0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS SHORT >>0<<
08-08 09:19:03.657 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS BLOB >>[[email protected]<<

Y aquí hay un ejemplo bastante ridículo con un tipo de columna de my_char_is_not_a_char_but_an_int según PRAGMA TABLE_INFO :-

08-08 09:19:03.657 13575-13575/mjt.soqanda D/TBL_INFO: Col=cid Value=7
08-08 09:19:03.657 13575-13575/mjt.soqanda D/   TBLINFO: Col=name Value=my_char_is_not_a_char_but_an_int_COL
08-08 09:19:03.657 13575-13575/mjt.soqanda D/   TBLINFO: Col=type Value=my_char_is_not_a_char_but_an_int
08-08 09:19:03.657 13575-13575/mjt.soqanda D/   TBLINFO: Col=notnull Value=0
08-08 09:19:03.657 13575-13575/mjt.soqanda D/   TBLINFO: Col=dflt_value Value=null
08-08 09:19:03.657 13575-13575/mjt.soqanda D/   TBLINFO: Col=pk Value=0

Los resultados (almacenados según 'Doble' arriba) son:-

08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes: Column=my_char_is_not_a_char_but_an_int_COL<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS INT >>213456789<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS LONG >>213456789<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS STRING >>2.13457e+08<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS DOUBLE >>2.134567894528791E8<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS FLOAT >>2.1345678E8<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:  VALUE AS SHORT >>6037<<
08-08 09:19:03.659 13575-13575/mjt.soqanda D/ColTypes:      Unable to handle with getBlob.

Lo anterior se basó en lo siguiente:- Tipos de datos en SQLite Versión 3 SQLite Autoincrementar declaraciones PRAGMA

El código se probó/ejecutó en un dispositivo emulado de GenyMotion que ejecuta API22 compilado con una versión mínima de 14 y un objetivo de 26.