`
mmdev
  • 浏览: 12951047 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Ubuntu下安装SQLite3

 
阅读更多
1.介绍:sqlite3是linux上的小巧的数据库,一个文件就是一个数据库。
2.安装:
要安装sqlite3,可以在终端提示符后运行下列命令:
sudo apt-get install sqlite3
检查版本
sqlite3 -version
3.测试
当前目录下建立test.db测试数据库文件
sqlite3 test.db
查询信息
.database
退出
.exit
4.图形界面
可以选择sqlitebrowser程式(qt3)
sudo apt-get install sqlitebrowser
启动图形界面可以在终端提示符后输入sqlitebrowser
5.编程
PHP:sudo apt-get install php5-sqlite
Python:sudo apt-get install python-pysqlite2
Ruby:sudo apt-get install libsqlite3-ruby


比较有用的命令:

.tables 显示数据库中所有的表.

.schema 显示所有的表的创建语句.

.schema tableX 显示表tableX的创建语句.

.quit 退出

SQLite库包含一个名字叫做sqlite3的命令行,它可以让用户手工输入并执行面向SQLite数据库的SQL命令。本文档提供一个样使用sqlite3的简要说明。

开始

启动sqlite3程序,仅仅需要敲入带有SQLite数据库名字的"sqlite3"命令即可。如果文件不存在,则创建一个新的(数据库)文件。然后 sqlite3程序将提示你输入SQL。敲入SQL语句(以分号“;”结束),敲回车键之后,SQL语句就会执行。

例如,创建一个包含一个表"tb11"名字为"ex1"的SQLite数据库,你可以这样做:

$sqlite3 ex1

SQLite version 3.3.17

Enter ".help" for instructions

sqlite> create table tbl1(one varchar(10), two smallint);

sqlite> insert into tbl1 values('hello!', 10);

sqlite> insert into tbl1 values('goodbye', 20);

sqlite> select * from tbl1;

hello!|10

goodbye|20

sqlite>

你可以通过敲你所用系统的文件结束符(通常是Ctrl + D)或者中断字符(通常是Ctrl + C)。来终止sqlite3程序。确定你在每个SQL语句结束敲入分号!sqlite3程序通过查找分号来决定一个SQL语句的结束。如果你省略分 号,sqlite3将给你一个连续的命令提示符并等你给当前的SQL命令添加更多的文字。这个特点让你输入多行的多个SQL语句,例如:

sqlite> create table tbl2(

...> f1 varchar(30) primary key,

...> f2 text,

...> f3 real

...> );

sqlite>

题外话:查询SQLITE_MASTER表

SQLite数据库的框架被保存在一个名叫"sqlite_master"的特殊的表中。你可以像查询其它表一样通过执行“SELECT”查询这个特殊的表。例如:

$ sqlite3 ex1

SQlite vresion 3.3.10

Enter ".help" for instructions

sqlite> select * from sqlite_master;

type = table

name = tbl1

tbl_name = tbl1

rootpage = 3

sql = create table tbl1(one varchar(10), two smallint)

sqlite>

但你不能在sqlite_master表中执行诸如DROP TABLE, UPDATE, INSERT 或者DELETE命令。sqlite_master表在你创建、删除和索引数据库时自动更新这个表。你不能手工更改sqlite_master表。

TEMPORARY表的结构没有存储在"sqlite_master"表中,由于TEMPORARY表对应用是不可见的,而不是应用程序创建这个表。 TEMPORARY表结构被存储在另外一个名叫"sqlite_temp_master"的特定的表中。"sqlite_temp_master"表是临 时表自身。

sqlite3的特殊命令

大多数候,sqlite3读入输入行,并把它们传递到SQLite库中去运行。但是如果输入行以一个点(“.”)开始,那么这行将被sqlite3程序自 己截取并解释。这些“点命令”通常被用来改变查询输出的格式,或者执行鞭个预封包(预定义prepackaged)的查询语句。

你可以在任何时候输入“.help”,列出可用的点命令。例如

sqlite> .help

.bail ON|OFF Stop after hitting an error. Default OFF

.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

.load FILE ?ENTRY? Load an extension library

.mode MODE ?TABLE? Set output mode where MODE is one of:

csv Comma-separated values

column Left-aligned columns. (See .width)

html HTML <table> 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>

改变输出格式

sqlite3程序可以以八种不同的格式显示一个查询的结果:"csv", "列", "html", "插入", "行", "制表"和"tcl"。你可以用".mode"点命令在这些输出格式之间切换。

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

sqlite> .mode list

sqlite> select * from tbl1;

hello|10

goodbye|20

sqlite>

你可以用“.separator”点命令来改变分界符。例如,为了把分割符改为一个逗号和一个空格,你可以这样做:

sqlite> .separator ", "

sqlite> select * from tbl1;

hello, 10

goodbye, 20

sqlite>

在“line"模式下,每一个位于条记录中的列在它自己那行显示。每行由列名、一个等号和列数据组成。下一条记录以一个空行隔开。这是一个行模式输出的例子:

sqlite> .mode line

sqlite> select * from tbl1;

one = hello

two = 10

one = goodbye

two = 20

sqlite>

在列模式下,每条记录在一个单独的行中以数据列对齐的方式显示。列如:

sqlite> .mode column

sqlite> select * from tbl1;

one two

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

hello 10

goodbye 20

sqlite>

在默认的情况下,每列至少10个字符宽。太宽的数据将被截取。你可以用“.width”命令来调整列宽。如下所示:

sqlite> .width 12 6

sqlite> select * from tbl1;

one two

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

hello 10

goodbye 20

sqlite>

上面例子中".width"命令设置第一列宽为12第二列宽为6。其它的列宽不变。你可以指定与你查询结果需要的列数一样多的“.width”参数。

如果你指定一列宽为0,那么这个列宽将自动以下面三个数字中的最大值做为列宽:10、表头宽度和最宽的数据列的宽度。这可以让列自动调整宽度。每列的默认设置为自动调整的0值。

出现在输出开头两行的列标示可以用".header"点命令关闭。在上面的例子中,列标示是打开的。可以用下面的方法关闭列标示:

sqlite> .header off

sqlite> select * from tbl1;

hello 10

goodbye 20

sqlite>

另外一个有用的输出模式是"insert"。在插入模式下,被子格式化为看起来像SQL INSERT语句的样式。你可以用插入模式来产生文件(便于)以后用于不同数据库的输入。

当指定插入模式时,你必须给定一个特定参数就是要插入的表名。例如:

sqlite> .mode insert new_table

sqlite> select * from tbl1;

INSERT INTO 'new_table' VALUES('hello',10);

INSERT INTO 'new_table' VALUES('goodbye',20);

sqlite>

最新的输出格式是“html”。在这种模式下,sqlite3把查询的结果写做XHTML表。开始的<TABLE>和结束 的</TABLE>(标记)没有写出,但有<TR>、<TH>和<TD>等分界符。html输出对 CGI来说是相当有用地。

把结果写到文件中

默认情况下,sqlte3把结送到标准输出。你可以用“.output”命令改变它。只须把输出文件名做为.output命令的输出参数然后所有后续查询结果将被写到那个文件中。用“.output stdout”再一次改为标准输出。例如:

sqlite> .mode list

sqlite> .separator |

sqlite> .output test_file_1.txt

sqlite> select * from tbl1;

sqlite> .exit

$ cat test_file_1.txt

hello|10

goodbye|20

$

查询数据库结构

sqlite3程序提供几个有用的用于查询数据库结构的快捷命令。这些不是不可以用别的方式来实现。这些命令仅仅是一个快捷方式而已。

例如,为了查看数据库的表列表,你可以敲入“.tables”。

sqlite> .tables

tbl1

tbl2

sqlite>

“.tables”命令相似于设置列表模式然后执行接下来的查询:

SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'UNION ALL SELECT name FROM sqlite_temp_master WHERE type IN ('table','view') ORDER BY 1sqlite> .schema

create table tbl1(one varchar(10), two smallint)

CREATE TABLE tbl2 (

f1 varchar(30) primary key,

f2 text,

f3 real

)

sqlite> .schema tbl2

CREATE TABLE tbl2 (

f1 varchar(30) primary key,

f2 text,

f3 real

)

sqlite>

事实上,你可以查看sqlite3的源代码(可以在源文件树的src/shell.c中),你可找到上面的具体的查询。

“.indices”命令作用类似的方 式是列出特定表的所有的索引。“.indics”命令须一个参数即所要索引表的表名。最后,但不是至少,是“.schema”命令。不带任何参 数,“.schema”命令显示原始的用于创建当前数据库的CREATE TABLE和CREATE INDEX语句。如果你给".schema"命令一个表名,它显示原始的创建该表和它所有索引的CREATE语句。我们可以:

".schema"命令可以用设置列表然后执行以下查询来实现:

SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master)WHERE type!='meta'ORDER BY tbl_name, type DESC, name

或者,如果你给".schema"命令一个参数,由于你只想得到一个表的结构,查询可以是这样:

SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master)WHERE type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'ORDER BY substr(type,2,1), name

你可以担供一个参数给.schema命令。如果这橛,查询可以是这样的:

SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master)WHERE tbl_name LIKE '%s' AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'ORDER BY substr(type,2,1), name

在查询中“%S“为你的参数所取代。这使你可以询数据库结构的某个子集。

sqlite> .schema %abc%

与这些一起,“.table”命令也接受一个模式作为他的参数。如果你给“.table”一个参数,“%”将被前后扩展并且一个LIKE子句被附加到查询上。这让你可以列出只与特定模式相匹配的的表。

“.datebasae”命令显示所有 当前连接打开的数据库的一个列表。将允许一次到少两个。第一个是“main”,最初打开的那个数据库。第二个是"temp",用于临时表的数据库。对于用 ATTACH语句附加的数据也许有附加数据库列表。输出的第一列与之相联的数据库名,第二列是外部文件名。

sqlite> .databases

将整个数据库转换为ASCII文本文件

".dump"命令成一个单一的ASCII文本文件。这个文件可以被用作管道传递给sqlite3命令来转换回数据库。

一个最好的制作一个数据库档案拷贝的命令是:

$ echo '.dump' | sqlite3 ex1 | gzip -c >ex1.dump.gz

它产生一个一个名为ex1.dump.gz的文件,它包含了你以后或在其它机器上重构数据库的所有的信息。要重构数据库,只须敲入:

$ zcat ex1.dump.gz | sqlite3 ex2

这个文本格式是纯粹的SQL语句所以你可以用.dump命令来导出一个SQLite数据库到另一个常用的SQL数据库引擎。比如:

$ createdb ex2

$ sqlite3 ex1 .dump | psql ex2

其它的点命令

".explain"命令可以被用来设 置输出格式为“column” 并设置列宽为EXPLAIN命令看起来比较合理的宽度。EXPLAIN命令是SQLite特有的SQL扩展,它是对调试有用。如果任何常规的SQL被 EXPLAIN执行,那么SQL命令被分解并分析但并不执行。取而代之的是,虚拟机指令序列将被用于执行SQL命令并返回一个类似的查询结果。如:

sqlite> .explain

sqlite> explain delete from tbl1 where two<20;

addr opcode p1 p2 p3

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

0 ListOpen 0 0

1 Open 0 1 tbl1

2 Next 0 9

3 Field 0 1

4 Integer 20 0

5 Ge 0 2

6 Key 0 0

7 ListWrite 0 0

8 Goto 0 2

9 Noop 0 0

10 ListRewind 0 0

11 ListRead 0 14

12 Delete 0 0

13 Goto 0 11

14 ListClose 0 0

“.timeout”命令设置sqlite3等待一个试图存储文件锁定请除直到错误返回的总时间。默认的超时值是0因此如果任何需要的数据库表或序列列被锁定时它将立即返回一个错误。

最后,我们提到“.exit”命令它交导致sqlite3退出。

在命令和脚本中使用sqlite3

一个在脚本命令中使用 sqlite3的方式是用“echo”或“cat”来产生一个命令序列在一个文件中,然后当从一个产生的命令行中重定向输入时调用sqlite3。它有用 并且适应许多环境。但作为一附加的便利是,sqlite3允许一个单一的SQL语句在命令行中作为数据库名后的第二个参数输入。当sqlite3程序带着 两个参数启动时,第二个参数被传递给SQLite库处理,查询以列表模式打印到标准输出,然后程序退出。这个机制被设计用于让sqlite3容易于用于连 接诸如"AWK"的程序。例如:

$ sqlite3 ex1 'select * from tbl1' |

> awk '{printf "<tr><td>%s<td>%s/n",$1,$2 }'

<tr><td>hello<td>10

<tr><td>goodbye<td>20

$

结束命令行命令

SQLite命令通常以一个分 号结束。在一个命令行中你也可以用“GO”单词(大小写敏感)或者一个“/”斜线在它所在好行结束一个命令。这常被SQL Server和Oracle使用。这些将不在sqlite3_exec()中有用,因为命令行在传递它们到函数之前把这些翻译为分号。

从源文件中编译sqlite3

sqlite3程序当你编译SQLite库时自动被建立。只须取得一个源文件树的拷贝,运行“configure"然后"make"即可。

C/C++下SQLite编程

参考文件:A introduction to the sqlite c/c++ interface

找到安装SQLite的路径:

我们的sqlite3的库文件目录是:/usr/local/sqlite3/lib //我的机子安装目录文件名是sqlite-3.3.6
可执行文件 sqlite3 的目录是: /usr/local/sqlite3/bin
头文件 sqlite3.h 的目录是: /usr/local/sqlite3/include

编译指南:现在编译:[root@localhost dada]# gcc c3.c -o c3

opendbsqlite.c:11:21: sqlite3.h: 没有那个文件或目录
opendbsqlite.c: In function `main':
opendbsqlite.c:19: `sqlite3' undeclared (first use in this function)
// 这是由于没有找到头文件的原因

/tmp/ccTkItnN.o(.text+0x2b): In function `main':
: undefined reference to `sqlite3_open'
/tmp/ccTkItnN.o(.text+0x45): In function `main':
//这是个没有找到库文件的问题。

