当前位置:文档之家› sqlite3使用详解

sqlite3使用详解

sqlite3使用详解
sqlite3使用详解

sqlite常量的定义:

const

SQLITE_OK = 0; 返回成功

SQLITE_ERROR = 1; SQL错误或错误的数据库

SQLITE_INTERNAL = 2; An internal logic error in SQLite

SQLITE_PERM = 3; 拒绝访问

SQLITE_ABORT = 4; 回调函数请求中断

SQLITE_BUSY = 5; 数据库文件被锁

SQLITE_LOCKED = 6; 数据库中的一个表被锁

SQLITE_NOMEM = 7; 内存分配失败

SQLITE_READONLY = 8; 试图对一个只读数据库进行写操作

SQLITE_INTERRUPT = 9; 由sqlite_interrupt()结束操作

SQLITE_IOERR = 10; 磁盘I/O发生错误

SQLITE_CORRUPT = 11; 数据库磁盘镜像畸形

SQLITE_NOTFOUND = 12; (Internal Only)表或记录不存在

SQLITE_FULL = 13; 数据库满插入失败

SQLITE_CANTOPEN = 14; 不能打开数据库文件

SQLITE_PROTOCOL = 15; 数据库锁定协议错误

SQLITE_EMPTY = 16; (Internal Only)数据库表为空

SQLITE_SCHEMA = 17; 数据库模式改变

SQLITE_TOOBIG = 18; 对一个表数据行过多

SQLITE_CONSTRAINT = 19; 由于约束冲突而中止

SQLITE_MISMATCH = 20; 数据类型不匹配

SQLITE_MISUSE = 21; 数据库错误使用

SQLITE_NOLFS = 22; 使用主机操作系统不支持的特性

SQLITE_AUTH = 23; 非法授权

SQLITE_FORMAT = 24; 辅助数据库格式错误

SQLITE_RANGE = 25; 2nd parameter to sqlite_bind out of range

SQLITE_NOTADB = 26; 打开的不是一个数据库文件

SQLITE_ROW = 100; sqlite_step() has another row ready

SQLITE_DONE = 101; sqlite_step() has finished executing

SQLITE3 使用总结(ZZ)

Posted by LostMyself

十一月22, 2008

发信人: lih (未醒), 信区: VC

标题: SQLITE3 使用总结

发信站: BBS 侏罗纪站(Wed Jul 11 09:02:02 2007)

前序:

Sqlite3 的确很好用。小巧、速度快。但是因为非微软的产品,帮助文档总觉得不够。这

些天再次研究它,又有一些收获,这里把我对sqlite3 的研究列出来,以备忘记。

这里要注明,我是一个跨平台专注者,并不喜欢只用windows 平台。我以前的工作就是为

unix 平台写代码。下面我所写的东西,虽然没有验证,但是我已尽量不使用任何windo

ws 的东西,只使用标准C 或标准C++。但是,我没有尝试过在别的系统、别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改。

下面我的代码仍然用VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合Vassist )。下面我所说的编译环境,是VC2003。如果读者觉得自己习惯于

unix 下用vi 编写代码速度较快,可以不用管我的说明,只需要符合自己习惯即可,因为

我用的是标准 C 或C++ 。不会给任何人带来不便。

一、版本

从https://www.doczj.com/doc/e99604632.html, 网站可下载到最新的sqlite 代码和编译版本。我写此文章时,最新

代码是 3.3.17 版本。

很久没有去下载sqlite 新代码,因此也不知道sqlite 变化这么大。以前很多文件,现

在全部合并成一个sqlite3.c 文件。如果单独用此文件,是挺好的,省去拷贝一堆文件还

担心有没有遗漏。但是也带来一个问题:此文件太大,快接近7万行代码,VC开它整个机器都慢下来了。如果不需要改它代码,也就不需要打开sqlite3.c 文件,机器不会慢。但是

,下面我要写通过修改sqlite 代码完成加密功能,那时候就比较痛苦了。如果个人水平

较高,建议用些简单的编辑器来编辑,例如UltraEdit 或Notepad 。速度会快很多。

二、基本编译

这个不想多说了,在VC 里新建dos 控制台空白工程,把sqlite3.c 和sqlite3.h 添加

到工程,再新建一个main.cpp 文件。在里面写:

extern "C"

{

#include "./sqlite3.h"

};

int main( int , char** )

{

return 0;

}

为什么要extern “C” ?如果问这个问题,我不想说太多,这是C++的基础。要在C++

里使用一段 C 的代码,必须要用extern “C” 括起来。C++跟C虽然语法上有重叠,但

是它们是两个不同的东西,内存里的布局是完全不同的,在C++编译器里不用extern “C”

括起C代码,会导致编译器不知道该如何为 C 代码描述内存布局。

可能在sqlite3.c 里人家已经把整段代码都extern “C” 括起来了,但是你遇到一个

.c 文件就自觉的再括一次,也没什么不好。

基本工程就这样建立起来了。编译,可以通过。但是有一堆的warning。可以不管它。

三、SQLITE操作入门

sqlite提供的是一些C函数接口,你可以用这些函数操作数据库。通过使用这些接口,传递一些标准sql 语句(以char * 类型)给sqlite 函数,sqlite 就会为你操作数据库。

sqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是,它实际上得到的就是一个文件

。备份这个文件就备份了整个数据库。

sqlite 不需要任何数据库引擎,这意味着如果你需要sqlite 来保存一些用户数据,甚至

都不需要安装数据库(如果你做个小软件还要求人家必须装了sqlserver 才能运行,那也太

黑心了)。

下面开始介绍数据库基本操作。

(1)基本流程

i.1 关键数据结构

sqlite 里最常用到的是sqlite3 * 类型。从数据库打开开始,sqlite就要为这个类型准

备好内存,直到数据库关闭,整个过程都需要用到这个类型。当数据库打开时开始,这个类型的变量就代表了你要操作的数据库。下面再详细介绍。

i.2 打开数据库

int sqlite3_open( 文件名, sqlite3 ** );

用这个函数开始数据库操作。

需要传入两个参数,一是数据库文件名,比如:c:\\DongChunGuang_Database.db。

文件名不需要一定存在,如果此文件不存在,sqlite 会自动建立它。如果它存在,就尝试把它当数据库文件来打开。

sqlite3 ** 参数即前面提到的关键数据结构。这个结构底层细节如何,你不要关它。

函数返回值表示操作是否正确,如果是SQLITE_OK 则表示操作正常。相关的返回值sqlit e定义了一些宏。具体这些宏的含义可以参考sqlite3.h 文件。里面有详细定义(顺便说一下,sqlite3 的代码注释率自称是非常高的,实际上也的确很高。只要你会看英文,sq lite 可以让你学到不少东西)。

下面介绍关闭数据库后,再给一段参考代码。

i.3 关闭数据库

int sqlite3_close(sqlite3 *);

前面如果用sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数

据库。

下面给段简单的代码:

extern "C"

{

#include "./sqlite3.h"

};

int main( int , char** )

{

sqlite3 * db = NULL; //声明sqlite关键结构指针

int result;

//打开数据库

//需要传入db 这个指针的指针,因为sqlite3_open 函数要为这个指针分配内存,还要让db指针指向这个内存区

result = sqlite3_open( “c:\\Dcg_database.db”, &db );

if( result != SQLITE_OK )

{

//数据库打开失败

return -1;

}

//数据库操作代码

//…

//数据库打开成功

//关闭数据库

sqlite3_close( db );

return 0;

}

这就是一次数据库操作过程。

(2)SQL语句操作

本节介绍如何用sqlite 执行标准sql 语法。

i.1 执行sql语句

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 把数据查出来,得通过回调告诉你查出

了什么数据。

i.2 exec 的回调

typedef int (*sqlite3_callback)(void*,int,char**, char**);

你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:

//sqlite3的回调函数

// sqlite 每查到一条记录,就调用一次这个回调

int LoadMyInfo( void * para, int n_column, char ** column_value, char **

column_name )

{

//para是你在sqlite3_exec 里传入的void * 参数

//通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然

后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据

//n_column是这一条记录有多少个字段(即这条记录有多少列)

// char ** column_value 是个关键值,查出来的数据都保存在这里,它实际

上是个1维数组(不要以为是2维数组),每一个元素都是一个char * 值,是一个字段内容(用字符串来表示,以\0结尾)

//char ** column_name 跟column_value是对应的,表示这个字段的字段名称

//这里,我不使用para 参数。忽略它的存在.

int i;

printf( “记录包含%d 个字段\n”, n_column );

for( i = 0 ; i < n_column; i ++ )

{

printf( “字段名:%s ?> 字段值:%s\n”, column_name*i+, column_valu

e[i] );

}

printf( “------------------\n“ );

return 0;

}

