A-A+

SQLite 教程

2008年09月20日 技术文章 暂无评论 阅读 1 次

SQLite 特点:

不需要配置,不需要安装,也不需要管理员
支持大部分SQL92
一个完整的数据库保存在磁盘上面一个文件
同一个数据库文件可以在不同机器上面使用
最大支持数据库到2T
字符和BLOB的支持仅限制于可用内存
整个系统少于3万行代码,少于250KB的内存占用(gcc)
大部分应用比目前常见的 客户端/服务端 的数据库快
没有其它依赖
源代码开放, 代码95%有较好的注释
简单易用的API. 官方带有TCL的编译版本。其它的单独提供

php 从 5.x 开始默认内置编译了SQLite, 4.x 需要通过pear 来安装 pear install sqlite SQLite 常用于嵌入到程序, 为一些需要数据库,但是不必要安装中/大型的数据库,而且进行的是比较普通的操作(例如select/insert/delete之类的)

php的sqlite的一些例子权所有
以下为打开一个名叫sqlite.db的库, 如果不存在,会创建一个(需要目录可写)

$db_name='sqlite.db';
$db=new SQLiteDatabase($db_name, 0644, $error);
if ($error) exit($error);

创建一个表, 三个字段
user,主键,非空,长度100的varchar
pass,非空,长度100的varchar
date,非空,整型,索引
这里使用了queryExec 而不是 query.因为只是执行,不需要返回结果
注意:在SQLite里面query也是可以执行多行语句,但是如果有结果返回的,则只会有执行第一个有结果返回的命令。
执行失败将会返回FALSE.