可以在gcc语句后面加上如下

-lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include

指明用到的库文件;为库文件指定路径;为头文件指定路径

继续编译:

出现 "error while loading shared libraries" 等错误

我们可以这样解决:
方法一:静态编译
在编译时加上 -static 参数,例如

[root@localhost temp]# gcc c3.c -o c3 -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include –static

静态编译后的文件相对动态编译更大,很容易理解,静态编译把头库文件作为程序的一部分都包含进来了。

方法二:重新配置系统环境变量 LD_LIBRARY_PATH
这时需要指定 libsqlite3.so.0 库文件的路径,也就是配置系统环境变量 LD_LIBRARY_PATH ,
使系统能够找到 libsqlite3.so.0 。

好了,现在我们来指定系统环境变量 LD_LIBRARY_PATH 的值
在shell下输入:
[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH
看看现在系统环境设置:
[root@localhost temp]#env

….

LD_LIBRARY_PATH=/usr/local/sqlite3/lib:

….. (看到了吧,LD_LIBRARY_PATH这一行开始就是sqlite3的库文件路径:)
去掉 -static ,再编译:
[root@localhost temp]# gcc c3.c -o c3 -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include

我们推荐使用动态编译的方法。
至此编译就不会有什么问题了,另外一点:如果在程序中把#include <sqlite3.h>写成#include<usr/local/sqlite-3.3.6/include/sqlite3.h>,这样在编译的时候就不需要-I/usr/local/sqlite3/include了。

常用函数

int sqlite3_open(
 const char *filename, /* Database filename (UTF-8) */
 sqlite3 **ppDb /* OUT: SQLite db handle */
);
int sqlite3_close(sqlite3 *);
int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg );
这就是执行一条 sql 语句的函数。
第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。
第2个参数const char *sql 是一条 sql 语句,以/0结尾。
第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
第4个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,这个指针比较重要,可以用来作参数的传递。如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。
第5 个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf(“%s/n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个 char*得到具体错误提示。
说明:通常, sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做 insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。用select时也可以用sqlite3_get_table

查询:

int sqlite3_get_table(
 sqlite3 *db, /* An open database */
 const char *zSql, /* SQL to be evaluated */
 char ***pazResult, /* Results of the query */
 int *pnRow, /* Number of result rows written here */
 int *pnColumn, /* Number of result columns written here */
 char **pzErrmsg /* Error msg written here */
);
void sqlite3_free_table(char **result); //释放内存空间


一.使用流程

要使用sqlite,需要从sqlite官网下载到三个文件,分别为sqlite3.lib,sqlite3.dll,sqlite3.h,然后再在自己的工程中配置好头文件和库文件,同时将dll文件放到当前目录下,就完成配置可以使用sqlite了。

使用的过程根据使用的函数大致分为如下几个过程:

  • sqlite3_open()
  • sqlite3_prepare()
  • sqlite3_step()
  • sqlite3_column()
  • sqlite3_finalize()
  • sqlite3_close()

这几个过程是概念上的说法,而不完全是程序运行的过程,如sqlite3_column()表示的是对查询获得一行里面的数据的列的各个操作统称,实际上在sqlite中并不存在这个函数。

1. sqlite3_open():打开数据库

在操作数据库之前,首先要打开数据库。这个函数打开一个sqlite数据库文件的连接并且返回一个数据库连接对象。这个操作同时程序中的第一个调用的sqlite函数,同时也是其他sqlite api的先决条件。许多的sqlite接口函数都需要一个数据库连接对象的指针作为它们的第一个参数。

函数定义

int sqlite3_open(

const char *filename, /* Database filename (UTF-8) */

sqlite3 **ppDb /* OUT: SQLite db handle */

);

int sqlite3_open16(

const void *filename, /* Database filename (UTF-16) */

sqlite3 **ppDb /* OUT: SQLite db handle */

);

int sqlite3_open_v2(

const char *filename, /* Database filename (UTF-8) */

sqlite3 **ppDb, /* OUT: SQLite db handle */

int flags, /* Flags */

const char *zVfs /* Name of VFS module to use */

);

说明:

假如这个要被打开的数据文件不存在,则一个同名的数据库文件将被创建。如果使用sqlite3_open和sqlite3_open_v2的话,数据库将采用UTF-8的编码方式,sqlite3_open16采用UTF-16的编码方式

返回值:

如果sqlite数据库被成功打开(或创建),将会返回SQLITE_OK,否则将会返回错误码。Sqlite3_errmsg()或者sqlite3_errmsg16可以用于获得数据库打开错误码的英文描述,这两个函数定义为:

const char *sqlite3_errmsg(sqlite3*);

const void *sqlite3_errmsg16(sqlite3*);

参数说明:

filename:需要被打开的数据库文件的文件名,在sqlite3_open和sqlite3_open_v2中这个参数采用UTF-8编码,而在sqlite3_open16中则采用UTF-16编码

ppDb:一个数据库连接句柄被返回到这个参数,即使发生错误。唯一的一场是如果sqlite不能分配内存来存放sqlite对象,ppDb将会被返回一个NULL值。

flags:作为数据库连接的额外控制的参数,可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一个,用于控制数据库的打开方式,可以和SQLITE_OPEN_NOMUTEXSQLITE_OPEN_FULLMUTEXSQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE结合使用,具体的详细情况可以查阅文档

2. Sqlite3_prepare()

这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。这个接口需要一个数据库连接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句

函数定义(仅列出UTF-8的)

int sqlite3_prepare(

sqlite3 *db, /* Database handle */

const char *zSql, /* SQL statement, UTF-8 encoded */

int nByte, /* Maximum length of zSql in bytes. */

sqlite3_stmt **ppStmt, /* OUT: Statement handle */

const char **pzTail /* OUT: Pointer to unused portion of zSql */

);

int sqlite3_prepare_v2(

sqlite3 *db, /* Database handle */

const char *zSql, /* SQL statement, UTF-8 encoded */

int nByte, /* Maximum length of zSql in bytes. */

sqlite3_stmt **ppStmt, /* OUT: Statement handle */

const char **pzTail /* OUT: Pointer to unused portion of zSql */

);

参数:

db:数据指针

zSql:sql语句,使用UTF-8编码

nByte:如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止

pzTail:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符

ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。

说明

如果执行成功,则返回SQLITE_OK,否则返回一个错误码。推荐在现在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容

备注

<1>准备语句(prepared statement)对象

typedef struct sqlite3_stmt sqlite3_stmt;

准备语句(prepared statement)对象一个代表一个简单SQL语句对象的实例,这个对象通常被称为“准备语句”或者“编译好的SQL语句”或者就直接称为“语句”。

语句对象的生命周期经历这样的过程:

l 使用sqlite3_prepare_v2或相关的函数创建这个对象

l 使用sqlite3_bind_*()给宿主参数(host parameters)绑定值

l 通过调用sqlite3_step一次或多次来执行这个sql

l 使用sqlite3——reset()重置这个语句,然后回到第2步,这个过程做0次或多次

l 使用sqlite3_finalize()销毁这个对象

在sqlite中并没有定义sqlite3_stmt这个结构的具体内容,它只是一个抽象类型,在使用过程中一般以它的指针进行操作,而sqlite3_stmt类型的指针在实际上是一个指向Vdbe的结构体得指针

<2>宿主参数(host parameters)

在传给sqlite3_prepare_v2()的sql的语句文本或者它的变量中,满足如下模板的文字将被替换成一个参数:

l ?

l ?NNN,NNN代表数字

l :VVV,VVV代表字符

l @VVV

l $VVV

在上面这些模板中,NNN代表一个数字,VVV代表一个字母数字标记符(例如:222表示名称为222的标记符),sql语句中的参数(变量)通过上面的几个模板来指定,如

“select ? from ? “这个语句中指定了两个参数,sqlite语句中的第一个参数的索引值是1,这就知道这个语句中的两个参数的索引分别为1和2,使用”?”的话会被自动给予索引值,而使用”?NNN”则可以自己指定参数的索引值,它表示这个参数的索引值为NNN。”:VVV”表示一个名为”VVV”的参数,它也有一个索引值,被自动指定。

可以使用sqlite3_bind_*()来给这些参数绑定值

3. sqlite3_setp()

这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回

函数定义

int sqlite3_step(sqlite3_stmt*);

返回值

函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prepare()和sqlite3_prepare16(),返回值会是SQLITE_BUSY,SQLITE_DONE,SQLITE_ROW,SQLITE_ERROR 或SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返回这些结果码和扩展结果码。

对所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后调用sqlite3_reset(),在后续的sqlite3_ step之前。如果调用sqlite3_reset重置准备语句失败,将会导致sqlite3_ step返回SQLITE_MISUSE,但是在V3. 6.23.1以后,sqlite3_step()将会自动调用sqlite3_reset。

int sqlite3_reset(sqlite3_stmt *pStmt);

sqlite3_reset用于重置一个准备语句对象到它的初始状态,然后准备被重新执行。所有sql语句变量使用sqlite3_bind*绑定值,使用sqlite3_clear_bindings重设这些绑定。Sqlite3_reset接口重置准备语句到它代码开始的时候。sqlite3_reset并不改变在准备语句上的任何绑定值,那么这里猜测,可能是语句在被执行的过程中发生了其他的改变,然后这个语句将它重置到绑定值的时候的那个状态。

4. sqlite3_column()

这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值。对列操作是有多个函数,均以sqlite3_column为前缀

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);

