SQLite
 sql >> Database >  >> RDS >> SQLite

Quanto sono flessibili/restrittivi i tipi di colonna SQLite?

I tipi di colonne SQLite sono flessibili (dinamici), in primo luogo sembra soddisfare l'adozione/adattamento di tipi di colonne rigidi utilizzati da altri sistemi di gestione di database.

Nota! questo Asnwer NON sta raccomandando l'uso di tipi di colonne strani e meravigliosi.

1) Puoi effettivamente utilizzare praticamente qualsiasi nome per un tipo di colonna, tuttavia ci sono alcune limitazioni.

2) Il tipo di colonna è il 2° valore nella definizione della colonna, ad es. CREATE TABLE table (columnname columntype .....,....) , sebbene possa essere omesso intenzionalmente o forse inavvertitamente Nota, vedi 5a)

3) La prima limitazione è che mycolumn INTEGER PRIMARY KEY o mycolumn INTEGER PRIMARY KEY AUTOINCREMENT è un tipo di colonna speciale. La colonna è un alias per il rowid che è un identificatore numerico univoco (AUTOINCREMENT impone una regola che il rowid deve essere maggiore dell'ultimo rowid utilizzato per la tabella, ad es. se una riga utilizza l'id (9223372036854775807), qualsiasi tentativo successivo di aggiungere una riga risulterà in un errore SQLITE FULL. ). Incremento automatico di SQLite

4) Altre limitazioni sono che il tipo di colonna non deve confondere il parser SQLite. Ad esempio, un tipo di colonna PRIMARY, TABLE, INDEX risulterà in un'eccezione SQLite (errore di sintassi (codice 1) ) per esempio. quando viene utilizzato un tipo di colonna di INDEX, allora:-

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

si verifica.

5) Un tipo di colonna non è obbligatorio, ad esempio CREATE TABLE mytable (...,PRIMARY_COL,.... nel qual caso un PRAGMA TABLE_INFO(tablename) non mostrerà alcun tipo ad es. (3a riga).

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) In alcuni casi il parser SQLite salterà a KEYWORDS valide, ad es. CREATE TABLE mytable (mycolumn NOT NULL,... risulta in NOT NULL utilizzato per indicare un NOT NULL colonna e il tipo essendo considerato nessun tipo (la table_info sopra era effettivamente da un tale utilizzo).

6) Un tipo non è limitato a una singola parola, ad es. VARYING CHARACTER(255) o THE BIG BAD WOLF può essere specificato come tipo come si può vedere da questo estratto table_info :-

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

Il motivo per utilizzare tipi di colonne non standard in SQLite!

In breve non c'è non motivo per cui, come affermato in un primo momento, la flessibilità dei tipi di colonna sembra essere principalmente per soddisfare il facile adattamento di SQL da altri sistemi di gestione di database.

I tipi di colonna stessi hanno scarso effetto poiché i dati verranno archiviati in base a ciò che SQLite determina come classe di archiviazione da utilizzare. Ad eccezione di rowid (vedi 3) sopra) qualsiasi colonna può contenere valori di qualsiasi tipo.

Ad eccezione dei dati archiviati come Blob, che devono essere recuperati utilizzando il cursor.getBlob e che cursor.getBlob non può essere utilizzato per i dati non archiviati come BLOB (getBlob non fallisce con i dati archiviati come TEXT), puoi recuperare molti dati (non necessariamente tutti utili) usando uno qualsiasi dei cursor.get???? metodi.

Ecco alcuni esempi:-

Per una colonna in cui i dati long myINT = 556677888; viene aggiunto (tramite ContentValues ​​es. cv1.put(columnanme,myINT) );

Allora :-

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 non ritorna al valore memorizzato, getBlob non può ottenere il valore memorizzato.

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

Ed ecco un esempio piuttosto ridicolo con un tipo di colonna di my_char_is_not_a_char_but_an_int come da 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

I risultati (memorizzati come in "Doppio" sopra) sono:-

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.

Quanto sopra si basava su quanto segue:-Tipi di dati in SQLite versione 3 SQLite Autoincrement PRAGMA Statements

Il codice è stato testato/eseguito su un dispositivo emulato GenyMotion che esegue API22 compilato con una versione minima di 14 e una destinazione di 26.