int main( int , char ** )

{

sqlite3 * db;

int result;

char * errmsg = NULL;

result = sqlite3_open( “c:\\D cg_database.db”, &db );

if( result != SQLITE_OK )

{

//数据库打开失败

return -1;

}

//数据库操作代码

//创建一个测试表,表名叫MyTable_1,有2个字段:ID 和name。其中ID是一个自动增加的类型,以后insert时可以不去指定这个字段,它会自己从0开始增加

result = sqlite3_exec( db, “create table MyTable_1( ID integer primary key au

toincrement, name nvarchar(32) )”, NULL, NULL, errmsg );

if(result != SQLITE_OK )

{

printf( “创建表失败,错误码:%d,错误原因:%s\n”, result, errmsg );

}

//插入一些记录

result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路’ )

”, 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( “插入记录失败,错误码:%d,错误原因:%s\n”, result, errmsg );

}

result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车’

)”, 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( “插入记录失败,错误码:%d,错误原因:%s\n”, result, errmsg );

}

result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车’

)”, 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( “插入记录失败,错误码:%d,错误原因:%s\n”, result, errmsg );

}

//开始查询数据库

result = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, NULL, errm

sg );

//关闭数据库

sqlite3_close( db );

return 0;

}

通过上面的例子,应该可以知道如何打开一个数据库,如何做数据库基本操作。

有这些知识,基本上可以应付很多数据库操作了。

i.3 不使用回调查询数据库

上面介绍的sqlite3_exec 是使用回调来执行select 操作。还有一个方法可以直接查询

而不需要回调。但是,我个人感觉还是回调好,因为代码可以更加整齐,只不过用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成static

的(要问为什么?这又是C++基础了。C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的sqlite 回调函数的参数不相符。只有当把成员函数声明成static 时,它才没有

多余的隐含的this参数)。

虽然回调显得代码整齐,但有时候你还是想要非回调的select 查询。这可以通过sqlit

e3_get_table 函数做到。

int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, i

nt *ncolumn, char **errmsg );

第1个参数不再多说,看前面的例子。

第2个参数是sql 语句,跟sqlite3_exec 里的sql 是一样的。是一个很普通的以\0结尾

的char *字符串。

第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。下面用例子来说事。

第4个参数是查询出多少条记录(即查出多少行)。

第5个参数是多少个字段(多少列)。

第6个参数是错误信息,跟前面一样,这里不多说了。

下面给个简单例子:

int main( int , char ** )

{

sqlite3 * db;

int result;

char * errmsg = NULL;

char **dbResult; //是char ** 类型,两个*号

int nRow, nColumn;

int i , j;

int index;

result = sqlite3_open( “c:\\Dcg_database.db”, &db );

if( result != SQLITE_OK )

{

//数据库打开失败

return -1;

}

//数据库操作代码

//假设前面已经创建了MyTable_1 表

//开始查询,传入的dbResult 已经是char **,这里又加了一个& 取地址符,传递进去

的就成了char ***

result = sqlite3_get_table( db, “select * from MyTable_1”, &dbResult, &nRow,

&nColumn, &errmsg );

if( SQLITE_OK == result )

{

//查询成功

index = nColumn; //前面说过dbResult 前面第一行数据是字段名称,从nColumn

索引开始才是真正的数据

printf( “查到%d条记录\n”, nRow );

for( i = 0; i < nRow ; i++ )

{

printf( “第%d 条记录\n”, i+1 );

for( j = 0 ; j < nColumn; j++ )

{

printf( “字段名:%s ?> 字段值:%s\n”, dbResult[j], dbRes

ult [index] );

++index; // dbResult 的字段值是连续的,从第0索引到第nColumn - 1

索引都是字段名称,从第nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示

}

printf( “-------\n” );

}

}

//到这里,不论数据库查询是否成功,都释放char** 查询结果,使用sqlite 提供的功

能来释放

sqlite3_free_table( dbResult );

//关闭数据库

sqlite3_close( db );

return 0;

}

到这个例子为止,sqlite3 的常用用法都介绍完了。

用以上的方法,再配上sql 语句,完全可以应付绝大多数数据库需求。

但有一种情况,用上面方法是无法实现的:需要insert、select 二进制。当需要处理二进

制数据时,上面的方法就没办法做到。下面这一节说明如何插入二进制数据

(2)操作二进制

sqlite 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt * 。

这个数据类型记录了一个“sql语句”。为什么我把“sql语句” 用双引号引起来?因为

你可以把sqlite3_stmt * 所表示的内容看成是sql语句,但是实际上它不是我们所熟知

的sql语句。它是一个已经把sql语句解析了的、用sqlite自己标记记录的内部数据结构。正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。当然,把二进制数据插到sqlite3_stmt 结构里可不能直接memcpy ,也不能像std::string 那样用

+ 号。必须用sqlite 提供的函数来插入。

i.1 写入二进制

下面说写二进制的步骤。

要插入二进制,前提是这个表的字段的类型是blob 类型。我假设有这么一张表:

create table Tbl_2( ID integer, file_content blob )

首先声明

sqlite3_stmt * stat;

然后,把一个sql 语句解析到stat 结构里去:

sqlite3_prepare( db, “insert into Tbl_2( ID, file_content) values( 10, ? )”,

-1, &stat, 0 );

上面的函数完成sql 语句的解析。第一个参数跟前面一样,是个sqlite3 * 类型变量,

第二个参数是一个sql 语句。

这个sql 语句特别之处在于values 里面有个? 号。在sqlite3_prepare函数里,?号表

示一个未定的值,它的值等下才插入。

第三个参数我写的是-1,这个参数含义是前面sql 语句的长度。如果小于0,sqlite会自

动计算它的长度(把sql语句当成以\0结尾的字符串)。

第四个参数是sqlite3_stmt 的指针的指针。解析以后的sql语句就放在这个结构里。

第五个参数我也不知道是干什么的。为0就可以了。

如果这个函数执行成功(返回值是SQLITE_OK 且stat 不为NULL ),那么下面就可以开

始插入二进制数据。

sqlite3_bind_blob( stat, 1, pdata, (int)(length_of_data_in_bytes), NULL ); //

pdata为数据缓冲区,length_of_data_in_bytes为数据大小,以字节为单位

这个函数一共有5个参数。

第1个参数:是前面prepare得到的sqlite3_stmt * 类型变量。

第2个参数:?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变bind_blob 函数第2个参数。这个参数我写1,表示这里插入的值要替换st at 的第一个?号(这里的索引从1开始计数,而非从0开始)。如果你有多个?号,就写多个bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sq lite为它取值null。

第3个参数:二进制数据起始指针。

第4个参数:二进制数据的长度,以字节为单位。

第5个参数:是个析够回调函数,告诉sqlite当把数据处理完后调用此函数来析够你的数据。这个参数我还没有使用过,因此理解也不深刻。但是一般都填NULL,需要释放的内存自己用代码来释放。

bind完了之后,二进制数据就进入了你的“sql语句”里了。你现在可以把它保存到数据库里:

int result = sqlite3_step( stat );

通过这个语句,stat 表示的sql语句就被写到了数据库里。

最后,要把sqlite3_stmt 结构给释放:

sqlite3_finalize( stat ); //把刚才分配的内容析构掉

i.2 读出二进制

下面说读二进制的步骤。

跟前面一样,先声明sqlite3_stmt * 类型变量:

sqlite3_stmt * stat;

然后,把一个sql 语句解析到stat 结构里去:

sqlite3_prepare( db, “select * from Tbl_2”, -1, &stat, 0 );

当prepare 成功之后(返回值是SQLITE_OK ),开始查询数据。

int result = sqlite3_step( stat );

这一句的返回值是SQLITE_ROW 时表示成功(不是SQLITE_OK )。

你可以循环执行sqlite3_step 函数,一次step 查询出一条记录。直到返回值不为SQL ITE_ROW 时表示查询结束。

然后开始获取第一个字段:ID 的值。ID是个整数,用下面这个语句获取它的值:

int stat, 0 ); //第2个参数表示获取第几个字段内容,从0开始计算,因为我的表的ID字

段是第一个字段,因此这里我填0

下面开始获取file_content 的值,因为file_content 是二进制,因此我需要得到它的

指针,还有它的长度:

const void * pFileContent = sqlite3_column_blob( stat, 1 );

int len = sqlite3_column_bytes( stat, 1 );

这样就得到了二进制的值。

把pFileContent 的内容保存出来之后,不要忘了释放sqlite3_stmt 结构:

sqlite3_finalize( stat ); //把刚才分配的内容析构掉

i.3 重复使用sqlite3_stmt 结构

如果你需要重复使用sqlite3_prepare 解析好的sqlite3_stmt 结构,需要用函数:sq

lite3_reset。

result = sqlite3_reset(stat);

这样,stat 结构又成为sqlite3_prepare 完成时的状态,你可以重新为它bind 内容。https://www.doczj.com/doc/e99604632.html, 网上down下来的sqlite3.c 文件,直接摸索出这些接口的实现,我认为

我还没有这个能力。

好在网上还有一些代码已经实现了这个功能。通过参照他们的代码以及不断编译中vc给出的错误提示,最终我把整个接口整理出来。

实现这些预留接口不是那么容易,要重头说一次怎么回事很困难。我把代码都写好了,直接把他们按我下面的说明拷贝到sqlite3.c 文件对应地方即可。我在下面也提供了sqlit

e3.c 文件,可以直接参考或取下来使用。

这里要说一点的是,我另外新建了两个文件:crypt.c和crypt.h。

其中crypt.h如此定义:

#ifndef DCG_SQLITE_CRYPT_FUNC_

#define DCG_SQLITE_CRYPT_FUNC_

/***********

董淳光写的SQLITE 加密关键函数库

***********/

/***********

关键加密函数

***********/

int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char

* key, unsigned int len_of_key );

/***********

关键解密函数

***********/

int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const cha

r * key, unsigned int len_of_key );

#endif

其中的crypt.c 如此定义:

#include "./crypt.h"

#include "memory.h"

/***********

关键加密函数

***********/

int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char

* key, unsigned int len_of_key )

{

return 0;

}

/***********

关键解密函数

***********/

int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const cha

r * key, unsigned int len_of_key )

{

return 0;

}

这个文件很容易看,就两函数,一个加密一个解密。传进来的参数分别是待处理的数据、

数据长度、密钥、密钥长度。

处理时直接把结果作用于pData 指针指向的内容。

你需要定义自己的加解密过程,就改动这两个函数,其它部分不用动。扩展起来很简单。

这里有个特点,data_len 一般总是1024 字节。正因为如此,你可以在你的算法里使用一

些特定长度的加密算法,比如AES要求被加密数据一定是128位(16字节)长。这个1024不是碰巧,而是Sqlite 的页定义是1024字节,在sqlite3.c文件里有定义:

# define SQLITE_DEFAULT_PAGE_SIZE 1024

你可以改动这个值,不过还是建议没有必要不要去改它。

上面写了两个扩展函数,如何把扩展函数跟Sqlite 挂接起来,这个过程说起来比较麻烦

。我直接贴代码。

分3个步骤。

首先,在sqlite3.c 文件顶部,添加下面内容:

#ifdef SQLITE_HAS_CODEC

#include "./crypt.h"

/***********

用于在sqlite3 最后关闭时释放一些内存

***********/

void sqlite3pager_free_codecarg(void *pArg);

#endif

这个函数之所以要在sqlite3.c 开头声明,是因为下面在sqlite3.c 里面某些函数里要

插入这个函数调用。所以要提前声明。

其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,要找到它的实现代码(而不

是声明代码)。

实现代码里一开始是:

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT

/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to

** malloc() must have already been made by this thread before it gets

** to this point. This means the ThreadData must have been allocated already

** so that ThreadData.nAlloc can be set.

*/

ThreadData *pTsd = sqlite3ThreadData();

assert( pPager );

assert( pTsd && pTsd->nAlloc );

#endif

需要在这部分后面紧接着插入:

#ifdef SQLITE_HAS_CODEC

sqlite3pager_free_codecarg(pPager->pCodecArg);

#endif

这里要注意,sqlite3PagerClose 函数大概也是 3.3.17版本左右才改名的,以前版本里是

叫“sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”

是搜不到的。

类似的还有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”

、“sqlite3pager_pagecount”等都是老版本函数,它们在pager.h 文件里定义。新版本

对应函数是在sqlite3.h 里定义(因为都合并到sqlite3.c和sqlite3.h两文件了)。所

以,如果你在使用老版本的sqlite,先看看pager.h 文件,这些函数不是消失了,也不是

新蹦出来的,而是老版本函数改名得到的。

最后,往sqlite3.c 文件下找。找到最后一行:

/************** End of main.c ************************************************

/

在这一行后面,接上本文最下面的代码段。

这些代码很长,我不再解释,直接接上去就得了。

唯一要提的是DeriveKey 函数。这个函数是对密钥的扩展。比如,你要求密钥是128位,

即是16字节,但是如果用户只输入1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,使之符合16字节的要求。

DeriveKey 函数就是做这个扩展的。有人把接收到的密钥求md5,这也是一个办法,因为m

d5运算结果固定16字节,不论你有多少字符,最后就是16字节。这是md5算法的特点。但是我不想用md5,因为还得为它添加包含一些md5 的.c或.cpp文件。我不想这么做。我自己

写了一个算法来扩展密钥,很简单的算法。当然,你也可以使用你的扩展方法,也而可以

使用md5 算法。只要修改DeriveKey 函数就可以了。

在DeriveKey 函数里,只管申请空间构造所需要的密钥,不需要释放,因为在另一个函数里有释放过程,而那个函数会在数据库关闭时被调用。参考我的DeriveKey 函数来申请内存。

这里我给出我已经修改好的sqlite3.c 和sqlite3.h 文件。

如果太懒,就直接使用这两个文件,编译肯定能通过,运行也正常。当然,你必须按我前面提的,新建crypt.h 和crypt.c 文件,而且函数要按我前面定义的要求来做。

i.3 加密使用方法:

现在,你代码已经有了加密功能。

你要把加密功能给用上,除了改sqlite3.c 文件、给你工程添加SQLITE_HAS_CODEC 宏,还得修改你的数据库调用函数。

前面提到过,要开始一个数据库操作,必须先sqlite3_open 。

加解密过程就在sqlite3_open 后面操作。

假设你已经sqlite3_open 成功了,紧接着写下面的代码:

int i;

//添加、使用密码

i = sqlite3_key( db, "dcg", 3 );

//修改密码

i = sqlite3_rekey( db, "dcg", 0 );

用sqlite3_key 函数来提交密码。

第1个参数是sqlite3 * 类型变量,代表着用sqlite3_open 打开的数据库(或新建数据库)。

第2个参数是密钥。

第3个参数是密钥长度。

用sqlite3_rekey 来修改密码。参数含义同sqlite3_key。

实际上,你可以在sqlite3_open函数之后,到sqlite3_close 函数之前任意位置调用sq lite3_key 来设置密码。

但是如果你没有设置密码,而数据库之前是有密码的,那么你做任何操作都会得到一个返回值:SQLITE_NOTADB,并且得到错误提示:“file is encrypted or is not a databas

e”。

只有当你用sqlite3_key 设置了正确的密码,数据库才会正常工作。

如果你要修改密码,前提是你必须先sqlite3_open 打开数据库成功,然后sqlite3_key

设置密钥成功,之后才能用sqlite3_rekey 来修改密码。

如果数据库有密码,但你没有用sqlite3_key 设置密码,那么当你尝试用sqlite3_reke

y 来修改密码时会得到SQLITE_NOTADB 返回值。

如果你需要清空密码,可以使用:

//修改密码

i = sqlite3_rekey( db, NULL, 0 );

来完成密码清空功能。

i.4 sqlite3.c 最后添加代码段

/***

董淳光定义的加密函数

***/

#ifdef SQLITE_HAS_CODEC

/***

加密结构

***/

#define CRYPT_OFFSET 8

typedef struct _CryptBlock

{

BYTE* ReadKey; // 读数据库和写入事务的密钥

BYTE* WriteKey; // 写入数据库的密钥

int PageSize; // 页的大小

BYTE* Data;

} CryptBlock, *LPCryptBlock;

#ifndef DB_KEY_LENGTH_BYTE /*密钥长度*/

#define DB_KEY_LENGTH_BYTE 16 /*密钥长度*/

#endif

#ifndef DB_KEY_PADDING /*密钥位数不足时补充的字符*/

#define DB_KEY_PADDING 0x33 /*密钥位数不足时补充的字符*/

#endif

/*** 下面是编译时提示缺少的函数***/

/** 这个函数不需要做任何处理,获取密钥的部分在下面DeriveKey 函数里实现**/ void sqlite3CodecGetKey(sqlite3* db, int nDB, void** Key, int* nKey)

{

return ;

}

/*被sqlite 和sqlite3_key_interop 调用, 附加密钥到数据库.*/

int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen);

