Chinaunix首页 | 论坛 | 博客
  • 博客访问: 862064
  • 博文数量: 150
  • 博客积分: 5123
  • 博客等级: 大校
  • 技术积分: 1478
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-06 10:03
文章分类

全部博文(150)

文章存档

2011年(2)

2010年(139)

2009年(9)

分类: 数据库开发技术

2010-09-23 10:00:11

转自:http://blog.csdn.net/byxdaz/archive/2010/08/28/5846023.aspx

一、SQLite简介  

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

  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

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

  下面是访问SQLite官方网站: / 时第一眼看到关于SQLite的特性.

  1. ACID事务

  2. 零配置  无需安装和管理配置

  3. 储存在单一磁盘文件中的一个完整的数据库

  4. 数据库文件可以在不同字节顺序的机器间自由的共享

  5. 支持数据库大小至2TB

  6. 足够小大致3万行C代码, 250K

  7. 比一些流行的数据库在大部分普通数据库操作要快

  8. 简单轻松的API

  9. 包含TCL绑定同时通过Wrapper支持其他语言的绑定

  10. 良好注释的源代码并且有着90%以上的测试覆盖率

  11. 独立没有额外依赖

  12. Source完全的Open, 你可以用于任何用途包括出售它

  13. 支持多种开发语言,C, PHP, Perl, Java, ASP.NET,Python

  2SQLite类型

  SQLite的数据类型

  首先你会接触到一个让你惊讶的名词: Typelessness(无类型). ! SQLite是无类型的这意味着你可以保存任何类型的数据到你所想要保存的任何表的任何列中无论这列声明的数据类型是什么(只有在一种情况下不是稍后解释). 对于SQLite来说对字段不指定类型是完全有效的:

  Create Table ex1(a, b, c);

  诚然SQLite允许忽略数据类型但是仍然建议在你的Create Table语句中指定数据类型因为数据类型对于你和其他的程序员交流或者你准备换掉你的数据库引擎. SQLite支持常见的数据类型:

  CREATE TABLE ex2(

  a VARCHAR(10),

  b NVARCHAR(15),

  c TEXT,

  d INTEGER,

  e FLOAT,

  f BOOLEAN,

  g CLOB,

  h BLOB,

  i TIMESTAMP,

  j NUMERIC(10,5)

  k VARYING CHARACTER (24),

  l NATIONAL VARYING CHARACTER(16)

  );

  前面提到在某种情况下, SQLite的字段并不是无类型的即在字段类型为”Integer Primary Key”时.

 

 

SQLite的简单使用

SQLite可以到官方站点下载
包括:Linux,Mac OS X, Windows下的已编译文件以及源代码、帮助文档。windows版的下载地址是:/sqlite-3_6_23_1.zip,下载后解压就可以了。这个文件是工作在命令行下的。双击它,就直接进入命令行了。

打开之后是这样显示的:

SQLite version 3.6.23.1

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite>

 

1、创建数据库

按理说第一步是创建一个数据库,我是学电子的,对计算机不了解,所以我不知道mysql是如何存储数据库的。但sqlite将一个数据库存储为一个文件。我们先进下cmd,关掉原来的sqlite3

在命令提示符下:

sqlite3 newsql.db

然后就会自动跳到sqlite>命令提示符下。我记得在linux下用时候会在当前目录下出现newsql.db文件。但在我所用版本的windows下没有出现。然后我做了些尝试得到如下结果:

sqlite3 newsql.db

.quit

注意:.quit是在sqlite提示符下输入的,代表退出。看目录下还是没有出现数据库文件。

sqlite3 newsql.db

;

.quit

出现了newsql.db文件。冒号加回车,在sqlite中,代表执行一条语句的意思,虽然我只输入了一个冒号加回车,没有输入任何的语句,但结果已是不同。

2、创建一个表

create table mytable(entry1 varchar(10),entry2 int);

不要忘了加冒号。冒号代表一条语句输入完毕。

mytable是我创建的表名。create table都是系统关键字。entry1,entry2是两个表项。

varchar(10) int是类型。根据我读到的内容,sqlite是不区分类型,但是我们还是要在创建表时,给他一个类型,以便于将这些代码移植到其他的数据库里面时更加的方便。

3、向表中插入一条记录

insert into mytable values("hello world",10);

插入完了之后才发现是不是超出定义的大小了?我定义的entry1项是varchar(10)型的,说实在的,我不知这个类型确切来讲是什么意思,我猜应该是10个字符的字符串数组吧。如果那样的话我是一定超出了。但既然sqlite是不区分类型的,我想应该没有问题吧。于是我急于看看是不是这样...

4、查询表中内容

select * from mytable;

执行这条语句,会列出mytable中的所有内容。

结果为:

sqlite> select * from mytable;

hello world|10

可见还是都插入进去了。

sqlite> insert into mytable values("goodbye cruel world",20);

sqlite> select * from mytable;

hello world|10

goodbye cruel world|20

也就是说,第一个条目的字符串完全不受限制。

5sqlite3 newsql.db的规则

我们现在退出,然后重新打开数据库:

sqlite> .quit

F:\sqlite>sqlite3 newsql.db

SQLite version 3.6.23.1

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite> select * from mytable;

hello world|10

goodbye cruel world|20

可见sqlite3 newsql.db这个命令规则为:打开名为newsql.db这个数据库,如果不存在则创建一个。

6、查询一个数据库中所有的表名

sqlite数据库中有一个系统建立的表,名为sqlite_master,查询这个表可以得到所有的表。

sqlite> create table my2ndtable(theonlyentry int);

sqlite> insert into my2ndtable values(30);

sqlite> select * from sqlite_master;

table|mytable|mytable|2|CREATE TABLE mytable(entry1 varchar(10),entry2 int)

table|my2ndtable|my2ndtable|3|CREATE TABLE my2ndtable(theonlyentry int)

对于这个表的定义,官方网站的FAQ中给出如下:

CREATE TABLE sqlite_master ( type TEXT, name TEXT, tbl_name TEXT, rootpage INTEGER, sql TEXT );第一个字段类型显然会一直是table,第二个字段是名称分别是mytablemy2ndtable,见上面的结果。第三个字段表名,没弄懂是什么意,想必是所在的表的名字,但是一个表的名字和所在的表名不是一样的吗?第四个字段rootpage,我也不知指什么,这个系统的学过数据库的人应该能知道,有路过的还望告之。第五个字段是创建表的使用的sql语句吧。

7sqlite的输出模式

 默认的输出格式是列表。在列表模式下,每条查询结果记录被写在一行中并且每列之间以一个字符串分割符隔开。默认的分隔符是一个管道符号(“|”)。列表符号在当你输出查询结果到另外一个符号处理的程序(如AWK)中去是尤为有用。

sqlite> .mode list

sqlite> select * from mytable;

hello world|10

goodbye cruel world|20

sqlite>

这是正常的模式。

sqlite> .mode csv

sqlite> select * from mytable;

"hello world",10

"goodbye cruel world",20

变化是什么?字符串被加上了引号。

sqlite> .mode column

sqlite> select * from mytable;

hello world  10

goodbye cru  20

哎呀,第二个字符串被截断了。

.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

这些来自.help命令的输出结果。

sqlite> .mode html

sqlite> select * from mytable;

.mode html是一种较新的输出方法。

另外,我们也可以把输出结果输出到文件:

sqlite> .output output.txt

sqlite> select * from mytable;

sqlite> .exit



F:\sqlite>type output.txt

hello world|10

goodbye cruel world|20

8、查看数据库中所有的表

sqlite> .tables

my2ndtable  mytable

9、查看所有的表的创建语句

sqlite> .schema

CREATE TABLE my2ndtable(theonlyentry int);

CREATE TABLE mytable(entry1 varchar(10),entry2 int);

sqlite> .schema mytable

CREATE TABLE mytable(entry1 varchar(10),entry2 int);

10、数据库导出和导入

我们可以利用这个功能做一个简单的备份,或是说创建一个同样的数据库。

第一步,把数据库倒出来:

cmd命令提示符下:

F:\sqlite>sqlite3 newsql.db ".dump" >a.sql

此语句将数据库导出成a.sql数据库语句文件,执行这个文件就可以创建一个一模一样数据库:

F:\sqlite>sqlite3 copied.db

SQLite version 3.6.23.1

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite> select * from mytable;

hello world|10

goodbye cruel world|20

11、删除记录
delete from mytable where entry2=10;
可以删掉mytable中所有entry2项为10的条目。
注意:不是delete * from mytable,delete from mytable.没有*.

 

三、SQLite3 C/C++ 开发接口简介(API函数)

SQLite3SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API. SQLite3是为了满足以下的需求而开发的:

  • 支持UTF-16编码.
  • 用户自定义的文本排序方法.
  • 可以对BLOBs字段建立索引.

因此为了支持这些特性我改变了数据库的格式,建立了一个与之前版本不兼容的3.0至于其他的兼容性的改变,例如全新的API等等,都将在理论介绍之后向你说明,这样可以使你最快的一次性摆脱兼容性问题.

3.0版的和2.X版的API非常相似,但是有一些重要的改变需要注意所有API接口函数和数据结构的前缀都由"sqlite_"改为了"sqlite3_". 这是为了避免同时使用SQLite 2.XSQLite 3.0这两个版本的时候发生链接冲突.

由于对于C语言应该用什么数据类型来存放UTF-16编码的字符串并没有一致的规范因此SQLite使用了普通的void* 类型来指向UTF-16编码的字符串客户端使用过程中可以把void*映射成适合他们的系统的任何数据类型.