$db->queryexec("
CREATE TABLE user (
user VARCHAR ( 100 ) NOT NULL PRIMARY KEY,
pass VARCHAR ( 100 ) NOT NULL,
date INTEGER NOT NULL,
);
CREATE INDEX user_date ON user(date);
");

插入一条数据

$db->query("INSERT INTO user (user, pass, date) VALUES ('admin', 'password', 123456789)");
$db->query("INSERT INTO user (user, pass, date) VALUES ('super', 'password2', 123456790)");

对某条记录进行更新

$db->query("UPDATE user SET password='password1' WHERE user='admin'");

查询
PHP下面SQLite的查询有很多形式
sqlite_array_query 进行一个查询,直接将返回的结果放入array
sqlite_query 是个普通的执行命令,返回为handle

返回来的handle 可以通过以下来获取结果
sqlite_fetch_all 获取所有结果并且将每条结果作为array,然后放入一个大的array里面
sqlite_fetch_array 获取下一个结果作为array
sqlite_fetch_column_types — Return an array of column types from a particular table
sqlite_fetch_object 获取下一个结果返回一个对象(obj)
sqlite_fetch_single 只获取第一列结果,返回为字符变量
sqlite_fetch_string 等同于 sqlite_fetch_single

因此会很方便写数据库的查询
例子:

$r=$db->singleQuery("SELECT password FROM user WHERE user='admin'");
// $r 则为返回来的 password1 字符串

$q=$db->Query("SELECT * FROM user");
while ($r=$q->fetch()) {
echo "User: $r[user] Password: $r[pass] Date: $r[date]n";
}
权所有
$r=$db->fetchAll("SELECT user, password FROM user");
print_r($r);

使用SQLite最大的好处是不用依赖使用其它DB,而且基本不需要担心DB server崩溃了你的程序就跟着挂了。
另外就是C/C++/delphi/java的可以把整个数据库引擎内嵌,不需要调用其它API,接口等。

sqlite简明教程

如何建立自动增长字段?
SQLite支持何种数据类型?
SQLite允许向一个integer型字段中插入字符串!
为什么SQLite不允许在同一个表不同的两行上使用0和0.0作主键?
多个应用程序或一个应用程序的多个实例可以同时访问同一个数据库文件吗?
SQLite线程安全吗?
在SQLite数据库中如何列出所有的表和索引?
SQLite数据库有已知的大小限制吗?
在SQLite中,VARCHAR字段最长是多少?
SQLite支持二进制大对象吗?
在SQLite中,如何在一个表上添加或删除一列?
我在数据库中删除了很多数据,但数据库文件没有变小,是Bug吗?
我可以在商业产品中使用SQLite而不需支付许可费用吗?
如何在字符串中使用单引号(')?
SQLITE_SCHEMA error是什么错误?为什么会出现该错误?
为什么 ROUND(9.95,1) 返回 9.9 而不是 10.0? 9.95不应该圆整(四舍五入)吗?

--------------------------------------------------------------------------------

(1) 如何建立自动增长字段?

简短回答:声明为 INTEGER PRIMARY KEY 的列将会自动增长。

长一点的答案: 如果你声明表的一列为 INTEGER PRIMARY KEY,那么, 每当你在该列上插入一NULL值时, NULL自动被转换为一个比该列中最大值大1的一个整数,如果表是空的, 将会是1。 (如果是最大可能的主键 9223372036854775807,那个,将键值将是随机未使用的数。) 如,有下列表:

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允许向一个integer型字段中插入字符串!

这是一个特性,而不是一个bug。SQLite不强制数据类型约束。 任何数据都可以插入任何列。你可以向一个整型列中插入任意长度的字符串, 向布尔型列中插入浮点数,或者向字符型列中插入日期型值。 在 CREATE TABLE 中所指定的数据类型不会限制在该列中插入任何数据。 任何列均可接受任意长度的字符串(只有一种情况除外: 标志为INTEGER PRIMARY KEY的列只能存储64位整数, 当向这种列中插数据除整数以外的数据时,将会产生错误。

但SQLite确实使用声明的列类型来指示你所期望的格式。所以, 例如你向一个整型列中插入字符串时,SQLite会试图将该字符串转换成一个整数。 如果可以转换,它将插入该整数;否则,将插入字符串。 这种特性有时被称为 类型或列亲和性(type or column affinity).

--------------------------------------------------------------------------------

(4)为什么SQLite不允许在同一个表不同的两行上使用0和0.0作主键?

主键必须是数值类型,将主键改为TEXT型将不起作用。

每一行必须有一个唯一的主键。对于一个数值型列, SQLite认为 '0' 和 '0.0' 是相同的, 因为他们在作为整数比较时是相等的(参见上一问题)。 所以,这样值就不唯一了。

--------------------------------------------------------------------------------

(5)多个应用程序或一个应用程序的多个实例可以同时访问同一个数据库文件吗?

多个进程可同时打开同一个数据库。多个进程可以同时进行SELECT 操作,但在任一时刻,只能有一个进程对数据库进行更改。

SQLite使用读、写锁控制对数据库的访问。(在Win95/98/ME等不支持读、 写锁的系统下,使用一个概率性的模拟来代替。)但使用时要注意: 如果数据库文件存放于一个NFS文件系统上,这种锁机制可能不能正常工作。 这是因为 fcntl() 文件锁在很多NFS上没有正确的实现。 在可能有多个进程同时访问数据库的时候,应该避免将数据库文件放到NFS上。 在Windows上,Microsoft的文档中说:如果使用 FAT 文件系统而没有运行 share.exe 守护进程,那么锁可能是不能正常使用的。那些在Windows上有很多经验的人告诉我: 对于网络文件,文件锁的实现有好多Bug,是靠不住的。如果他们说的是对的, 那么在两台或多台Windows机器间共享数据库可能会引起不期望的问题。

我们意识到,没有其它嵌入式的 SQL 数据库引擎能象 SQLite 这样处理如此多的并发。SQLite允许多个进程同时打开一个数据库, 同时读一个数据库。当有任何进程想要写时,它必须在更新过程中锁住数据库文件。 但那通常只是几毫秒的时间。其它进程只需等待写进程干完活结束。 典型地,其它嵌入式的SQL数据库引擎同时只允许一个进程连接到数据库。

但是,Client/Server数据库引擎(如 PostgreSQL, MySQL, 或 Oracle) 通常支持更高级别的并发,并且允许多个进程同时写同一个数据库。 这种机制在Client/Server结构的数据库上是可能的, 因为总是有一个单一的服务器进程很好地控制、协调对数据库的访问。 如果你的应用程序需要很多的并发,那么你应该考虑使用一个Client/Server 结构的数据库。但经验表明,很多应用程序需要的并发,往往比其设计者所想象的少得多。

当SQLite试图访问一个被其它进程锁住的文件时,缺省的行为是返回 SQLITE_BUSY。 可以在C代码中使用 sqlite3_busy_handler() 或 sqlite3_busy_timeout() API 函数调整这一行为。

--------------------------------------------------------------------------------

(6)SQLite线程安全吗?

线程是魔鬼(Threads are evil)。 避免使用它们。

SQLite 是线程安全的。由于很多用户会忽略我们在上一段中给出的建议, 我们做出了这种让步。但是,为了达到线程安全,SQLite在编译时必须将 SQLITE_THREADSAFE 预处理宏置为1。在Windows和Linux上, 已编译的好的二进制发行版中都是这样设置的。 如果不确定你所使用的库是否是线程安全的,可以调用 sqlite3_threadsafe() 接口找出。

在 3.3.1 版本之前,一个 sqlite3 结构只能被用于调用 sqlite3_open 创建的同一线程。你不能在一个线程中打开数据库, 然后将数据库句柄传递给另外一个进程使用。 这主要是由于在好多通用的线程实现(如RedHat9)中的限制引起的(是Bug吗?)。 特别的,在有问题的系统上,一个进程创建的 fcntl() 锁无法被其它线程清除或修改。 所以,由于 SQLite 大量使用 fcntl() 锁做并发控制, 如果你在不同的线程间移动数据库连接,就可能会出现严重的问题。

在3.3.1版本上,关于在线程间移动数据库连接的限制变得宽松了。 在它及以后的版本中,只要连接没有持有 fcntl() 锁,在线程间移动句柄是安全的。 如果没有未决的事务,并且所有的语句都已执行完毕, 你就可以安全的假定不再持有任何锁。

在UNIX中,在执行 fork() 系统调用时不应携带已打开的数据库进入子进程。 那样做将会有问题。

--------------------------------------------------------------------------------

(7)在SQLite数据库中如何列出所有的表和索引?

如果你运行 sqlite3 命令行来访问你的数据库,可以键入 “.tables”来获得所有表的列表。或者,你可以输入 “.schema” 来看整个数据库模式,包括所有的表的索引。 输入这些命令,后面跟一个LIKE模式匹配可以限制显示的表。

在一个 C/C++ 程序中(或者脚本语言使用 Tcl/Ruby/Perl/Python 等) 你可以在一个特殊的名叫 SQLITE_MASTER 上执行一个SELECT查询以获得所有 表的索引。每一个 SQLite 数据库都有一个叫 SQLITE_MASTER 的表, 它定义数据库的模式。 SQLITE_MASTER 表看起来如下:

CREATE TABLE sqlite_master (
type TEXT,
name TEXT,
tbl_name TEXT,
rootpage INTEGER,
sql TEXT
);
对于表来说,type 字段永远是 'table',name 字段永远是表的名字。所以,要获得数据库中所有表的列表, 使用下列SELECT语句:

SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
对于索引,type 等于 'index', name 则是索引的名字,tbl_name 是该索引所属的表的名字。 不管是表还是索引,sql 字段是原先用 CREATE TABLE 或 CREATE INDEX 语句创建它们时的命令文本。对于自动创建的索引(用来实现 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

--------------------------------------------------------------------------------

(8) SQLite数据库有已知的大小限制吗?

对有关SQLite限制的详细讨论,见 limits.html 。

--------------------------------------------------------------------------------

(9) 在SQLite中,VARCHAR字段最长是多少?

SQLite 不强制 VARCHAR 的长度。 你可以在 SQLITE 中声明一个 VARCHAR(10),SQLite还是可以很高兴地允许你放入500个字符。 并且这500个字符是原封不动的,它永远不会被截断。

--------------------------------------------------------------------------------

(10) SQLite支持二进制大对象吗?

SQLite 3.0 及以后版本允许你在任何列中存储 BLOB 数据。 即使该列被声明为其它类型也可以。

--------------------------------------------------------------------------------

(11) 在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;

--------------------------------------------------------------------------------

(12) 我在数据库中删除了很多数据,但数据库文件没有变小,是Bug吗?

不是。当你从SQLite数据库中删除数据时, 未用的磁盘空间将会加入一个内部的“自由列表”中。 当你下次插入数据时,这部分空间可以重用。磁盘空间不会丢失, 但也不会返还给操作系统。

如果删除了大量数据,而又想缩小数据库文件占用的空间,执行 VACUUM 命令。 VACUUM 将会从头重新组织数据库。这将会使用数据库有一个空的“自由链表”, 数据库文件也会最小。但要注意的是,VACUUM 的执行会需要一些时间 (在SQLite开发时,在Linux上,大约每M字节需要半秒种),并且, 执行过程中需要原数据库文件至多两倍的临时磁盘空间。

对于 SQLite 3.1版本,一个 auto-vacumm 模式可以替代 VACUUM 命令。 可以使用 auto_vacuum pragma 打开。

--------------------------------------------------------------------------------

(13) 我可以在商业产品中使用SQLite而不需支付许可费用吗?

是的。SQLite 在 public domain。 对代码的任何部分没有任何所有权声明。你可以使用它做任何事。

--------------------------------------------------------------------------------

(14) 如何在字符串中使用单引号(')?

SQL 标准规定,在字符串中,单引号需要使用逃逸字符,即在一行中使用两个单引号。在这方面 SQL 用起来类似 Pascal 语言。 SQLite 尊循标准。如:

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

--------------------------------------------------------------------------------

(15) SQLITE_SCHEMA error是什么错误?为什么会出现该错误?

当一个准备好的(prepared)SQL语句不再有效或者无法执行时, 将返回一个 SQLITE_SCHEMA 错误。发生该错误时,SQL语句必须使用 sqlite3_prepare() API来重新编译. 在 SQLite 3 中, 一个 SQLITE_SCHEMA 错误只会发生在用 sqlite3_prepare()/sqlite3_step()/sqlite3_finalize() API 执行 SQL 时。而不会发生在使用 sqlite3_exec()时。 在版本2中不是这样。

准备好的语句失效的最通常原因是:在语句准备好后, 数据库的模式又被修改了。另外的原因会发生在:

数据库离线:DETACHed.
数据库被 VACUUMed
一个用户存储过程定义被删除或改变。
一个 collation 序列定义被删除或改变。
认证函数被改变。
在所有情况下,解决方法是重新编译并执行该SQL语句。 因为一个已准备好的语句可以由于其它进程改变数据库模式而失效, 所有使用 sqlite3_prepare()/sqlite3_step()/sqlite3_finalize() API 的代码都应准备处理 SQLITE_SCHEMA 错误。下面给出一个例子:

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 );

--------------------------------------------------------------------------------

(16) 为什么 ROUND(9.95,1) 返回 9.9 而不是 10.0? 9.95不应该圆整 (四舍五入)吗?

SQLite 使用二进制算术,在二进制中, 无法用有限的二进制位数表示 9.95 。使用 64-bit IEEE 浮点 (SQLite就是使用这个)最接近 9.95 的二进制表示是 9.949999999999999289457264239899814128875732421875。 所在,当你输入 9.95 时,SQLite实际上以为是上面的数字, 在四舍五入时会舍去。

这种问题在使用二进制浮点数的任何时候都会出现。 通常的规则是记住很多有限的十进制小数都没有一个对应的二进制表示。 所以,它们只能使用最接近的二进制数。它们通常非常接近, 但也会有些微小的不同,有些时候也会导致你所期望的不同的结果。

SQLite是一款轻型的数据库,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如Tcl、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。

SQLite虽然很小巧,但是支持的SQL语句不会逊色于其他开源数据库,它支持的SQL包括:

ATTACH DATABASE
BEGIN TRANSACTION
comment
COMMIT TRANSACTION
COPY
CREATE INDEX
CREATE TABLE
CREATE TRIGGER
CREATE VIEW
DELETE
DETACH DATABASE
DROP INDEX
DROP TABLE
DROP TRIGGER
DROP VIEW
END TRANSACTION
EXPLAIN
expression
INSERT
ON CONFLICT clause
PRAGMA
REPLACE
ROLLBACK TRANSACTION
SELECT
UPDATE

同时它还支持事务处理功能等等。也有人说它象Microsoft的Access,有时候真的觉得有点象,但是事实上它们区别很大。比如SQLite支持跨平台,操作简单,能够使用很多语言直接创建数据库,而不象Access一样需要Office的支持。如果你是个很小型的应用,或者你想做嵌入式开发,没有合适的数据库系统,那么现在你可以考虑使用SQLite。目前它的最新版本是 3.2.2,它的官方网站是:http://www.sqlite.org,能在上面获得源代码和文档。同时因为数据库结构简单,系统源代码也不是很多,也适合想研究数据库系统开发的专业人士。

现在我们开始简单的介绍,主要我是想讲清楚几个问题,一是如何安装使用,二是如何跟PHP结合开发。

一、安装

1. Windows平台

下载windows下的文件,其实就是一个命令行程序,(下载地址:http://www.sqlite.org/sqlite-3_2_2.zip),这个命令行程序用来包括生成数据库文件、执行SQL查询、备份数据库等等功能。
下载后比如我们解压缩到 D:Downloadssqlitesqlite-3_2_2 这个目录下,那么我们进入cmd,并且进入该目录:
cd D:Downloadssqlitesqlite-3_2_2
D:Downloadssqlitesqlite-3_2_2>sqlite3 test.db
# 如果test.db不存在,那么就产生一个数据库文件,如果存在就直接使用该数据库文件,相当于mysql中的use
SQLite version 3.2.2
Enter ".help" for instructions
sqlite>
# SQLite的提示符,如果想查看命令帮助输入 .help,在sqlite中所有系统命令都是 . 开头的:
sqlite> .help
.databases List names and files of attached databases
.dump ?TABLE? ... Dump the database in an SQL 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
.import FILE TABLE Import data from FILE into TABLE
.indices TABLE Show names of all indices on TABLE
.mode MODE ?TABLE? Set output mode where MODE is one of:
csv Comma-separated values
column Left-aligned columns. (See .width)
html HTML code
insert SQL insert statements for TABLE
line One value per line
list Values delimited by .separator string
tabs Tab-separated values
tcl TCL list elements
.nullvalue STRING Print STRING in place of NULL values
.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 used by output mode and .import
.show Show the current values for various settings
.tables ?PATTERN? List names of tables matching a LIKE pattern
.timeout MS Try opening locked tables for MS milliseconds
.width NUM NUM ... Set column widths for "column" mode
sqlite>
www.knowsky.com
# 我们创建一个数据库catlog
sqlite> create table catalog(
...> id integer primarykey,
...> pid integer,
...> name varchar(10) UNIQUE
...> );
sqlite>
# 如果表存在就会提示:
SQL error: table catalog already exists
# 我们创建索引信息
create index catalog_idx on catalog (id asc);
# 我们查看表的信息,看有多少个表
sqlite> .table
aa catalog
# 查看表的结构:
sqlite> .schema catalog
CREATE TABLE catalog(
id integer primary key,
pid integer,
name varchar(10) UNIQUE
);
CREATE INDEX catalog_idx on catalog(id asc);
# 给数据表插入一条记录
sqlite> insert into catalog (ppid,name) values ('001','heiyeluren');
# 成功无任何提示,如果表达式错误提示错误信息:
SQL error: near "set": syntax error
# 检索有多少条记录
sqlite> select count(*) from catalog;
1
# 检索搜索记录
sqlite> select * from catalog;
1|1|heiyeluren

反正使用标准的SQL来操作就没有问题,不清楚可以去官方网站上查看帮助信息。另外还要说明的是SQLite不支持修改表结构,如果要修改表结构,只有删除表重新再建立,所以建立表的时候一定要考虑扩展性。估计以后这方面的功能会加强。

2. Linux/Unix 平台

error: 目前还没装过,呵呵,不过估计跟Windows差不多,改天把这部分内容补上。

二、PHP对SQLite的开发

PHP 5开始不再默认支持Mysql,而是默认支持SQLite,可见它的影响力多么大,所以如果你想做SQLite的PHP开发,建议你使用PHP 5.0.0以上版本,我目前使用的是 PHP 5.0.4版本,直接支持SQLite扩展,这里我就不仔细讲如何安装PHP扩展,如果不清楚可以查看PHP相关文档。
这里我主要是讲针对SQLite的开发。目前PHP的主流DB类都支持SQLite的驱动,包括PEAR::DB类、ADOdb类都支持,所以使用DB来来做开发也是个好的选择。

(以下操作为了简便,都是再Windows xp平台进行的)

1. 使用PHP操作已经建立好的sqlite数据库

如果你有一个已经通过sqlite.exe建立好了的数据库和表结构,那么你就能够直接对它进行操作。php中针对sqlite的处理函数比较多,你可以查看PHP手册获得详细信息。

我们使用sqlite_open()函数来打开一个sqlite数据库,它成功返回一个操作资源,失败返回false,那么以后的所有操作都是在这个资源上进行的,执行一个sql查询使用sqlite_query函数。

下面我假设你在当前PHP程序目录下有一个abc.db的sqlite数据库文件,我们对该文件进行操作:

//打开sqlite数据库
$db = @sqlite_open("abc.db");
//异常处理
if (!$db) die("Connection Sqlite failed.n");
//添加一个叫做foo的数据库
@sqlite_query($db, "CREATE TABLE foo (bar varchar(10))");
//插入一条记录
@sqlite_query($db, "INSERT INTO foo VALUES ('fnord')");
//检索所有记录
$result = @sqlite_query($db, 'select bar from foo');
//打印获取的结果
print_r(sqlite_fetch_array($result));

?>
我们看到的输出结果是:

Array
(
[0] => fnord
[bar] => fnord
)

证明我们代码执行成功,没有输入请检查程序,或者你的数据库文件是否存在。

那么有了这个基本操作,你就能够考虑使用更复杂的操作和SQL来操作它,让它帮你管理信息,你可以做一个留言本,或者做一个CMS系统,我想都是没有问题的。

2. 使用PHP建立数据库并且操作

如果你没有任何sqlite.exe之类的工具,那么你也能够通过php来创建一个sqlite数据库,并且对它进行管理。
其实通过sqlite.exe程序建立的数据库,内容是空的,其实只有后来等创建表,添加数据以后,数据库文件才有,那么我们是不是能够手工添加一个文件,比如一个空的 test.db 文件,并且对它进行操作。这是完全可以,下面我们就使用PHP程序来完成创建一个数据库,并且执行简单的建立数据表,插入数据和检索数据的功能。

首先我们来看代码:(代码比较长,但比较容易理解)

/**
* 文件:sqlite.php
* 功能:对sqlite数据库的处理
* 作者:heiyeluren
* 时间:2005-8-5
*/
define("LN", __LINE__);//行号
define("FL", __FILE__);//当前文件
define("DEBUG", 0);//调试开关

$db_name = "heiyeluren.db";
//创建数据库文件,文件内容为空
if (!file_exists($db_name)) {
if (!($fp = fopen($db_name, "w+"))) {
exit(error_code(-1, LN));
}
fclose($fp);
}
//打开数据库文件
if (!($db = sqlite_open($db_name))) {
exit(error_code(-2, LN));
}
//产生数据表结构
if (!sqlite_query($db, "DROP TABLE test")) {
exit(error_code(-3, LN));
}
if (!sqlite_query($db, "CREATE TABLE test (id integer primary key,pid integer,name varchar(10) UNIQUE)")) {
exit(error_code(-3, LN));
}
//插入一条数据
if (!sqlite_query($db, " INSERT INTO test (name) VALUES ('heiyeluren') ")) {
exit(error_code(-4, LN));
}
//把数据检索出来
if (!($result = sqlite_query($db, "SELECT * FROM test"))) {
exit(error_code(-5, LN));
}

//获取检索数据并显示
while ($array = sqlite_fetch_array($result)) {
echo "ID: ". $array[id] ."
Name: ". $array[name] ;
}

/* 错误信息代码函数 */
function error_code($code, $line_num, $debug=DEBUG)
{
if ($code<-6 || $code>-1) {
return false;
}
switch($code) {
case -1: $errmsg = "Create database file error.";
break;
case -2: $errmsg = "Open sqlite database file failed.";
break;
case -3: $errmsg = "Create table failed, table already exist.";
break;
case -4: $errmsg = "Insert data failed.";
break;
case -5: $errmsg = "Query database data failed.";
break;
case -6: $errmsg = "Fetch data failed.";
break;
case -7: $errmsg = "";
break;
default: $errmsg = "Unknown error.";
}

$m = "[ Error ]
File: ". basename(FL) ."
Line: ". LN ."
Mesg: ". $errmsg ."";
if (!$debug) {
($m = $errmsg);
}
return $m;
}

?>

如果你操作无误的话,那么程序最后输出:

ID: 1
Name: heiyeluren

我们以上的程序包括了比较完整的功能,有调试、异常处理、存取数据库等功能,算是一个简单应用。如果你有兴趣也可以进行扩展。

* 结束:

我们基本的操作就讲到这里,以后有空我会把内容补全。如果大家有兴趣可以去研究一下,也许你的个人主页就需要这样的小型数据库来帮助你。

* 参考文档:
http://www.donews.net/limodou/archive/2004/03/21/7997.aspx
http://www.linuxsir.org/bbs/showthread.php?p=1213668#post1213668

* SQLite资源
官方网站:http://www.sqlite.org
SQL语法: http://www.sqlite.org/lang.html
开发文档:http://www.sqlite.org/docs.html
常见问题:http://www.sqlite.org/faq.html
下载地址:http://www.sqlite.org/download.html

给我留言

Copyright © 浩然东方 保留所有权利.   Theme  Ality 07032740

用户登录