0%

Sqlite问题小结

最近为了学习用了一下sqlite,开始就碰上了最棘手的问题,乱码、版本不兼容等。查了些资料,自己终于想办法解决了。

之前没有接触过sqlite,只是知道在嵌入式方面用的颇广,这次也算学习一下。

一、 版本兼容问题

首先是版本兼容的问题,刚拿到的是个sqlite2数据库,而我的arch上都是sqlite3的各种包,sqlite3 pinyin.db自然失败。好吧,把sqlite2的各种包装上。

sudo yaourt -Ss sqlite|grep installed
core/sqlite3 3.7.10-1 [installed]
core/sqlite3-doc 3.7.10-1 [installed]
community/gambas2-gb-db-sqlite2 2.23.1-8 (gambas2) [installed]
community/gambas3-gb-db-sqlite2 3.0.0-5 (gambas3) [installed]
community/libgda3 3.1.5-11 [installed]
community/sqlite2 2.8.17-5 [installed]
community/sqlitebrowser 2.0b1-2 [installed]
community/sqliteman 1.2.2-5 [installed]
community/sqlitemanager 1.2.4-2 [installed]

好了 尝试打开数据库:

sqlite pinyin.db
SQLite version 2.8.17
Enter ".help" for instructions
sqlite> .tables
acs_active        firereport        lapes_list        netconfig
acs_key_active    firereport_his    list_dev          pinyin
acssub            floor             logic_detail      sys
carddev           gz_type           logic_fixtimerun  timelist
cardmain          gz_view           logic_list        userinfo
devname           id100             logic_main        usertip
devtype           language          logic_out
sqlite>

OK,顺利打开。

不过我想采用GUI的方式查看数据库,我已经安装了sqliteman与sqlitebroswer,但是他们全是支持sqlite3的,好吧,需要把sqlite2的数据库转化为sqlite3的。

sqlite有个.dump命令,十分好用,先看下帮助:

sqlite
SQLite version 2.8.17
Enter ".help" for instructions
sqlite> .help
.databases             List names and files of attached databases
.dump ?TABLE? ...      Dump the database in a text format
.echo ON|OFF           Turn command echo on or off
.exit                  Exit this program
.explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.
.header(s) ON|OFF      Turn display of headers on or off
.help                  Show this message
.indices TABLE         Show names of all indices on TABLE
.mode MODE             Set mode to one of "line(s)", "column(s)",
                       "insert", "list", or "html"
.mode insert TABLE     Generate SQL insert statements for TABLE
.nullvalue STRING      Print STRING instead of nothing for NULL data
.output FILENAME       Send output to FILENAME
.output stdout         Send output to the screen
.prompt MAIN CONTINUE  Replace the standard prompts
.quit                  Exit this program
.read FILENAME         Execute SQL in FILENAME
.schema ?TABLE?        Show the CREATE statements
.separator STRING      Change separator string for "list" mode
.show                  Show the current values for various settings
.tables ?PATTERN?      List names of tables matching a pattern
.timeout MS            Try opening locked tables for MS milliseconds
.width NUM NUM ...     Set column widths for "column" mode
sqlite>

.dump 将数据库转换为文本格式保存,我理解是保存为sql,稍后会发现这个.dump确实太有用了。

使用下面的命令实现sqlite2与sqlite3间的装换:

sqlite pinyin.db .dump|sqlite3 pinyin.db3;file pinyin*
pinyin.db:  SQLite 2.x database
pinyin.db3: SQLite 3.x database

接下来使用sqliteman或者sqlitebroswer就能顺利打开pinyin.db3了。

二、UTF-8与GBK间的乱码问题

——————————————————————————————————————————————————

首先需要明确的是sqlite默认采用UTF-8编码;

Sqlite管理器类的工具不论平台当然使用的文本编码也是UTF8;

Windows中AAuto默认编码是ANSI(不是UTF8,而是GBK);

windows下AAuto标准库里的sqlite库中的sqlite类对象会自动转换编码(UTF8->ANSI或ANSI->UTF8),使用UTF8编码写入sqlite数据库,再将读取的UTF8转换为ANSI编码.而直接用sqlite库的原始API,不会自动进行编码转换,需要自已调用string.fromto()函数转换.

在archlinux下xterm默认用的是UTF-8编码.

——————————————————————————————————————————————————

我数据库是从Windows平台下拷过来的,果不其然中间出现了乱码问题,必然需要转码了。

先看下原来的编码,pinyin.db是sqlie2数据库,pinyin.db3刚转化而来的sqlite3数据库

enca pinyin*
pinyin.db: Simplified Chinese National Standard; GB2312
  Surrounded by/intermixed with non-text data
pinyin.db3: Unrecognized encoding

一个个text让应用去转码不可能,直接在数据库中转不具备可操作性,最后我想到了dump:

sqlite3 pinyin.db3 .dump>>conv.txt;enca conv.txt
Simplified Chinese National Standard; GB2312

将数据库以文本格式保存,对文本进行转码,这个就多了,用iconv、enconv专门转码的也可以,用vim、gedit也行;我最终选择了vim,因为转起来方便。

vim conv.txt后,:set fileencoding=utf8,最后:wq保存退出就可以了。看下结果

vim conv.txt




enca conv.txt
Universal transformation format 8 bits; UTF-8
  Surrounded by/intermixed with non-text data

好了,sql文本已经转换为UTF-8编码,这时候问题已经基本解决了。

最后重新生成sqlite3数据库即可:

cat conv.txt|sqlite3 utf8pinyin.db3

好了,现在可以轻松使用sqliteman或者sqlitebroswer打开utf8pinyin.db3,没有乱码了。

最后,我想团队开发一定要注意工作平台,另外尽量采用广泛支持的国际unicode编码。

坚持原创技术分享,您的支持将鼓励我继续创作!

Welcome to my other publishing channels