/**

这个函数好像是sqlite 3.3.17前不久才加的,以前版本的sqlite里没有看到这个函数

这个函数我还没有搞清楚是做什么的,它里面什么都不做直接返回,对加解密没有影响**/

void sqlite3_activate_see(const char* right )

{

return;

}

int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);

int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey);

/***

下面是上面的函数的辅助处理函数

***/

// 从用户提供的缓冲区中得到一个加密密钥

// 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展

static unsigned char * DeriveKey(const void *pKey, int nKeyLen);

//创建或更新一个页的加密算法索引.此函数会申请缓冲区.

static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryp

tBlock pExisting);

//加密/解密函数, 被pager调用

void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode) ;

//设置密码函数

int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)

;

// 修改密码函数

int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySiz e);

//销毁一个加密块及相关的缓冲区,密钥.

static void DestroyCryptBlock(LPCryptBlock pBlock);

static void * sqlite3pager_get_codecarg(Pager *pPager);

void sqlite3pager_set_codec(Pager *pPager,void *(*xCodec)(void*,void*,Pgno,int ),void *pCodecArg );

//加密/解密函数, 被pager调用

void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode) {

LPCryptBlock pBlock = (LPCryptBlock)pArg;

unsigned int dwPageSize = 0;

if (!pBlock) return data;

// 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.

if (nMode != 2)

{

PgHdr *pageHeader;

pageHeader = DATA_TO_PGHDR(data);

if (pageHeader->pPager->pageSize != pBlock->PageSize)

{

CreateCryptBlock(0, pageHeader->pPager, pBlock);

}

}

switch(nMode)

{

case 0: // Undo a "case 7" journal file encryption

case 2: //重载一个页

case 3: //载入一个页

if (!pBlock->ReadKey) break;

dwPageSize = pBlock->PageSize;

My_DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE ) ; /*调用我的解密函数*/

break;

case 6: //加密一个主数据库文件的页

if (!pBlock->WriteKey) break;

memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);

data = pBlock->Data + CRYPT_OFFSET;

dwPageSize = pBlock->PageSize;

My_Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE )

; /*调用我的加密函数*/

break;

case 7: //加密事务文件的页

/*在正常环境下, 读密钥和写密钥相同. 当数据库是被重新加密的,读密钥和写密钥未必相同.

回滚事务必要用数据库文件的原始密钥写入.因此,当一次回滚被写入,总是用数据库的读密钥,

这是为了保证与读取原始数据的密钥相同.

*/

if (!pBlock->ReadKey) break;

memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);

data = pBlock->Data + CRYPT_OFFSET;

dwPageSize = pBlock->PageSize;

My_Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );

/*调用我的加密函数*/

break;

}

return data;

}

//销毁一个加密块及相关的缓冲区,密钥.

static void DestroyCryptBlock(LPCryptBlock pBlock)

{

//销毁读密钥.

if (pBlock->ReadKey){

sqliteFree(pBlock->ReadKey);

}

//如果写密钥存在并且不等于读密钥,也销毁.

if (pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey){

sqliteFree(pBlock->WriteKey);

}

if(pBlock->Data){

sqliteFree(pBlock->Data);

}

//释放加密块.

sqliteFree(pBlock);

}

static void * sqlite3pager_get_codecarg(Pager *pPager)

{

return (pPager->xCodec) ? pPager->pCodecArg: NULL;

}

// 从用户提供的缓冲区中得到一个加密密钥

static unsigned char * DeriveKey(const void *pKey, int nKeyLen)

{

unsigned char * hKey = NULL;

int j;

if( pKey == NULL || nKeyLen == 0 )

{

return NULL;

}

hKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + 1 );

if( hKey == NULL )

{

return NULL;

}

hKey[ DB_KEY_LENGTH_BYTE ] = 0;

if( nKeyLen < DB_KEY_LENGTH_BYTE )

{

memcpy( hKey, pKey, nKeyLen ); //先拷贝得到密钥前面的部分

j = DB_KEY_LENGTH_BYTE - nKeyLen;

//补充密钥后面的部分

memset( hKey + nKeyLen, DB_KEY_PADDING, j );

}

else

{ //密钥位数已经足够,直接把密钥取过来

memcpy( hKey, pKey, DB_KEY_LENGTH_BYTE );

}

return hKey;

}

//创建或更新一个页的加密算法索引.此函数会申请缓冲区.

static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryp tBlock pExisting)

{

LPCryptBlock pBlock;

if (!pExisting) //创建新加密块

{

pBlock = sqliteMalloc(sizeof(CryptBlock));

memset(pBlock, 0, sizeof(CryptBlock));

pBlock->ReadKey = hKey;

pBlock->WriteKey = hKey;

pBlock->PageSize = pager->pageSize;

pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFS ET);

}

else //更新存在的加密块

{

pBlock = pExisting;

if ( pBlock->PageSize != pager->pageSize && !pBlock->Data){

sqliteFree(pBlock->Data);

pBlock->PageSize = pager->pageSize;

pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT _OFFSET);

}

}

memset(pBlock->Data, 0, pBlock->PageSize + CRYPT_OFFSET);

return pBlock;

}

/*

** Set the codec for this pager

*/

void sqlite3pager_set_codec(

Pager *pPager,

void *(*xCodec)(void*,void*,Pgno,int),

void *pCodecArg

)

{

pPager->xCodec = xCodec;

pPager->pCodecArg = pCodecArg;

}

int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)

{

return sqlite3_key_interop(db, pKey, nKey);

}

int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)

{

return sqlite3_rekey_interop(db, pKey, nKey);

}

/*被sqlite 和sqlite3_key_interop 调用, 附加密钥到数据库.*/

int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen) {

int rc = SQLITE_ERROR;

unsigned char* hKey = 0;

//如果没有指定密匙,可能标识用了主数据库的加密或没加密.

if (!pKey || !nKeyLen)

{

if (!nDb)

{

return SQLITE_OK; //主数据库, 没有指定密钥所以没有加密.

}

else //附加数据库,使用主数据库的密钥.

{

//获取主数据库的加密块并复制密钥给附加数据库使用

LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqli

te3BtreePager(db->aDb[0].pBt));

if (!pBlock) return SQLITE_OK; //主数据库没有加密

if (!pBlock->ReadKey) return SQLITE_OK; //没有加密

memcpy(pBlock->ReadKey, &hKey, 16);

}

}

else //用户提供了密码,从中创建密钥.

{

hKey = DeriveKey(pKey, nKeyLen);

}

//创建一个新的加密块,并将解码器指向新的附加数据库.

if (hKey)

{

LPCryptBlock pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db->aDb [nDb].pBt), NULL);

sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Cod ec, pBlock);

rc = SQLITE_OK;

}

return rc;

}

// Changes the encryption key for an existing database.

int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySiz e)

{

Btree *pbt = db->aDb[0].pBt;

Pager *p = sqlite3BtreePager(pbt);

LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p); unsigned char * hKey = DeriveKey(pKey, nKeySize);

int rc = SQLITE_ERROR;

if (!pBlock && !hKey) return SQLITE_OK;

//重新加密一个数据库,改变pager的写密钥, 读密钥依旧保留.

if (!pBlock) //加密一个未加密的数据库

{

pBlock = CreateCryptBlock(hKey, p, NULL);

pBlock->ReadKey = 0; // 原始数据库未加密

sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);

}

else // 改变已加密数据库的写密钥

{

pBlock->WriteKey = hKey;

}

// 开始一个事务

rc = sqlite3BtreeBeginTrans(pbt, 1);

if (!rc)

{

// 用新密钥重写所有的页到数据库。

Pgno nPage = sqlite3PagerPagecount(p);

Pgno nSkip = PAGER_MJ_PGNO(p);

void *pPage;

Pgno n;

for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)

{

if (n == nSkip) continue;

rc = sqlite3PagerGet(p, n, &pPage);

if(!rc)

{

rc = sqlite3PagerWrite(pPage);

sqlite3PagerUnref(pPage);

}

}

}

// 如果成功,提交事务。

if (!rc)

{

rc = sqlite3BtreeCommit(pbt);

}

// 如果失败,回滚。

if (rc)

{

sqlite3BtreeRollback(pbt);

}

// 如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。if (!rc)

{

if (pBlock->ReadKey)

{

sqliteFree(pBlock->ReadKey);

}

pBlock->ReadKey = pBlock->WriteKey;

}

else// 如果失败,销毁当前的写密钥,并恢复为当前的读密钥。{

if (pBlock->WriteKey)

{

sqliteFree(pBlock->WriteKey);

}

pBlock->WriteKey = pBlock->ReadKey;

}