int sqlite3_column_bytes(sqlite3_stmt*, int iCol);

int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);

double sqlite3_column_double(sqlite3_stmt*, int iCol);

int sqlite3_column_int(sqlite3_stmt*, int iCol);

sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);

int sqlite3_column_type(sqlite3_stmt*, int iCol);

sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

说明

第一个参数为从sqlite3_prepare返回来的prepared statement对象的指针,第二参数指定这一行中的想要被返回的列的索引。最左边的一列的索引号是0,行的列数可以使用sqlite3_colum_count()获得。

这些过程会根据情况去转换数值的类型,sqlite内部使用sqlite3_snprintf()去自动进行这个转换,下面是关于转换的细节表:

内部类型

请求的类型

转换

NULL

INTEGER

结果是0

NULL

FLOAT

结果是0.0

NULL

TEXT

结果是NULL

NULL

BLOB

结果是NULL

INTEGER

FLOAT

从整形转换到浮点型

INTEGER

TEXT

整形的ASCII码显示

INTEGER

BLOB

同上

FLOAT

INTEGER

浮点型转换到整形

FLOAT

TEXT

浮点型的ASCII显示

FLOAT

BLOB

同上

TEXT

INTEGER

使用atoi()

TEXT

FLOAT

使用atof()

TEXT

