什么是指向sqlite句柄的指针

什么是指向sqlite句柄的指针,第1张

sqlite句柄实质上是对要 *** 作的数据库的描述的一个结构体,可以理解为类似文件描述符一类的东西.只是文件描述符描述的是文件,而sqlite句柄描述的是数据库.下面这个有更详细的代码描述:http://blog.csdn.net/binbby/article/details/50120333

SQLite3是目前最新的SQLite版本。可以从网站上下载SQLite3的源代码(本书使用的版本是sqlite-3.6.12.tar.gz)。

解压缩后进入sqlite-3.6.12的根目录,首先命令“./configure”生成Makefile文件,接着运行命令“make”对源代码进行编译,最后运行命令“make install”安装SQLite3。安装完毕后,可以运行命令sqlite3查看SQLite3是否能正常运行,如下所示

[root@localhost ~]# sqlite3

SQLite version 3.6.12

Enter ".help" for instructions

Enter SQL statements terminated with a ""

sqlite>

可以看到,SQLite3启动后会停留在提示符sqlite>处,等待用户输入SQL语句

在使用SQLite3前需要先了解下SQLite3支持的数据类型。SQLite3支持的基本数据类型主要有以下几类:

NULL

NUMERIC

INTEGER

REAL

TEXT

SQLite3会自动把其他数据类型转换成以上5类基本数据类型,转换规则如下所示:

char、clob、test、varchar—>TEXT

integer—>INTEGER

real、double、float—>REAL

blob—>NULL

其余数据类型都转变成NUMERIC

下面通过一个实例来演示SQLite3的使用方法。

新建一个数据库

新建数据库test.db(使用.db后缀是为了标识数据库文件)。在test.db中新建一个表test_table,该表具有name,、sex、age三列。SQLite3的具体 *** 作如下所示:

[root@localhost home]# sqlite3 test.db

SQLite version 3.6.12

Enter ".help" for instructions

Enter SQL statements terminated with a ""

sqlite>create table test_table(name, sex, age)

如果数据库test.db已经存在,则命令“sqlite3 test.db”会在当前目录下打开test.db。如果数据库test.db不存在,则命令“sqlite3 test.db”会在当前目录下新建数据库test.db。为了提高效率,SQLite3并不会马上创建test.db,而是等到第一个表创建完成后才会在物理上创建数据库。

由于SQLite3能根据插入数据的实际类型动态改变列的类型,所以在create语句中并不要求给出列的类型。

创建索引

为了加快表的查询速度,往往在主键上添加索引。如下所示的是在name列上添加索引的过程。

sqlite>create index test_index on test_table(name)

*** 作数据

如下所示的是在test_table中进行数据的插入、更新、删除 *** 作:

sqlite>insert into test_table values ('xiaoming', 'male', 20)

sqlite>insert into test_table values ('xiaohong', 'female', 18)

sqlite>select * from test_table

xiaoming|male|20

xiaohong|female|18

sqlite>update test_table set age=19 where name = 'xiaohong'

sqlite>select * from test_table

xiaoming|male|20

xiaohong|female|19

sqlite>delete from test_table where name = 'xiaoming'

sqlite>select * from test_table

xiaohong|female|19

批量 *** 作数据库

如下所示的是在test_table中连续插入两条记录:

sqlite>begin

sqlite>insert into test_table values ('xiaoxue', 'female', 18)

sqlite>insert into test_table values ('xiaoliu', 'male', 20)

sqlite>commit

sqlite>select * from test_table

xiaohong|female|19

xiaoxue|male|18

xiaoliu|male|20

运行命令commit后,才会把插入的数据写入数据库中。

数据库的导入导出

如下所示的是把test.db导出到sql文件中:

[root@localhost home]# sqlite3 test.db ".dump" >test.sql

test.sql文件的内容如下所示:

BEGIN TRANSACTION

CREATE TABLE test_table(name, sex, age)

INSERT INTO "test_table" VALUES('xiaohong','female',19)

CREATE INDEX test_index on test_table(name)

COMMIT

如下所示的是导入test.sql文件(导入前删除原有的test.db):

[root@localhost home]# sqlite3 test.db <test.sql

通过对test.sql文件的导入导出,可以实现数据库文件的备份。

11.2.2 SQLite3的C接口

以上介绍的是SQLite3数据库的命令 *** 作方式。在实际使用中,一般都是应用程序需要对数据库进行访问。为此,SQLite3提供了各种编程语言的使用接口(本书介绍C语言接口)。SQLite3具有几十个C接口,下面介绍一些常用的C接口。

sqlite_open

作用:打开SQLite3数据库

原型:int sqlite3_open(const char *dbname, sqlite3 **db)

参数:

dbname:数据库的名称;

db:数据库的句柄;

sqlite_colse

作用:关闭SQLite3数据库

原型:int sqlite_close(sqlite3 *db)

例如:

test.c:

#include <stdio.h>

#include <sqlite3.h>

static sqlite3 *db=NULL

int main()

{

int rc

rc= sqlite3_open("test.db", &db)

if(rc)

{

printf("can't open database!\n")

}

else

{

printf("open database success!\n")

}

sqlite3_close(db)

return 0

}

运行命令“gcc –o test test.c –lsqlite3”进行编译,运行test的结果如下所示:

[root@localhost home]# open database success!

sqlite_exec

作用:执行SQL语句

原型:int sqlite3_exec(sqlite3 *db, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg)

参数:

db:数据库;

sql:SQL语句;

callback:回滚;

errmsg:错误信息

例如:

test.c:

#include <stdio.h>

#include <sqlite3.h>

static sqlite3 *db=NULL

static char *errmsg=NULL

int main()

{

int rc

rc = sqlite3_open("test.db", &db)

rc = sqlite3_exec(db,"insert into test_table values('daobao', 'male', 24)", 0, 0, &errmsg)

if(rc)

{

printf("exec fail!\n")

}

else

{

printf("exec success!\n")

}

sqlite3_close(db)

return 0

}

编译完成后,运行test的结果如下所示:

[root@localhost home]# ./test

exec success!

[root@localhost home]# sqlite3 test.db

SQLite version 3.6.11

Enter ".help" for instructions

Enter SQL statements terminated with a ""

sqlite>select * from test_table

daobao|male|24

sqlite3_get_table

作用:执行SQL查询

原型:int sqlite3_get_table(sqlite3 *db, const char *zSql, char ***pazResult, int *pnRow, int *pnColumn, char **pzErrmsg)

参数:

db:数据库;

zSql:SQL语句;

pazResult:查询结果集;

pnRow:结果集的行数;

pnColumn:结果集的列数;

errmsg:错误信息;

sqlite3_free_table

作用:注销结果集

原型:void sqlite3_free_table(char **result)

参数:

result:结果集;

例如:

test.c:

#include <stdio.h>

#include <sqlite3.h>

static sqlite3 *db=NULL

static char **Result=NULL

static char *errmsg=NULL

int main()

{

int rc, i, j

int nrow

int ncolumn

rc= sqlite3_open("test.db", &db)

rc= sqlite3_get_table(db, "select * from test_table", &Result, &nrow, &ncolumn,

&errmsg)

if(rc)

{

printf("query fail!\n")

}

else

{

printf("query success!\n")

for(i = 1i <= nrowi++)

{

for(j = 0j <ncolumnj++)

{

printf("%s | ", Result[i * ncolumn + j])

}

printf("\n")

}

}

sqlite3_free_table(Result)

sqlite3_close(db)

return 0

}

编译完成后,运行test的结果如下所示:

[root@localhost home]# ./test

query success!

xiaohong | female | 19 |

xiaoxue | female | 18 |

xiaoliu | male | 20 |

daobao | male | 24 |

sqlite3_prepare

作用:把SQL语句编译成字节码,由后面的执行函数去执行

原型:int sqlite3_prepare(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **stmt, const char **pTail)

参数:

db:数据库;

zSql:SQL语句;

nByte:SQL语句的最大字节数;

stmt:Statement句柄;

pTail:SQL语句无用部分的指针;

sqlite3_step

作用:步步执行SQL语句字节码

原型:int sqlite3_step (sqlite3_stmt *)

例如:

test.c:

#include <stdio.h>

#include <sqlite3.h>

static sqlite3 *db=NULL

static sqlite3_stmt *stmt=NULL

int main()

{

int rc, i, j

int ncolumn

rc= sqlite3_open("test.db", &db)

rc=sqlite3_prepare(db,"select * from test_table",-1,&stmt,0)

if(rc)

{

printf("query fail!\n")

}

else

{

printf("query success!\n")

rc=sqlite3_step(stmt)

ncolumn=sqlite3_column_count(stmt)

while(rc==SQLITE_ROW)

{

for(i=0i<2i++)

{

printf("%s | ", sqlite3_column_text(stmt,i))

}

printf("\n")

rc=sqlite3_step(stmt)

}

}

sqlite3_finalize(stmt)

sqlite3_close(db)

return 0

}

编译完成后,运行test的结果如下所示:

[root@localhost home]# ./test

query success!

xiaohong | female | 19 |

xiaoxue | female | 18 |

xiaoliu | male | 20 |

daobao | male | 24 |

在程序中访问SQLite3数据库时,要注意C API的接口定义和数据类型是否正确,否则会得到错误的访问结果。

SQLite是一个嵌入式SQL数据库引擎。与大多数其他 SQL 数据库不同,SQLite 没有单独的服务器进程。SQLite 直接读写普通磁盘文件。具有多个表、索引、触发器和视图的完整SQL数据库包含在单个磁盘文件中。

SQLite比MySQL还要轻量级,官方提供的程序包大约1MB。但是这么小的内容居然也是一个关系型数据库,所以SQLite也很适合作为入门数据库。其中,SQL最基础的功能就是查询了。

2. 详论

2.1. 打开/关闭数据库

使用数据库的第一步当然是打开数据库了。对于C接口来说,通常的实现是提供一个打开的接口,得到一个句柄或者指针,然后通过这个句柄或者指针进行进一步 *** 作,包括关闭数据库 *** 作。SQLite正是这么设计的:

int nRes = sqlite3_open("D:/test.db", &pDB)

if (nRes != SQLITE_OK) {

cout <<"Open database fail: " <<sqlite3_errmsg(pDB)

return 1

}

sqlite3_close(pDB)

1

2

3

4

5

6

7

8

1

2

3

4

5

6

7

8

通过sqlite3_open()这个函数打开数据库文件,如果数据库.db文件不存在,则会创建这个文件文件。一旦创建成功,在程序结束时最好调用sqlite3_close()这个函数进行关闭,否则会内存泄漏。如果需要更加精细的打开数据库文件控制,最好使用sqlite3_open_v2()这个接口:

int flags =

SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE

int nRes = sqlite3_open_v2("D:/test.db", &pDB, flags, nullptr)

1

2

3

1

2

3

sqlite3_open_v2()提供了很多打开数据库文件时的配置,例如如果需要在数据库文件不存在时进行创建,可以再加上SQLITE_OPEN_CREATE。

2.2. 数据查询

如果在可视化管理工具(例如SQLite Expert)中,无论是查询、插入、修改或者删除 *** 作,都是直接输入SQL语句,然后执行运行 *** 作,就可以得到相应的结果。SQLite也有这样的接口sqlite3_exec(),例如我们查询一个表中所有的数据:

char* cErrMsg

int res =

sqlite3_exec(pDB, "select * from metadata", ResultCallBack, 0, &cErrMsg)

if (res != SQLITE_OK) {

cout <<"select fail: " <<cErrMsg <<endl

return false

}

sqlite3_free(cErrMsg)

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

6

7

8

9

10

sqlite3_exec()是一个回调函数,每查询到一行数据就调用一次:

int ResultCallBack(void* NotUsed, int argc, char** argv,

char** azColName) {

for (int i = 0i <argci++) {

cout <<azColName[i] <<" = " <<(argv[i] ? argv[i] : "NULL") <<", "

}

cout <<endl

return 0

}

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

如果需要进行更加细粒度的控制,那么一个合适的做法是使用statement(语句)。首先,我们将我们需要的sql语句编译成数据库引擎识别的字节码,这个步骤可以叫做prepare(准备):

sqlite3_stmt* statement = nullptr

int ret = sqlite3_prepare_v2(pDB, sqlStr, -1, &statement, nullptr)

if (ret != SQLITE_OK) {

printf("prepare error ret : %d\n", ret)

return 1

}

1

2

3

4

5

6

1

2

3

4

5

6

接着,就是执行准备好的SQL语句:

while (sqlite3_step(statement) == SQLITE_ROW) {

//...

}

1

2

3

1

2

3

sqlite3_setp()每次查询一行记录,并且返回SQLITE_ROW;知道查询完成,就返回SQLIET_DONE。通过这种方式实现了一种类似迭代器的 *** 作,循环遍历每个查询结果。

最后,我们对每一行查询的结果进行解析:

while (sqlite3_step(statement) == SQLITE_ROW) {

cout <<sqlite3_data_count(statement) <<'\n'

cout <<sqlite3_column_text(statement, 0) <<'\t'

<<sqlite3_column_text(statement, 1) <<'\n'

}

1

2

3

4

5

1

2

3

4

5

sqlite3_column_X是一系列函数,可以直接获取每一行相应列的数据类型。例如获取整型就是sqlite3_column_int。

另外,不要忘了关闭这个语句:

sqlite3_finalize(statement)

1

1

3. 参考


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10016902.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存