// 如果读密钥和写密钥皆为空,就不需要再对页进行编解码。

// 销毁加密块并移除页的编解码器

if (!pBlock->ReadKey && !pBlock->WriteKey)

{

sqlite3pager_set_codec(p, NULL, NULL);

DestroyCryptBlock(pBlock);

}

return rc;

}

/***

下面是加密函数的主体

***/

int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)

{

return sqlite3CodecAttach(db, 0, pKey, nKeySize);

}

// 释放与一个页相关的加密块

void sqlite3pager_free_codecarg(void *pArg)

{

if (pArg)

DestroyCryptBlock((LPCryptBlock)pArg);

}

#endif //#ifdef SQLITE_HAS_CODEC

五、后记

写此教程,可不是一个累字能解释。

但是我还是觉得欣慰的,因为我很久以前就想写sqlite 的教程,一来自己备忘,二而已造福大众,大家不用再走弯路。

本人第一次写教程,不足的地方请大家指出。

本文可随意转载、修改、引用。但无论是转载、修改、引用,都请附带我的名字:董淳光。以示对我劳动的肯定

sqlite3常用命令及语法

https://www.doczj.com/doc/e99604632.html,/linchunhua/article/details/7184439 sqlite数据库只用一个文件就ok,小巧方便,所以是一个非常不错的嵌入式数据库,SQLite 大量的被用于手机,PDA,MP3播放器以及机顶盒设备。 Mozilla Firefox使用SQLite作为数据库。 Mac计算机中的包含了多份SQLite的拷贝,用于不同的应用。 PHP将SQLite作为内置的数据库。 Skype客户端软件在内部使用SQLite。 SymbianOS(智能手机操作平台的领航)内置SQLite。 AOL邮件客户端绑定了SQLite。 Solaris 10在启动过程中需要使用SQLite。 McAfee杀毒软件使用SQLite。 iPhones使用SQLite。 Symbian和Apple以外的很多手机生产厂商使用SQLite。 下面就sqlite中的常用命令和语法介绍 https://www.doczj.com/doc/e99604632.html,/download.html可下载不同操作系统的相关版本sqlite gedit 也可以使用火狐中的插件sqlite manager 新建数据库 sqlite3 databasefilename 检查databasefilename是否存在,如果不存在就创建并进入数据库(如果直接退出,数据库文件不会创建)如果已经存在直接进入数据库对数据库进行操作 sqlite中命令: 以.开头,大小写敏感(数据库对象名称是大小写不敏感的) .exit .help 查看帮助针对命令 .database 显示数据库信息;包含当前数据库的位置 .tables 或者.table 显示表名称没有表则不显示 .schema 命令可以查看创建数据对象时的SQL命令; .schema databaseobjectname查看创建该数据库对象时的SQL的命令;如果没有这个数据库对象就不显示内容,不会有错误提示 .read FILENAME 执行指定文件中的SQL语句 .headers on/off 显示表头默认off .mode list|column|insert|line|tabs|tcl|csv 改变输出格式,具体如下 sqlite> .mode list sqlite> select * from emp; 7369|SMITH|CLERK|7902|17-12-1980|800||20 7499|ALLEN|SALESMAN|7698|20-02-1981|1600|300|30 如果字段值为NULL 默认不显示也就是显示空字符串

sqlite3使用教程

Sqlite3教程 一、基本命令 1、进入命令行环境: 显示版本号,并告诉每一条SQL语句必须用分号;结尾2、命令行帮助:

3、退出命令行环境 或者 二、数据库相关命令 1、创建(或打开)一个新的数据库:文件名 若文件存在,刚打开该文件;若文件不存在,则创建一个*.db数据库文件。 导入SQL语句文件。

、列出所有数据表: 4、显示数据库结构: 用一些SQL语句描述数据库的结构。 5、显示表的结构:表名 6、导入数据:文件名表名 若导入csv文件,设置分隔符为逗号。 、导出数据:文件名 查询结果默认在终端显示,查询表格结构,语句查询表格数据。设置查询目标后,查询结果显示在设置的文件中 文件名 然后输入sql查询语句,查询的结果显示在设置的文件中,不在终端显示 运行恢复导出到终端(标准输出)。 导出数据到excle表格中 设置分隔符为逗号: 设置导出文件名,后缀为csv: 查询语句:表名

三、数据显示命令 运行表名,显示全表的内容 1.设置分隔符:分隔符 默认分隔符是“|”。 2.设置显示模式:模式

默认的是list显示模式,一般使用column模式。 3.显示标题栏: 4.设置每一列的显示宽度: 5.列出当前显示格式设置情况: 四、数据库基本操作 1.数据库定义语言DDL 在关系型数据库中,数据库中的表table、视图、索引、关系和触发器等等,构成了数据库的架构。在SQL语句中,专门有一些语句用来定义数据库架构,这些语句被称为“数据库定义语言”,即DDL。 SQLite数据库引擎支持下列三种DDL语句: ●CREATE:创建 ●ALTER TABLE:改变表的结构 ●DROP:删除

SQLITE3的操作方法及应用

数据库的操作 我们在这个项目中使用的是SQLITE3数据库软件。 通过使用SQLITE3进行创建数据库,创建表,插入记录,查询记录,更新记录,关闭数据库等操作来实现将相应的数据存入数据库中。 1.打开数据库,创建表 1.1sqlite*db;定义一个sqlite*的变量 sqlite3_open(“./link.db”,&db); 在当前目录下打开一个名为link.db的数据库,若是没有则在当前目录下创建一个名为link.db 的数据库。 1.2sql="create table weblink(id integer primary key,domain text,page text,fromdomain text,status integer);" 在已打开的数据库中创建一个名weblink的表。表的属性如下: id integer primary key:ID号(表中黙认包含的) domain text:域名 page text:子网页 fromdomain text:源域名 status integer:状态标志 1.3sqlite3_exec(db,sql,NULL,NULL,NULL); 执行一条sql语句的函数。 函数原型:int sqlite3_exec(sqlite3*,const char*sql,sqlite3_callback,void*,char**errmsg) 第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表

sqlite 基本操作 全

sqlite3本地数据库学习 sqlite3只是一个轻型的嵌入式数据库引擎,占用资源非常低,处理速度比mysql还快,专门用于移动设备上进行适量的数据存取,它只是个文件,不需要服务器进程。 常用术语:表(table)、字段(colum,列,属性)、记录(row,record) 关键字:select、insert、updete、delete、from、creat、where、desc、order、by、group、table、alter、view、index等。 1、安装sqlite3 sudo()apt-get()install()sqlite3 2、存储类型 integer 整型:int,shoert,long text 文本字符串:string real 浮点型:float,double blob 二进制 3、字段结束 not null:字段的值不能为空 unique:字段的值必须是唯一的 default:指定字段的默认值 primarykey:主键,用来唯一的标识某条记录,相当于记录的身份证。主键可以是一个或多个字段,应由计算机自动生成和管理。主键字段默认包含了not null和unique两个约束。 autoincrement:当主键是integer类型时,应该增加autoincrement约束,能实现主键值的自动增长。 外键:利用外键可以用来建立表与表之间的联系,一般是一张表的某个字段,引用着另一张表的主键。 4、创建数据库usr.db在当前目录下 sqlite3()usr.db 5、创建表格,表格内容以树状存储 create()table()表名(字段名1()字段类型1,字段名2()字段类型2...) 6、数据库中不能使用关键字命名表和字段,不区分大小写,每条语句后加";"结尾 7、删除表格 drop()table()表名 8、向表格里添加数据 insert()into()表名(字段1,字段2...)values(字段1的值,字段2的值...) 8、修改表中的数据 updata()表名()set()字段1=字段1的值,字段2=字段2的值... //将字段为name全部修改成'Tom' updata()stu()set()name='Tom'; //将字段为id=1001的字段name修改成'Tom' updata()stu()set()name='Tom'()where()id=1001; //将字段为id=1001同时字段name='lisi'的字段name修改成'Tom' updata()stu()set()name='Tom'()where()id=1001()and()name='lisi'; 9、删除表中的数据

QSQLite 数据库

这里我们只是演示了一下使用这个框架完成最简单的程序的过程,只起到抛砖引玉的作用。这个框架很复杂,但是功能也很强大,Qt Creator中自带了几个相关的例子(在帮助中查找Graphics View Examples即可),你可以参考一下。因为篇幅问题,我们就只讲这么多,如果以后有机会,我会推出一个相关的专题来讲述这个框架。 分类:Qt系列教程作者: yafeilinux 日期:四月 30th, 2010. 3,006 views Tags: 2D绘图, creator, qt, yafeilinux, 教程