BLOB

没有转换

BLOB

INTEGER

先到TEXT,然后使用atoi

BLOB

FLOAT

先到TEXT,然后使用atof

BLOB

TEXT

如果需要的话添加0终止符

注:BLOB数据类型是指二进制的数据块,比如要在数据库中存放一张图片,这张图片就会以二进制形式存放,在sqlite中对应的数据类型就是BLOB

int sqlite3_column_bytes(sqlite3_stmt*, int iCol)int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)两个函数返回对应列的内容的字节数,这个字节数不包括后面类型转换过程中加上的0终止符。

下面是几个最安全和最简单的使用策略

  • 先sqlite3_column_text() ,然后 sqlite3_column_bytes()
  • 先sqlite3_column_blob(),然后sqlite3_column_bytes()
  • 先sqlite3_column_text16(),然后sqlite3_column_bytes16()

5. sqlite3_finalize

int sqlite3_finalize(sqlite3_stmt *pStmt);

这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露。

在空指针上调用这个函数没有什么影响,同时可以准备语句的生命周期的任一时刻调用这个函数:在语句被执行前,一次或多次调用sqlite_reset之后,或者在sqlite3_step任何调用之后不管语句是否完成执行

6. sqlite3_close

这个过程关闭前面使用sqlite3_open打开的数据库连接,任何与这个连接相关的准备语句必须在调用这个关闭函数之前被释放

