SQLite
 sql >> Base de données >  >> RDS >> SQLite

Dans quelle mesure les types de colonnes SQLite sont-ils flexibles/restrictifs ?

Les types de colonnes SQLite sont flexibles (dynamiques), principalement, il semble répondre à l'adoption/adaptation des types de colonnes rigides utilisés par d'autres systèmes de gestion de base de données.

Remarque ! cette réponse ne recommande PAS l'utilisation de types de colonnes étranges et merveilleux.

1) Vous pouvez en fait utiliser pratiquement n'importe quel nom pour un type de colonne, il existe cependant certaines limitations.

2) Le type de colonne est la 2e valeur dans la définition de colonne, par ex. CREATE TABLE table (columnname columntype .....,....) , bien qu'il puisse être omis intentionnellement ou peut-être par inadvertance Note voir 5a)

3) La première limitation est que mycolumn INTEGER PRIMARY KEY ou mycolumn INTEGER PRIMARY KEY AUTOINCREMENT est un type de colonne spécial. La colonne est un alias pour le rowid qui est un identifiant numérique unique (AUTOINCREMENT impose une règle selon laquelle le rowid doit être supérieur au dernier rowid utilisé pour la table, par ex. si une ligne utilise l'identifiant (9223372036854775807), toute tentative ultérieure d'ajout d'une ligne entraînera une erreur SQLITE FULL. ). Auto-incrémentation SQLite

4) D'autres limitations sont que le type de colonne ne doit pas confondre l'analyseur SQLite. Par exemple, un type de colonne PRIMARY, TABLE, INDEX entraînera une exception SQLite (erreur de syntaxe (code 1) ) par exemple. lorsqu'un type de colonne INDEX est utilisé alors :-

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

se produit.

5) Un type de colonne n'est pas obligatoire, par exemple CREATE TABLE mytable (...,PRIMARY_COL,.... auquel cas un PRAGMA TABLE_INFO(tablename) n'affichera aucun type, par ex. (3ème ligne).

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) Dans certains cas, l'analyseur SQLite passera aux mots clés valides, par ex. CREATE TABLE mytable (mycolumn NOT NULL,... donne NOT NULL utilisé pour indiquer un NOT NULL colonne et le type étant considéré comme aucun type (le table_info ci-dessus provenait en fait d'un tel usage).

6) Un type n'est pas limité à un seul mot, par ex. VARYING CHARACTER(255) ou THE BIG BAD WOLF peut être spécifié comme un type comme on peut le voir à partir de cet extrait table_info :-

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

La raison d'utiliser des types de colonnes non standard dans SQLite !

Bref il n'y a non raison, comme indiqué au début, la flexibilité des types de colonnes semble être principalement pour répondre à l'adaptation facile de SQL à partir d'autres systèmes de gestion de base de données.

Les types de colonnes eux-mêmes ont peu d'effet car les données seront stockées en fonction de ce que SQLite détermine comme classe de stockage à utiliser. À l'exception de rowid (voir 3) ci-dessus) n'importe quelle colonne peut contenir des valeurs de n'importe quel type.

À l'exception des données stockées sous forme de Blob, qui doivent être récupérées à l'aide du cursor.getBlob et que le curseur.getBlob ne peut pas être utilisé pour les données non stockées en tant que BLOB (getBlob n'échoue pas avec les données stockées en tant que TEXT), vous pouvez très bien récupérer des données (toutes ne sont pas nécessairement utiles) en utilisant n'importe lequel des curseurs cursor.get???? méthodes.

Voici quelques exemples :-

Pour une colonne où les données long myINT = 556677888; est ajouté (via ContentValues, par exemple cv1.put(columnanme,myINT) );

Alors :-

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 ne retourne pas à la valeur stockée, getBlob ne peut pas obtenir la valeur stockée.

Pour 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.

Pour 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]<<

Et voici un exemple assez ridicule avec un type de colonne de my_char_is_not_a_char_but_an_int selon 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

Les résultats (stockés selon 'Double' ci-dessus) sont :-

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.

Ce qui précède était basé sur les éléments suivants :- Types de données dans les instructions PRAGMA d'auto-incrémentation SQLite version 3 SQLite

Le code a été testé/exécuté sur un appareil émulé GenyMotion exécutant API22 compilé avec une version minimale de 14 et une cible de 26.