二十一、Qt数据库(一)简介 本文章原创于https://www.doczj.com/doc/e99604632.html,转载请注明出处。 从今天开始我们学习Qt数据库编程的内容。 先说明:我们以后使用现在最新的基于Qt 4.6.2的Qt Creator 1.3.1 Windows版本,该版本是2010年2月17日发布的。 数据库几乎是每个较大的软件所必须应用的,而在Qt中也使用QtSql模块实现了对数据库的完美支持。我们在Qt Creator的帮助中查找QtSql Module,其内容如下图: 可以看到这个模块是一组类的集合,使用这个模块我们需要加入头文件#include ,而在工程文件中需要加入一行代码:QT += sql 这里每个类的作用在后面都有简单的介绍,你也可以进入其中查看其详细内容。下面我们先简单的说一下QSqlDatabase类和QSqlQuery类。 QSqlDatabase类实现了数据库连接的操作,现在Qt支持的数据库类型有如下几种: 而现在我们使用的免费的Qt只提供了SQLite和ODBC数据库的驱动(我们可以在Qt Creator 安装目录下的qt\plugins\sqldrivers文件夹下查看),而其他数据库的驱动需要我们自己添加。SQLite是一个小巧的嵌入式数据库,关于它的介绍你可以自己在网上查找。 QSqlQuery类用来执行SQL语句。(关于SQL语句:在我的教程中只会出现很简单的SQL语句,你没有相关知识也可以看懂,但是如果想进行深入学习,就需要自己学习相关知识了。)

SQLITE最基本操作

SQLite数据库的基本操作 main.xml(主布局)

android:orientation="vertical">

sqlite3在Linux下的安装和使用

sqlite3在Linux下的安装和使用 2008-06-10 16:51:14| 分类:sqlite|字号订阅 一.sqlite3的安装和配置 下载sqlite3源码包 tar xvfz sqlite-src-3.3.5 cd sqlite-3.3.5 ./configure –no-tcl make (如果在arm板上用需修改Makefile,在LIBS 项中加入–L/usr/local/arm/3.3.2/lib 保存后退出.然后再make) 安装成功后生成文件将被复制到指定目录 再加入一个环境变量 vi /etc/profile 在export区域加入SQLITE3_PATH=/usr/local/sqlite-3.3.5 保存后退出 source /etc/profile 有用文件分别为$SQLITE3_PATH/include/sqlite3.h 头文件 $SQLITE3_PATH/bin/sqlite3 可执行文件 $SQLITE3_PATH/lib/libsqlite3.a https://www.doczj.com/doc/e99604632.html, libsqlite3.so -> libsqlite3.so.0.8.6 libsqlite3.so.0 -> libsqlite3.so.0.8.6 libsqlite3.so.0.8.6 在程序使用到数据库 #include

在.pro文件中添加: INCLUDEPATH +=$(SQLITE3_PATH)/include DEPENDPATH +=$(SQLITE3_PATH)/include LIBS +=-L$(SQLITE3_PATH)/lib LIBS +=-lsqlite3 保存后退出 tmake hello.pro –o Makefile make 二.程序的编写: sqlite3 *db; int rc = sqlite3_open(“data.db”,&db); //打开数据库data.db if(rc!=SQLITE_OK);//打开失败 创建表rc = sqlite3_exec(db,”create table student(ID integer primarykey,name nvarchar(32))”,NULL,NULL,&mrrmsg); 插入rc = sqlite3_exec(db,”insert into student values(…3?,?Zhang San?)”,0,0,&mrrmsg); 修改rc = sqlite3_exec(db,”update student set name=?Li Si? where ID=?4?”,0,0,&mrrmsg);删除rc = sqlite3_exec(db,”delete * from student where name=?Wang Wu?”,0,0,&mrrmsg); 查询是重点 回调式查询rc = sqlite3_exec(db,”select * from student where ID>2 and name<>?Zhang San?”,LoadInfo,NULL,&mrrmsg); 查询的结果通过LoadInfo函数来导出

Unity3D教程:Unity3D与Sqlite数据库直连

Unity3D教程:Unity3D与Sqlite数据库直连 Posted on 2013年01月10日 by U3d / Unity3D 基础教程/被围观 475 次环境介绍: Windows7,Unity3D,SQLite Expert Personal 3 开发语言: JavaScript 需要的dll文件: Mono.Data.Sqlite.dll和sqlite3.dll,dll文件位置,截图: Unity3D教程:Unity3D与Sqlite数据库直连一定要在这个目录下,请保持一致。 如果需要将编译好的程序发布成功的话,需要改一些地方,具体见下面的截图:

Unity3D教程:Unity3D与Sqlite数据库直连 要改动的地方已用红色标记,注意这个要改成.NET2.0,这样才能够发布的。系统默认的不是.NET2.0,这一点要注意!!! 下面来看下代码吧,先看下如何创建数据库的代码,这一篇代码是不用挂到任何对象上面去的,你只用把它当成一个工具即可。如下所示: /* Javascript class for accessing SQLite objects. To use it, you need to make sure you COPY Mono.Data.SQLiteClient.dll from wherever it lives in your Unity directory

to your project's Assets folder Originally created by dklompmaker in 2009 https://www.doczj.com/doc/e99604632.html,/threads ... sier-Database-Stuff Modified 2011 by Alan Chatham */ //#pragma strict /* 代码描述 *本代码是为了在Windows环境下运行unity3d和Sqlite数据库而写的;实现的基本功能是unity3d能够与数据库之间进行基本的通信,比如说:在数据库中的数据被改变了以后,unity3d中得到的数据也会在刷新了之后跟着改变;这只是一个基本的核心的技术,为的是能够应用在大型的unity3d项目中,能够存储场景中的项目的属性,在需要改变对象的属性或增加、减少等对象时能够很方便的用得上。要实现本代码。首先需要一些dll文件,一个是Mono.Data.SQLiteClient.dll,另外一个是sqlite3.dll,这些文件都能够在unity3d的安装目录中找得到。除此之外,还需要把这两个文件放在你的项目的这个路径下面:\Assets\Plugins\,没有Plugins文件夹就必须创建这个文件夹,然后将这两个dll文件放在该文件夹写。当然,如果你想能够在PC上面发布成可执行文件,还需要改动

SQLite3 API使用大全

SQLite3API使用大全E-mail:18918737 (at) qq dot com,智有不明

前序: (1) 一、版本 (1) 二、基本编译 (2) 三、 SQLITE操作入门 (2) (1)基本流程 (2) (2) SQL语句操作 (4) (3)操作二进制 (8) (4)事务处理 (10) 四、给数据库加密 (10) 五、后记 (25) 前序: Sqlite3 的确很好用。小巧、速度快。但是因为非微软的产品,帮助文档总觉得不够。这些天再次研究它,又有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记。 这里要注明,我是一个跨平台专注者,并不喜欢只用 windows 平台。我以前的工作就是为unix 平台写代码。下面我所写的东西,虽然没有验证,但是我已尽量不使用任何 windows 的东西,只使用标准 C 或标准C++。但是,我没有尝试过在别的系统、别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改。 下面我的代码仍然用 VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合 Vassist )。下面我所说的编译环境,是VC2003。如果读者觉得自己习惯于 unix 下用 vi 编写代码速度较快,可以不用管我的说明,只需要符合自己习惯即可,因为我用的是标准 C 或 C++ 。不会给任何人带来不便。 一、版本 从https://www.doczj.com/doc/e99604632.html,网站可下载到最新的 sqlite 代码和编译版本。我写此文章时,最新代码是 3.3.17 版本。 很久没有去下载 sqlite 新代码,因此也不知道 sqlite 变化这么大。以前很多文件,现在全部合并成一个 sqlite3.c 文件。如果单独用此文件,是挺好的,省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题:此文件太大,快接近7万行代码,VC开它整个机器都慢下来了。如果不需要改它代码,也就不需要打开 sqlite3.c 文件,机器不会慢。但是,下面我要写通过修改 sqlite 代码完成加密功能,那时候就比较痛苦了。如果个人水平较高,建议用些简单的编辑器来编辑,例如 UltraEdit 或 Notepad 。速度会快很多。 二、基本编译 这个不想多说了,在 VC 里新建 dos 控制台空白工程,把 sqlite3.c 和 sqlite3.h 添加到工程,再新建一个 main.cpp 文件。在里面写: extern "C" { #include "./sqlite3.h" }; int main( int , char** ) { return 0; }

Sqlite使用文档