二.使用举例

#include "stdafx.h"
#include "sqlite3.h"
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i;
for(i=0; i<argc; i++){
printf("%s = %s/n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("/n");
return 0;
}
#define CHECK_RC(rc,szInfo,szErrMsg,db) if(rc!=SQLITE_OK) /
{printf("%s error!/n",szInfo);/
printf("%s/n",szErrMsg); /
sqlite3_free(szErrMsg); /
sqlite3_close(db); /
return 0;}
int _tmain(int argc, _TCHAR* argv[])
{
sqlite3 *db;
char *dbPath="f:/test.db";
char *szErrMsg = 0;
int rc= sqlite3_open(dbPath, &db);
CHECK_RC(rc,"open database",db);
char *szSql="create table UserInfo(ID int primary key , UserName char, PassWord char);";
rc=sqlite3_exec(db,szSql,0,0,&szErrMsg);
CHECK_RC(rc,"create table",szErrMsg,db);
rc=sqlite3_exec(db,"insert into UserInfo(ID,UserName,PassWord) values(1,'kfqcome','123456')",0,0,&szErrMsg);
CHECK_RC(rc,"insert info",szErrMsg,db);
rc=sqlite3_exec(db,"insert into UserInfo(ID,UserName,PassWord) values(2,'miss wang','654321')",0,0,&szErrMsg);
CHECK_RC(rc,"insert info",szErrMsg,db);
szSql="select * from UserInfo";
rc = sqlite3_exec(db,szSql, callback, 0, &szErrMsg);
CHECK_RC(rc,"query values",szErrMsg,db);
sqlite3_close(db);
getchar();
return 0;
}

  输出的结果:

ID = 1

UserName = kfqcome

PassWord = 123456

ID = 2

UserName = miss wang

PassWord = 654321

这里执行sql语句用的是sqlite3_exec,它是前面几个函数的封装

int sqlite3_exec(

sqlite3*,/* An open database */

const char *sql,/* SQL to be evaluated */

int (*callback)(void*,int,char**,char**),/* Callback function */

void *,/* 1st argument to callback */

char **errmsg/* Error msg written here */

);

sqlite3_exec是sqlite3_prepare_v2,sqlite3_step()和sqlite3_finalize()的封装,能让程序多次执行sql语句而不要写许多重复的代码。

Sqlite3_exec接口执行0或多个UTF-8编码的,分号分割的sql语句,传到第二个参数中。如果sqlite3_exec的第三个参数回调函数指针不为空,那么它会为每个来自执行的SQL语句的结果行调用(也就是说回调函数会调用多次,上面例子中会返回2个结果行,因而会被执行2次),第4个参数是传给回调函数的第一个参数,如果回调函数指针为空,那么回调不会发生同时结果行被忽略。

如果在执行sql语句中有错误发生,那么当前的语句的执行被停止,后续的语句也被跳过。第五个参数不为空的时候,它被分配内存并写入了错误信息,所以在sqlite3_exec后面需要调用sqlite3_free去释放这个对象以防止内存泄露

回调函数:

int (*callback)(void*,int,char**,char**),/* Callback function */

第一个参数通过sqlite3_exec的第第四个参数传入的

第二个参数是结果行的列数

第三个参数是行中列数据的指针

第四个参数是行中列名称的指针


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics