sqliteSQLite FAQ

————————–修改表结构————————————————–
SQLite的的ALTER
TABLE命令允许用户重命名或补给加新的字段到既产生表中,不可知于表中删除字段。

而只能在表的结尾添加栏目

本,为 Subscription添加有数单栏目

ALTER TABLE Subscription ADD COLUMN Activation BLOB;
ALTER TABLE Subscription ADD COLUMN Key BLOB;

得于一个事务中施行如下语句来提供 修改表的效果
将表名改也临时表
ALTER TABLE Subscription RENAME TO __temp__Subscription;
创立新表
CREATE TABLE Subscription (OrderId VARCHAR(32) PRIMARY KEY ,UserName
VARCHAR(32) NOT NULL ,ProductId VARCHAR(16) NOT NULL);
导入数据
INSERT INTO Subscription SELECT OrderId, “”, ProductId FROM
__temp__Subscription;
或者
INSERT INTO Subscription() SELECT OrderId, “”, ProductId FROM
__temp__Subscription;
顾 双引号”” 是用来填补原来不有的数码的
除去临时表
DROP TABLE __temp__Subscription;


(1) 如何创造于添字段?**

大概的答:一个声明也 INTEGER PRIMARY KEY 的字段将电动增加。

此是事无巨细的答案: 从 SQLite 的 2.3.4
版本开始,如果您用一个表中的一个字段声明也 INTEGER PRIMARY
KEY,那么不论你何时为该表的欠字段插入一个 NULL 值,这个 NULL
值将自动为移也比表中该字段所有行的卓绝要命价值大 1
的整数;如果表也空,那么用于转换为 1。比如,假要你发这样的均等布置数据表:

CREATE TABLE t1(  a INTEGER PRIMARY KEY,  b INTEGER);

于即时张数表里,声明

INSERT INTO t1 VALUES(NULL,123);

当逻辑意义上价于:

INSERT INTO t1 VALUES((SELECT max(a) FROM t1)+1,123);

一个新的API函数
sqlite3_last_insert_rowid()
返回最近之插入操作的整形键

只顾这个整型键始终比之前插入表中的末段一个键大1。新键相对于表中的曾发生键来说是绝无仅有的,
但它或许同前由表中删除的键值重叠。要尽抱在尽表中绝无仅有的键,在INTEGER
PRIMARY
KEY的宣示前加要词AUTOINCREMENT.这样于选择的键将总是比表中一度是的最为可怜键大1。若可能的
最大键已在于表中,INSERT操作以砸并返回一个SQLITE_FULL错误码.


(2) SQLite 支持什么数据类型?

参见 http://www.sqlite.org/datatype3.html.


(3) 为什么能向 SQLite 数据库的整型字段中插入字符串?

眼看是一个功力,不是一个
bug。你可当其余字段中放任何音讯,而不用无配段声明为什么类型。
你得通往整型字段中插入任意长度的字符串,或者往布尔字段中插入浮点数,或者为字符字段中
插入日期。在 CREATE TABLE
命令中若指定给这个字段的数据类型不见面限制插入这个字段的数目。
所有的字段可以插任意长度的字符串。但对于 INTEGER PRIMARY KEY
字段例外。这种字段只能 存放一个64号之平头,否则会拧。

但SQLite会默认你期望采取声明的字段类型。所以,比如你指望以一个声明也INTEGER的字段
中插入一个字符串,SQLite会试图将那个更换为一个平头。如果换成,那么整数将受插,否
则插入字符串,这种特性有时受称为type or column
affinity.


(4) 为什么 SQLite 认为表达式 ‘0’==’00’ 为确实?

以 2.7.0 之后,表达式不起。参见文档 datatypes in SQLite version
3


(5) 为什么 SQLite 不容许以平等摆设表里使用 ‘0’ 和 ‘0.0’
作为少数独不同之执行之主键?

乃的主键一定是数值类的,把品种变更呢 TEXT 就足以了。

各国一行要来一个唯一的主键。作为一个数字型的字段,SQLite 认为
‘0’‘0.0’的价值是平之,
因为他们在数字达到的于是等的(看眼前的题材)因此值不是绝无仅有的。


(6) 为什么不可知在 Linux box 中读取在 SparcStation 中创造的 SQLite
数据库?

您得升级而的 SQLite 库到 2.6.3 或更新版本。

x86 处理器是 little-endian 型的比方 Sparc 是 big-endian 型的。新本子的
SQLite 解决了是题材。

注:   big endian和little
endian是CPU处理多字节数的异方式。例如“汉”字的Unicode编码是6C49。那么写及文件里经常,究竟是拿6C写以前头,还是将49勾以前方?如果以6C写在头里,就是big
endian。还是用49描绘以眼前,就是little endian。


(7)
多单应用程序或者与一个应用程序的大多只例程能同时存取同一个数据库文件呢?

差不多进程可以以开辟和一个数据库,也足以而且 SELECT
。但无非生一个进程可以及时改数据库。

SQLite使用读/写锁定来控制数据库访问。(Win95/98/ME
操作系统缺乏读/写锁定支持,在低于 2.7.0 的版本中,这代表当 windows
下在同一时间内只能发出一个经过读数据库。在本 2.7.0 中 这个问题通过在
windows 接口代码中执行一个用户距离几带队读写锁定策略解决了。)
但如果数据库文件于一个 NFS
文件系统中,控制并发读书的锁定机制得以见面错。因为 NFS 的fcntl()
文件锁定有时见面起题目。如果生多进程可能并发读数据库则因当避免把数据库文件在
NFS 文件系统中。 根据微软的文档,如果非运行 Share.exe 后台程序则 FAT
文件系统中的锁定或者无办事。对 Windows
非常有更的人数告自己网络文件的锁定有不少题目而不可靠。如果是如此,在2独或以上
Windows 系统中共享一个 SQLite 数据库文件会招致不可预知的题目。

咱们知道没有任何的嵌入式 SQL数据库引擎比SQLite支持再次多之并发性。
SQLite允许多进程
同时开辟和读取数据库。任何一个历程要写副常,整个数据库将在马上同过程被于锁定。但马上貌似但耗时
几毫秒。其他进程就需要等接下来继续其他事情。其他嵌入式SQL数据库引擎往往只允许就进程看数据库。

而是,client/server型的数据库引擎 (如 PostgreSQL, MySQL, 以及 Oracle)
通常支持再次强之并发度,
并支持多进程而写副同一个数据库。由于总有一个操可以的服务器协调数据库的拜会,这才确保了上述
特性的实现。如果你的使得很高之并发度,你当考虑下client/server数据库。事实上,经验告诉
我们大部分施用所要之连发度比他们的设计者们想象的假设丢得多。

当 SQLite 尝试操作一个于外一个过程锁定的文件时,缺省之所作所为是回
SQLITE_BUSY。你可就此 C代码更改这等同行事。 使用
sqlite3_busy_handler()
或sqlite3_busy_timeout()
API函数。

如果少独或更多进程又打开和一个数据库,其中一个过程创造了新的表要索引,则其它进程或无克马上看见新的阐发。其它进程可能得关闭并还接数据库。


(8) SQLite是线程安全之啊?

突发性是的。为了线程安全,SQLite 必须以编译时拿 THREADSAFE
预处理宏设为1。在缺乏省的批发的已编译版本中 Windows 版的是线程安全的,而
Linux 版的无是。如果要求线程安全,Linux 版的设又编译。

“线程安全”是凭借二单或三单线程可以而且调用独立的两样之sqlite3_open()
返回的”sqlite3“结构。而不是以差不多线程中还要用以及一个 sqlite3
结构指针。

一个sqlite3布局只能于调用
sqlite3_open缔造它的慌进程面临使。你免克当一个线程中打开一个数据库然后拿指针传递让其他一个线程使用。这是为大部分多线程系统的限制(或
Bugs?)例如RedHat9上。在这些有问题之网及,一个
线程创建的fcntl()锁不克由其余一个线程删除或改动。由于SQLite依赖fcntl()锁来进展并发控制,当在线程间传递数据库连接时会出现严重的问题。

莫不在Linux下出点子缓解fcntl()锁之题材,但那十分复杂并且对正确的测试将是最最困难的。因此,SQLite目前莫同意在线程间共享句柄。

于UNIX下,你莫可知经过一个 fork() 系统调用把一个开辟的 SQLite
数据库放入子过程中,否则会拧。


(9) 如何列有一个 SQLite 数据库被的富有的表/索引?

sqlite3 命令行程序中公可就此命令 “.tables
来显示所有的表或者用
.schema“来显示有的表明结构以及目录。但令后并非和 LIKE
语句,否则会限制表的亮。

在 C/C++ 程序中 (或行使
Tcl/Ruby/Perl/Python绑定的下面本中)你可经走访名吧”SQLITE_MASTER的表来实现。每个
SQLite 数据库有一个 SQLITE_MASTER
表,表外发数据库的布局。SQLITE_MASTER表是这样的:

CREATE TABLE sqlite_master (  type TEXT,  name TEXT,  tbl_name TEXT,  rootpage INTEGER,  sql TEXT);

对表来说,type字段的价也‘table’name
字段是发明底名称。使用以下语句可以等及所有表的列表:

SELECT name FROM sqlite_masterWHERE type='table'ORDER BY name;

对索引来说, type = ‘index’, name 是索引的称号,
tbl_name 是索引所属的阐明的称谓。对于表及目录,sql
字段是开创表要索引的原始语句文本。对于活动创建的目录(一般是使用
PRIMARY KEY 或 UNIQUE 创建的),sql字段为 NULL.

SQLITE_MASTER表是仅念之。你无克针对该表使用 UPDATE, INSERT, 或
DELETE。该表自动由 CREATE TABLE, CREATE INDEX, DROP TABLE 和 DROP
INDEX 命令更新。

临时表及其索引不以 SQLITE_MASTER 表中使在 SQLITE_TEMP_MASTER
中出现。SQLITE_TEMP_MASTER 与 SQLITE_MASTER
表一样干活,但单对开创临时表的次序可见。要落所在表包括临时表可以采取如下命令:

SELECT name FROM    (SELECT * FROM sqlite_master UNION ALL    SELECT * FROM sqlite_temp_master)WHERE type='table'ORDER BY name

(10) SQLite数据库是否生曾经清楚之大小限制?

数据库大小为限以 2TB(241 bytes).
这是辩论限制。事实上,你应当将
SQLite数据库的轻重限制于100GB以下,以免出现运行性能及之题材。如果您待仓储100GB或还多多少在一个数据库中,
考虑采取与否夫而计划的合作社版数据库吧。

一个数据库的理论行数限制是
264-1,显然你见面以齐行数限制之前先超过文件大小的克。目前一行可以存放
230 bytes 数据。而基本的文件格式可以支撑实施大小及大约
262 bytes.

莫不还会见发生对表、索引的数码或表和目录中的许段往往的克,但从没人理解凡是微。事实上,每当新数据库打开时,SQLite需要读取和
分析所有表和目录声明的初始SQL,所以,为了调用
sqlite3_open()
时获得最佳性能,最好减少声明的表的多少。同样的,即使
对于表中配段往往没有范围,多于100个也出示无比多了。
只生说明开始的31只字段会得到优化。你可当一个索引中放入任意多之字段但超过30许段的目录将不用于优化查询。

表明,索引,视图,触发器和字段名称可以任意长,但SQL 函数名 (由
sqlite3_create_function()
API创建的)不得跨越255只字符。


(11) 在 SQLite 中 VARCHAR 的无比特别尺寸是小?

SQLite不强制VARCHAR的尺寸。你可声明一个VARCHAR(10),SQLite一样可以吃你存放500单字符在中间。
并且她会老完整无缺——决不会被截断。


(12) SQLite 是否支持 BLOB 类型?

SQLite 3.0 版支持以外字段存放 BLOB 数据,不管字段声明为什么类型。


(13) 如何由一个早就是的 SQLite 数据表中添加/删除字段?

SQLite有些许的ALTER
TABLE支撑,可以用来补充加字段到表的末尾
或改表名。如果您而对表的构造作更复杂的修改,你要再行创建表。你得以一个临时表中备份数据,撤销原有表,重建新表后再恢复数据。