SQLite的配置和使用文档 一.引言: 本文将简要介绍如何在Linux和ARM-Linux平台上移植SQLite嵌入式数据库,以及一些简单的测试案例。 嵌入式数据库采用程序方式直接驱动,而传统数据库则采用引擎响应方式驱动。由于嵌入式数据库的体积通常很小,这使得嵌入式数据库常常应用在移动设备上。 SQLite是一种嵌入式数据库。SQLite的目标是尽量简单,因此它抛弃了传统企业级数据库的种种复杂特性,只实现那些对于数据库而言非常必要的功能。尽管简单性是SQLite追求的首要目标,但是其功能和性能都非常出色由于SQLite具有功能强大、接口简单、速度快、占用空间小等优点,因此特别适合于应用在嵌入式环境中。SQLite在手机、PDA、机顶盒等设备上已获得了广泛应用。 二.软硬件平台: OS:fedora7; 编译器:gcc 版本 4.1.2 20070502 (Red Hat 4.1.2-12): 开发板:基于Sep4020的UB4020EVB(1.6) 开发套件; Linux内核:Linux Kernel v2.6.16: 交叉编译器:gcc version 3.4.1: Sqlite:sqlite-3.3.8 三.PC端编译环境的安装: 此处使用的为SQLite版本为sqlite-3.3.8.tar.gz,可以通过以下方式获得此压缩包https://www.doczj.com/doc/e99604632.html,/sqlite-3.3.8.tar.gz(利用迅雷等工具下载)。 将此压缩包拷贝到/root目录下,在终端中进入此目录,并解压sqlite-3.3.8.tar.gz压缩包:

[root@localhost ~]# cd /root/ [root@localhost ~]# tar -zxvf sqlite-3.3.8.tar.gz 将sqlite-3.3.8更名为sqlit_pc,并进入sqlite_pc目录: [root@localhost ~]# mv sqlite-3.3.8 sqlite_pc [root@localhost ~]# cd sqlite_pc //进入目录后采用默认配置生成Makefile文件: [root@localhost sqlite_pc]# ./configure 配置结束后进行编译并且将所生成的文件安装: [root@localhost sqlite_pc]# make [root@localhost sqlite_pc]# make install Make install 安装以后会生成以下文件,系统默认的目录为/usr/local: lib:libsqlite3.a https://www.doczj.com/doc/e99604632.html, libsqlite3.so libsqlite3.so.0 libsqlite3.so.0.8.6 include:sqlite3.h bin: sqlite3 由于/usr/local为系统路径,此时只要在终端直接输入sqlite3 [数据库名] 即可打开(没有时创建)一个数据库文件。 例1:在终端输入以下语句: [root@localhost sqlite-3.3.8]# sqlite3 prochip.db SQLite version 3.3.8 Enter ".help" for instructions sqlite> 此时就会正确的打开(没有时创建)prochip.db数据库文件。

SQLite Expert Personal使用教程

小蛙今天要介紹一套圖形化的SQLite管理軟體,目前像Android, iOS … 等手持式裝置內部都支援使用SQLite,不外乎是因為它方便、小、速度快,SQLite不像一般MySQL、Oracle、MSSQL這麼複雜,我們可以把SQLite想像成一個檔案(實際上存好之後也只有一個檔案),但這一個檔案又比Microsoft Access有更大的便利性(可以在很多平台使用,不會只鎖定微軟平台),想更了解SQLite可以參考、或者是。是小蛙今天要介紹的軟體,它不只可以瀏覽SQLite內儲存的資料,同時也可以進行新增、修改、刪除…等操作,就像官網首頁寫的「SQLite Expert: A powerful administration tool for your SQLite databases」。 注意:這篇文章主要是以圖形化工具操作SQLite,並不會讓你學到SQLite指令操作。 先到官網下載SQLite Expert Personal免費版,上面的是專業版,只能試用30天,那小蛙只是需要一些資料庫基本操作,選擇下面的License是Freeware的個人免費版。下載完之後安裝,預設一直下一步直到安裝完成。 安裝完成後執行SQLite Expert Personal,在桌面可以看到圖示,如果沒有的話到開始所有程式(程式集)裡面去找「SQLite Expert」,點兩下執行。

啟動之後我們必須先建立一個新的資料庫,點選左上角紅色框框新增資料庫,並且輸入相關設定。 新增完資料庫後,畫面左邊可以看到小蛙剛剛新增的資料庫「postman」,在資料庫上點選滑鼠右鍵,選擇「New Table」來新增需要的表單。

C C++中使用SQLite_3 数据库

在C/C++中使用SQLite 廖卫东

C/C++接口 SQLite3.0依据以下需求而创建: 支持UTF-16。 用户可定义的文本排序。 以索引列的形式存储BLOB。 SQLite3.0的API包括了83个独立的函数。简单的程序可以通过三个函数工作:sqlite3_open()、sqlite3_exec()和 sqlite3_close()。 更多的数据库引擎运行控制可以用sqlite3_prepare()来编译一个SQLite语句成字节代码并通过sqlite3_step()来执行它。 一个用sqlite3_column_开头的命令序列可以用来提取关于查询结果的信息。许多接口函数是以UTF-8和UTF-16的形式成对出现的。并且有一个用于实现用户定义SQL函数和用户定义的text比较。

打开与关闭一个数据库 typedef struct sqlite3 sqlite3; int sqlite3_open(const char*, sqlite3**); int sqlite3_open16(const void*, sqlite3**); int sqlite3_close(sqlite3*); sqlite3_open()程序返回一个整型错误代码,而不是像sqlite2做的那样返回一个指向sqlite3结构。sqlite3_open()与 sqlite3_open16()间的区别是sqlite3_open16()采用UTF-16(以本地字节顺序)作为数据库文件名。如果一个新数据库文件需要被创建,那么sqlite3_open16()设置本地的文本表达式为UTF-16而sqlite3_open()设置文本表达式为UTF-8。

PHP进行SQLite实例教程

PHP进行SQLite实例教程 PHP进行SQLite实例教程文章录入:https://www.doczj.com/doc/e99604632.html, 责任编辑:https://www.doczj.com/doc/e99604632.html, 63【字体:小大】本教程将向你介绍SQLite API所支持的重要方法,提供一个能够用在你开发中的简单脚本模板,从而告诉你如何使用PHP与SQLite数据库进行交互操作。本文假设你已经安装好了Apache和PHP。 你的系统上并不是一定非要安装可交互的SQLite 程序;但是为了能够简化创建本教程所需要的一系列初始表格,你应该下载和安装这个程序。然后,为你的SQL查询创建一个示例表格,方法是创建一个空白的文本文件,将该文件名作为下列命令(列表A)的参数在交互命令提示符下执行二进制程序: sqlite> CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, country TEXT); sqlite> INSERT INTO users VALUES (1, 'john', 'IN'); sqlite> INSERT INTO users VALUES (2, 'joe', 'UK'); sqlite> INSERT INTO users VALUES (3, 'diana', 'US');一旦表格创建好了,下面就是使用PHP的SQLite方法建立一个脚本模板。 <?php

// set access parameters $db = "users.db"; // open database file // make sure script has read/write permissions! $conn = sqlite_open($db) or die ("ERROR: Cannot open database"); // create and execute INSERT query $sql = "INSERT INTO users (id, username, country) VALUES ('5', 'pierre', 'FR')"; sqlite_query($conn, $sql) or die("Error in query execution: " . sqlite_error_string(sqlite_last_error($conn))); // create and execute SELECT query $sql = "SELECT username, country FROM users"; $result = sqlite_query($conn, $sql) or die("Error in query execution: " . sqlite_error_string(sqlite_last_error($conn))); // check for returned rows // print if available if (sqlite_num_rows($result) > 0) { while($row = sqlite_fetch_array($result)) { echo $row[0] . " (" . $row[1] . ") "; } }

sqlite3的数据类型详解

sqlite3中的数据类型 大多数的数据库引擎(到现在据我们所知的除了sqlite的每个sql数据库引擎)都使用静态的、刚性的类型,使用静态类型,数据的类型就由它的容器决定,这个容器是这个指被存放的特定列。 Sqlite使用一个更一般的动态类型系统,sqlite中,值的数据类型跟值本身相关,而不是与它的容器相关。Sqlite的动态类型系统和其他数据库的更为一般的静态类型系统相兼容,但同时,sqlite中的动态类型允许它能做到一些传统刚性类型数据库所不可能做到的事。 1.存储类和数据类型 每个存放在sqlite数据库中(或者由这个数据库引擎操作)的值都有下面中的一个存储类: ●NULL,值是NULL ●INTEGER,值是有符号整形,根据值的大小以1,2,3,4,6或8字节存放 ●REAL,值是浮点型值,以8字节IEEE浮点数存放 ●TEXT,值是文本字符串,使用数据库编码(UTF-8,UTF-16BE或者UTF-16LE) 存放 ●BLOB,只是一个数据块,完全按照输入存放(即没有准换) 从上可以看出存储类比数据类型更一般化。比如INTEGER存储类,包括6中不同长度的不同整形数据类型,这在磁盘上造成了差异。但是只要INTEGER值被从磁盘读出进入到内存进行处理,它们被转换成最一般的数据类型(8-字节有符号整形)。 Sqlite v3数据库中的任何列,除了整形主键列,可以用于存储任何一个存储列的值。sql语句中的中所有值,不管它们是嵌入在sql文本中或者是作为参数绑定到一个预编译的sql语句,它们的存储类型都是未定的。在下面描述的情况中,数据库引擎会在查询执行过程中在数值(numeric)存储类型(INTEGER和REAL)和TEXT 之间转换值。 1.1布尔类型 Sqlite没有单独的布尔存储类型,它使用INTEGER作为存储类型,0为false,1为true 1.2 Date和Time Datatype Sqlite没有另外为存储日期和时间设定一个存储类集,内置的sqlite日期和时间函数能够将日期和时间以TEXT,REAL或INTEGER形式存放 ●TEXT 作为IS08601字符串("YYYY-MM-DD HH:MM:SS.SSS") ●REAL 从格林威治时间11月24日,4174 B.C中午以来的天数 ●INTEGER 从 1970-01-01 00:00:00 UTC以来的秒数 程序可以任意选择这几个存储类型去存储日期和时间,并且能够使用内置的日期和时间函数在这些格式间自由转换 2.0 类型近似

SQLite数据库常用命令

SQLite数据库入门及常用命令 SQLite软件包中包含了一个名字叫做sqlite3的命令行,它可以让用户手工输入并执行面向SQLite数据库的SQL命令。本文档提供了一个较为详尽的关于sqlite3的使用说明。 启动sqlite3程序,仅仅需要敲入带有SQLite数据库名字的“sqlite3”命令即可。如果文件不存在,则创建一个新的数据库文件。然后,sqlite3程序将提示你输入SQL语句。敲入SQL语句,以分号“;”结束,敲击回车键后,SQL语句就会执行。 例如,创建一个包含一个表“tbl1”名称为“ex1”的SQLite数据库,你可以这样操作: 你可以通过敲击你所用系统的文件结束符(通常是Ctrl+D)或者中断字符(通常是Ctrl+C),来终止sqlite3程序。请记得在每个SQL语句结束后敲入分号!sqlite3程序通过查找分号来决定一个SQL语句是否结束。如果你省略分号,sqlite3将给你一个连续的命令行提示符并等你给当前的SQL命令添加更多的文字。这个特点很利于多行的SQL语句输入。 SQLite数据库的框架被保存在一个名叫“sqlite_master”的特殊表中。你可以像查询其他表一样通过执行“SELECT”语句查询这个特殊的表:

但是,我们不能在sqlite_master表中执行诸如DROP TABLE、UPDATE、INSERT或者DELETE之类的命令。Sqlite_master表在你创建、删除和索引数据库时自动更新这个表。我们不能手工地更改这个表。 temporary表的结构没有存储在“sqlite_master”表中,这是由于temporary表对应用是不可见的,而不是应用程序创建的。temporary表的结构是被存储在另外一个名叫“sqlite_temp_master”的特定表中。 sqlite3的特殊命令。大多数的时候,sqlite3读入用户输入的行,并把它们传递到SQLite库中去运行。但是,如果用户输入的行以一个点“.”开始,那么,这行将被sqlite3程序自身截获并进行解释。这些“点命令”通常被用来改变查询输出的格式,或者执行某个预定义的查询语句。 你可以在任何时候输入“.help”,列出可用的“点命令”。 sqlite3命令可以以8中不同的格式输出查询结果:“csv”、“列”、“html”、“插入”、“行”、“制表”和“tcl”。你可以使用“.mode”这个点命令来在这些输出格式之间进行切换。 默认的输出格式是“列表”。在列表模式下,每条查询结果记录被写在一行中,并且,每列之间以一个字符串分隔符隔开。默认的分隔符是一个管道符号“|”。列表符号模式在当你输出查询结果到另外一个字符处理器的程序(如awk)中时是尤为有用的: 我们也可以使用“.separator”点命令来改变分界符。例如,为了把分隔符改为一个逗号和空格,我们可以这么做:

易语言外部数据库sqlite3教程

易语言外部数据库sqlite3教程 =========================================================== 第一部分 sqlite基础 ----------------------------------------------------------- 1、什么是sqliet SQLite是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite是一个增长最快的数据库引擎,这是在普及方面的增长,与它的尺寸大小无关。SQLite 源代码不受版权限制。 SQLite与其他SQL数据库不同,SQLite没有单独的服务器进程。它直接读取和写入普通磁盘文件。具有多个表,索引,触发器和视图的完整SQL数据库包含在单个磁盘文件中。 ----------------------------------------------------------- 2、为什么要用 SQLite? 不需要一个单独的服务器进程或操作的系统(无服务器的)。 SQLite 不需要配置,这意味着不需要安装或管理。 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。 SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。 SQLite 是自给自足的,这意味着不需要任何外部的依赖。

SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。 SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。 SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的API。 SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和Windows(Win32, WinCE, WinRT)中运行。 ----------------------------------------------------------- 3、常用易语言单机的、免费、轻量级数据库比较 易语言自带数据库易数据库可以说不能称为数据库,它只是“表”,而且还是单张表,所以直接PASS掉。 大部分人会用access,其实Access数据库本身有很多的问题:性能不行;数据不安全,用户可以直接用Access打开数据库文件进行数据修改,即使加密后都可以直接破解;Access的数据量一大,文件本身的体积就异常庞大等因素。 SQLite是一个小型的C程序库,实现了独立的,可嵌入的,零配置的SQL数据库引擎。 SQLite就是Access理想的替代品。 ----------------------------------------------------------- 4、sqlite3数据类型 SQLite存储类比数据类型更通用一些。类型比其他数据库的数据类型少,但是更实用些。

zend studio详细使用教程

zend studio详细使用教程 这一部分是让大伙儿熟悉Zend Studio集成开发环境的界面布局,以及菜单、工具栏命令的功能介绍。目的是熟悉开发环境,明白zde到底都给我们提供了什么?或者这些都是干什么用的?本文将以图文并茂的方式呈现给大家。 先看一下整个界面的截图 窗口界面: ?编辑器:主区域的一个窗口,用来编写代码的,能同时打开多个代码编辑窗口,具强大的提示、语法检查和代码高亮功能,支持php、html代码,是不可多得的神器级编辑工具。 ?浏览器(Browser):zde内置的一个标准的互联网web浏览器,其调试工具栏又让它成为使用zend studio进行调试时的重要组成部分(关于zend studio强大的调试功能,我会在后面单独撰文以讲之。) ?文件管理器:zend studio 5.5.1版的文件管理器窗口包含了3个选项卡:①文件系统:可以浏览本地硬盘上所有的文件,并可以选择性的打开使用编辑器对其编辑;②项目:在该选项卡您可以方便的进行项目的新建、打开、保存以及添加等操作,这些操作都藏在右键快捷菜单中;③SQL:这里是管理数据库连接的,zend studio 5.5.1版支持以下数据库连接:Oracle、SQLite、MSSQL、PostgreSQL、MYSQL、DB2等等。 ?检查器:该窗口包含了3个子选项卡:①文件检查器:列出了编辑器当前打开文件的引用文件、常量、自定义函数等等;②项目检查器:列出了当前项目的所有定义类、函数、常量等内容;③列出当前使用的php版本(zde支持php4和php5,可以在首选项中设置切换)。

?调试窗口:调试窗口包含了5个选项卡:①断点:显示所有设置的断点;②堆栈:调试时显示调用堆栈;③监视点:显示已定义的监视点;④变量:调试时显示全局和局部变量;⑤输出缓冲区:调试时显示脚本的缓冲区数据。 ?消息窗口:用于查看zde在编译时产生的包括Notice、Warning、Error三个级别的信息。 ?调试输出:显示当前脚本运行时输出的结果,有文本和html两种呈现方式。 主要菜单功能介绍: 文件菜单:新建文件、打开文件、关闭文件,打开项目、关闭项目,选择最近打开的文件或项目等,注意这里不能执行新建项目操作,这个需要在项目窗口才能新建项目; 编辑菜单:除了复制粘贴剪切等常规操作外,还有转换为小写、大写,代码缩进、代码折叠功能,最为称道的应该就是展示片段这个命令了。

相关主题
文本预览
相关文档 最新文档