SQLite 列类型是灵活的(动态的),主要是为了迎合其他数据库管理系统使用的刚性列类型的采用/适应。
注意!这个 Asnwer 不推荐使用奇怪而美妙的列类型。
1) 实际上,您几乎可以为列类型使用任何名称,但是存在一些限制。
2) 列类型是列定义中的第二个值,例如CREATE TABLE table (columnname columntype .....,....),尽管它可能会被有意或无意地省略 注意见 5a)
3) 第一个限制是mycolumnINTEGER PRIMARY KEY 或mycolumnINTEGER PRIMARY KEY AUTOINCREMENT 是一种特殊的列类型。该列是 rowid 的别名,它是唯一的数字标识符(AUTOINCREMENT 强制规定 rowid 必须大于上次使用的表的 rowid 例如,如果一行使用 id (9223372036854775807),那么任何后续添加行的尝试都将导致 SQLITE FULL 错误。)。 SQLite Autoincrement
4) 其他限制是列类型不能混淆 SQLite 解析器。例如,PRIMARY、TABLE、INDEX 列类型将导致 SQLite 异常(语法错误(代码 1)),例如当使用 INDEX 列类型时:-
android.database.sqlite.SQLiteException: near "INDEX": syntax error (code 1):
发生。
5) 列类型不是强制性的,例如 CREATE TABLE mytable (...,PRIMARY_COL,.... 在这种情况下 PRAGMA TABLE_INFO(tablename) 将不显示任何类型,例如(第 3 行)。
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) 在某些情况下,SQLite 解析器会跳到有效的关键字,例如CREATE TABLE mytable (mycolumn NOT NULL,... 导致 NOT NULL 被用来表示 NOT NULL 列,而 type 被视为 no type (上面的 table_info 实际上来自这样的用法) .
6) 类型不限于单个单词,例如VARYING CHARACTER(255) 或 THE BIG BAD WOLF 可以指定为从 table_info 提取中可以看出的类型:-
08-08 08:23:26.423 4799-4799/? D/ TBLINFO: Col=type Value=THE BIG BAD WOLF
在 SQLite 中使用非标准列类型的原因!
简而言之,没有原因,正如开头所述,列类型的灵活性似乎主要是为了迎合从其他数据库管理系统轻松适应 SQL。
列类型本身几乎没有影响,因为数据将根据 SQLite 确定的要使用的存储类进行存储。除了rowid(参见上面的3))任何列都可以保存任何类型的值。
除了存储为 Blob 的数据,必须使用 cursor.getBlob 检索,并且 cursor.getBlob 不能用于未存储为 BLOB 的数据(getBlob 不会因为存储为 TEXT 的数据而失败),您可以使用任何cursor.get???? 方法非常多地检索数据(不一定有用)。
这里有一些例子:-
对于添加了数据 long myINT = 556677888; 的列(通过 ContentValues,例如 cv1.put(columnanme,myINT));
然后:-
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 不返回存储值,getBlob 无法获取存储值。
对于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.
对于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 >>[B@2f9e811e<<
这是一个非常荒谬的例子,列类型为my_char_is_not_a_char_but_an_int,根据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
结果(按上面的“双”存储)是:-
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.
以上内容基于以下几点:-
Datatypes In SQLite Version 3
SQLite Autoincrement
PRAGMA Statements
代码在运行 API22 的 GenyMotion 模拟设备上测试/运行,最低版本为 14,目标为 26。