诸如,假要你生一个称为吧 “t1” 的申,有名吧 “a”, “b”, 和 “c”
三个字段,你只要去除字段 “c” 。可随如下步骤操作:

BEGIN TRANSACTION;CREATE TEMPORARY TABLE t1_backup(a,b);INSERT INTO t1_backup SELECT a,b FROM t1;DROP TABLE t1;CREATE TABLE t1(a,b);INSERT INTO t1 SELECT a,b FROM t1_backup;DROP TABLE t1_backup;COMMIT;

(14) 我去了很多数额可数据库文件并从未减弱多少,是休是 Bug?

未是的。当您于 SQLite
删除数据后,未运的磁盘空间被补加至一个内在的“空闲列表”中用于存储你下次安插的数码。磁盘空间并无丢失,但是呢不往操作系统返回磁盘空间。

一经您去了大量的多寡还想只要压缩数据库文件,执行
VACUUM令。VACUUM
命令会清空“空闲列表”,把多少库尺寸缩到最小。注意, VACUUM
会耗费一些时间(在 Linux
系统下大约0.5秒/兆)并且使利用简单加倍于数据库文件大小的磁盘空间。

对此SQLite version 3.1, 替代VACUUM命令的一个法是auto-vacuum模式,用
auto_vacuum
pragma语法开启该模式。


(15) 是否能将 SQLite 用于商业用途而毫无交版权费用?

可以。SQLite
是公开的。代码的另外有都无声明所有权。你得为此它们来做乃想只要的旁工作。


(16) 如何插入有单引号(’)的字符串?

使用对单引号即可,例如:

    INSERT INTO xyz VALUES('5 O''clock');  

安插数据库的凡:5 0’clock。


(17) SQLITE_SCHEMA 错误代表什么?

每当 SQLite 版本3饱受,当一个事先处理 SQL 语句不合法不可知执行时就见面回去一个
SQLITE_SCHEMA 错误。当是似是而非有常,该语句应当用
sqlite3_prepare()
API函数重新编译。在 SQLite 版本3蒙受,只有利用
sqlite3_prepare()/sqlite3_step()/sqlite3_finalize()
API函数执行 SQL 才会发出是错误,而利用
sqlite3_exec().
则免会见。这同版本2不同。

大多数闹是荒唐的缘故是当 SQL
预处理完时数据库都改成了(可能是给另外一个经过改变的)。还可能发如下原因:

  • 本着一个数据库进行DETACH操作
  • 针对一个数据库进行VACUUM操作
  • 一个用户函数定义为删去或改了。
  • 一个排序定义为删除或变更了。
  • 一个授权函数改变了。

化解的点子是双重编译并更尝试推行。所有涉及
sqlite3_prepare()/sqlite3_step()/sqlite3_finalize()
API 函数的且应再编译。参见下例:

    int rc;    sqlite3_stmt *pStmt;    char zSql[] = "SELECT .....";    do {      /* Compile the statement from SQL. Assume success. */      sqlite3_prepare(pDb, zSql, -1, &pStmt, 0);      while( SQLITE_ROW==sqlite3_step(pStmt) ){        /* Do something with the row of available data */      }      /* Finalize the statement. If an SQLITE_SCHEMA error has      ** occured, then the above call to sqlite3_step() will have      ** returned SQLITE_ERROR. sqlite3_finalize() will return      ** SQLITE_SCHEMA. In this case the loop will execute again.      */      rc = sqlite3_finalize(pStmt);    } while( rc==SQLITE_SCHEMA );      

(18) 为什么ROUND(9.95,1) 返回 9.9 而未是 10.0? 难道9.95
不欠提高进发位么?

SQLite 内部采用二进制运算,9.95用 64-bit IEEE 浮点数 ( SQLite
内部以的)
表示也9.949999999999999289457264239899814128875732421875。所以当你输入
“9.95”时,SQLite
就知道为上述的数字,进而四放弃五可取9.9。这个问题在处理浮点二进制数总会发出。通常的平整是十进制的少浮点数通常无法表示为二进制有限浮点数,只能出于最相近的老二前进制数来取代。这个近乎数会非常接近原数,但终究有细微之不比,所以可能无法取得你预期的结果。

原稿链接:

网站地图xml地图