SQLite
 sql >> Datenbank >  >> RDS >> SQLite

Wie flexibel/restriktiv sind SQLite-Spaltentypen?

SQLite-Spaltentypen sind flexibel (dynamisch), in erster Linie scheinen sie für die Annahme/Anpassung starrer Spaltentypen zu sorgen, die von anderen Datenbankverwaltungssystemen verwendet werden.

Hinweis! Diese Antwort empfiehlt NICHT die Verwendung von seltsamen und wunderbaren Spaltentypen.

1) Sie können praktisch jeden Namen für einen Spaltentyp verwenden, es gibt jedoch einige Einschränkungen.

2) Spaltentyp ist der 2. Wert in der Spaltendefinition z.B. CREATE TABLE table (Spaltenname Spaltentyp .....,....) , obwohl es absichtlich oder vielleicht versehentlich weggelassen werden kann Hinweis siehe 5a)

3) Die erste Einschränkung ist, dass mycolumn Ganzzahliger Primärschlüssel oder mycolumn INTEGER PRIMARY KEY AUTOINCREMENT ist ein spezieller Spaltentyp. Die Spalte ist ein Alias ​​für die rowid Dies ist eine eindeutige numerische Kennung (AUTOINCREMENT erlegt eine Regel auf, dass die rowid muss größer als die zuletzt verwendete Rowid für die Tabelle sein, z. Wenn eine Zeile die ID (9223372036854775807) verwendet, führen alle nachfolgenden Versuche, eine Zeile hinzuzufügen, zu einem SQLITE FULL-Fehler. ). SQLite Autoinkrement

4) Weitere Einschränkungen bestehen darin, dass der Spaltentyp den SQLite-Parser nicht verwirren darf. Beispielsweise führt ein Spaltentyp von PRIMARY, TABLE, INDEX zu einer SQLite-Ausnahme (Syntaxfehler (Code 1) ) z.B. wenn ein Spaltentyp von INDEX verwendet wird, dann:-

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

auftritt.

5) Ein Spaltentyp ist nicht obligatorisch, zum Beispiel CREATE TABLE mytable (...,PRIMARY_COL,.... in diesem Fall ein PRAGMA TABLE_INFO(tablename) zeigt keinen Typ an, z. (3. Zeile).

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 einigen Fällen springt der SQLite-Parser zu gültigen SCHLÜSSELWÖRTERN, z. CREATE TABLE meinetabelle (meinespalte NICHT NULL,... ergibt NOT NULL verwendet, um ein NOT NULL anzuzeigen Spalte und den Typ als kein Typ angenommen (Die obige table_info stammt tatsächlich von einer solchen Verwendung).

6) Ein Typ ist nicht auf ein einzelnes Wort beschränkt, z. VARYING CHARACTER(255) oder THE BIG BAD WOLF kann als Typ angegeben werden, wie aus diesem table_info-Extrakt ersichtlich ist:-

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

Der Grund für die Verwendung von Nicht-Standard-Spaltentypen in SQLite!

Kurz gesagt, es gibt nein Aus diesem Grund scheint die Flexibilität von Spaltentypen, wie eingangs erwähnt, in erster Linie der einfachen Adaption von SQL von anderen Datenbankverwaltungssystemen zu dienen.

Spaltentypen selbst haben nur geringe Auswirkungen, da Daten entsprechend der von SQLite als zu verwendende Speicherklasse festgelegten Speicherklasse gespeichert werden. Mit Ausnahme von rowid (siehe 3) oben) kann jede Spalte Werte jeden Typs enthalten.

Mit Ausnahme der als Blob gespeicherten Daten, die mit cursor.getBlob abgerufen werden müssen und dass cursor.getBlob nicht für Daten verwendet werden kann, die nicht als BLOB gespeichert sind (getBlob schlägt nicht fehl, wenn Daten als TEXT gespeichert sind). .get???? Methoden.

Hier sind einige Beispiele:-

Für eine Spalte mit den Daten long myINT =556677888; hinzugefügt (über ContentValues ​​z. B. cv1.put(columnanme,myINT) );

Dann :-

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 kehrt nicht zum gespeicherten Wert zurück, getBlob kann den gespeicherten Wert nicht abrufen.

Für 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.

Für String myTEXT ="Der faule schnelle braune Fuchs sprang über den Zaun oder so etwas.";

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

Und hier ist ein ziemlich lächerliches Beispiel mit einem Spaltentyp von my_char_is_not_a_char_but_an_int gemäß 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

Ergebnisse (gespeichert wie oben bei 'Double') sind:-

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.

Das Obige basierte auf Folgendem:-Datentypen in SQLite Version 3 SQLite Autoincrement PRAGMA Statements

Der Code wurde auf einem emulierten GenyMotion-Gerät getestet/ausgeführt, auf dem API22 ausgeführt wird, das mit einer Mindestversion von 14 und einem Ziel von 26 kompiliert wurde.