SQLite 3.0一共有83API函数,此外还有一些数据结构和预定义(#defines). (完整的API介绍请参看另一份文档.) 不过你们可以放心,这些接口使用起来不会像它的数量所暗示的那么复杂最简单的程序仍然使用三个函数就可以完成: sqlite3_open(), sqlite3_exec(),  sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把SQL语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码sqlite3_column_开头的一组API函数用来获取查询结果集中的信息许多接口函数都是成对出现的,同时有UTF-8UTF-16两个版本并且提供了一组函数用来执行用户自定义的SQL函数和文本排序函数.

2.1 如何打开关闭数据库

   typedef struct sqlite3 sqlite3;
   int sqlite3_open(const char*, sqlite3**);
   int sqlite3_open16(const void*, sqlite3**);
   int sqlite3_close(sqlite3*);
   const char *sqlite3_errmsg(sqlite3*);
   const void *sqlite3_errmsg16(sqlite3*);
   int sqlite3_errcode(sqlite3*);

sqlite3_open() 函数返回一个整数错误代码,而不是像第二版中一样返回一个指向sqlite3结构体的指针. sqlite3_open()  sqlite3_open16() 的不同之处在于sqlite3_open16() 使用UTF-16编码(使用本地主机字节顺序)传递数据库文件名如果要创建新数据库, sqlite3_open16() 将内部文本转换为UTF-16编码反之sqlite3_open() 将文本转换为UTF-8编码.

打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行而且允许使用PRAGMA声明来设置如本地文本编码或默认内存页面大小等选项和参数.

sqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码. sqlite3_errmsg() 则用来得到这些错误代码所对应的文字说明这些错误信息将以 UTF-8 的编码返回,并且在下一次调用任何SQLite API函数的时候被清除. sqlite3_errmsg16()  sqlite3_errmsg() 大体上相同,除了返回的错误信息将以 UTF-16 本机字节顺序编码.

SQLite3的错误代码相比SQLite2没有任何的改变,它们分别是:

#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite_interrupt() */
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_ROW         100  /* sqlite_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite_step() has finished executing */

2.2 执行 SQL 语句

       typedef int (*sqlite_callback)(void*,int,char**, char**);
       int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void*, char**);

sqlite3_exec 函数依然像它在SQLite2中一样承担着很多的工作该函数的第二个参数中可以编译和执行零个或多个SQL语句查询的结果返回给回调函数更多地信息可以查看API 参考.

SQLite3,sqlite3_exec一般是被准备SQL语句接口封装起来使用的.

       typedef struct sqlite3_stmt sqlite3_stmt;
       int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**);
       int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**);
       int sqlite3_finalize(sqlite3_stmt*);
       int sqlite3_reset(sqlite3_stmt*);

sqlite3_prepare 接口把一条SQL语句编译成字节码留给后面的执行函数使用该接口访问数据库是当前比较好的的一种方法.

sqlite3_prepare() 处理的SQL语句应该是UTF-8编码的sqlite3_prepare16() 则要求是UTF-16编码的输入的参数中只有第一个SQL语句会被编译第四个参数则用来指向输入参数中下一个需要编译的SQL语句存放的SQLite statement对象的指针任何时候如果调用 sqlite3_finalize() 将销毁一个准备好的SQL声明在数据库关闭之前,所有准备好的声明都必须被释放销毁. sqlite3_reset() 函数用来重置一个SQL声明的状态,使得它可以被再次执行.

SQL声明可以包含一些型如"?"  "?nnn"  ":aaa"的标记,其中"nnn" 是一个整数,"aaa" 是一个字符串这些标记代表一些不确定的字符值(或者说是通配符),可以在后面用sqlite3_bind 接口来填充这些值每一个通配符都被分配了一个编号(由它在SQL声明中的位置决定,从1开始),此外也可以用 "nnn" 来表示 "?nnn" 这种情况允许相同的通配符在同一个SQL声明中出现多次在这种情况下所有相同的通配符都会被替换成相同的值没有被绑定的通配符将自动取NULL.

       int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
       int sqlite3_bind_double(sqlite3_stmt*, int, double);
       int sqlite3_bind_int(sqlite3_stmt*, int, int);
       int sqlite3_bind_int64(sqlite3_stmt*, int, long long int);
       int sqlite3_bind_null(sqlite3_stmt*, int);
       int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
       int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
       int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);

以上是 sqlite3_bind 所包含的全部接口,它们是用来给SQL声明中的通配符赋值的没有绑定的通配符则被认为是空值绑定上的值不会被sqlite3_reset()函数重置但是在调用了sqlite3_reset()之后所有的通配符都可以被重新赋值.



阅读(1430) | 评论(2) | 转发(0) |
0

上一篇:python中使用sqlite

下一篇:SQLite使用小结_2

给主人留下些什么吧!~~

chinaunix网友2010-09-26 15:30:37

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com

chinaunix网友2010-09-26 15:21:45

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com

hello world10
goodbye cruel world20