SQLite的使用(包括编译安装的步骤)
SQLite官网
http://www.sqlite.org/
SQLite简介
SQLite是一款轻型的数据库,是遵守ACID(原子性、一致性、隔离性和持久性)的关系式数据库管理系统。SQLite实现了多数的SQL-92标准,包括事务、触发器和多数的复杂查询。
SQLite的设计目标是嵌入式的,它占用的资源非常低,目前在很多嵌入式产品中都使用了SQLite。
SQLite是跨平台的、可移植的,能够支持Windows/Linux/Unix等主流操作系统,同时SQLite能够和很多程序语言相结合,例如Tcl、C#、PHP和Java等。在C/C++程序中可以很方便的使用SQLite库,Python自2.5版本后也内置了SQLite模块,模块名为sqlite3。
SQLite第一个Alpha版本诞生于2000年5月。目前SQLite最新的版本是 3.11 。
SQLite的特性
- ACID事务
- 开放源代码
- 小巧、独立、简单易用,同时功能不落后于流行的数据库
- 整个数据库存储在一个文件中,不需要服务器支持
- 跨平台,支持Windows/Linux/Unix等主流操作系统
- 支持多种开发语言,C, C++,PHP, Perl, Java, C#,Python等
- 简洁易用的API接口
SQLite 管理客户端
- SQLiteMan,使用QT开发的一个SQLite客户端,支持多语言、跨平台。
- SQLite Manager, 以火狐浏览器的扩展形式提供的SQLite客户端。
- SQLite Database Browser, a graphical client to access SQLite databases
- SqlPro SQL Client, another graphical client to work with SQLite databases
- SQLiteStudio2(Tcl/Tk界面): http://sqlitestudio.pl/files/free/stable/
- SQLiteStudio3(Qt/C++重写): http://sqlitestudio.pl/files/sqlitestudio3/complete/
安装
(一)通过编译源码安装
下载地址 https://www.sqlite.org/download.html
下载文件 sqlite-autoconf-3110000.tar.gz

// 解压
tar zxvf sqlite-autoconf-3110000.tar.gz // 安装
cd sqlite-autoconf-3110000
./configure --prefix=/usr/local
make
make install

源码编译会生成这样几个等的文件:
/usr/bin/sqlite3
/usr/local/include/sqlit3.h
/usr/local/lib/libsqlite3.so

(二)通过包安装SQLite
sudo apt-get install sqlite3 libsqlite3-dev
编译程序的时候需要这样
gcc dbtest.c -o dbtest –lsqlite3
注:-l和sqlite3之间可以有空格。
(三)不安装SQLite编译程序
在Linux系统上,将dbtest.c程序保存在libsqlite3.so , sqlite3和sqlite3.h同一个目录下。
可以通过执行这条命令编译文件:
gcc dbtest.c -o dbtest -lsqlite3 -L.

sqlite3二进制程序和sqlite3.h都可以在SQLite官网下载到,libsqlite3.so的获取有两种方法:
1)通过源码编译会在/usr/local/lib/目录下生成libsqlite3.so文件,cp出来就可以了;
2)在系统/usr/lib/x86_64-linux-gnu目录下本来就有(我是64位的系统)。

如果安装了libsqlite3-dev,该目录下会多出如下的文件:

小测试
下面就是dbtest.c的程序,只有打开和关闭的操作。

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> int main(void)
{
sqlite3 *db = NULL;
int rc;
// 打开数据库,不存在会创建一个新的
rc = sqlite3_open("my.db",&db);
if(rc) // 不为0,打开失败
{
fprintf(stderr,"Can't open database:%s\n",sqlite3_errmsg(db));
sqlite3_close(db);
exit(0);
}
else
{
printf("open db success!\n");
sqlite3_close(db);
}
return 0;
}

编译时常见的错误
1)没有找到头文件,错误信息包含下面这句:
sqlite3.h: 没有那个文件或目录
2)没有找到库文件,错误信息包含下面这些句子:
: undefined reference to `sqlite3_open'
: undefined reference to `sqlite3_errmsg'
: undefined reference to `sqlite3_close'
: undefined reference to `sqlite3_close'
gcc的-l、-L、-I参数
-l参数就是用来指定程序要链接的库,例如本程序中要链接libsqlite3.so,去掉前后缀就是了。
放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了。
如果库文件不在这3个目录下,譬如说自己写的库,就需要用-L+Dir的方式指定库文件的目录。
-include、-I参数是用来指定头文件目录,gcc默认目录是/usr/include
SQLite API 函数
SQLite是一个调用级别上的接口库,它能够嵌入到应用程序中。所有的API函数都是以sqlite3_前缀命名,并且在sqlite3.h中声明。
| 序号 | API & 描述 |
|---|---|
| 1 | sqlite3_open(const char *filename, sqlite3 **ppDb)
如果 filename 参数是 NULL 或 ':memory:',那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。 如果文件不存在,SQLite将自动的创建数据库文件。 |
| 2 | sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。 sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。 |
| 3 | sqlite3_close(sqlite3*)
关闭数据库连接,并且释放了分配给该连接的所有资源。 如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。 |
注:在打开或创建一个数据库文件时,SQLite遵守一个懒惰策略:知道该文件被阅读访问时才真正的打开或者创建。
sql字符串可以由多个SQL语句组成,例如:
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
"SELECT * from COMPANY";
sqlite3_exec()函数如果不需要回调,最简洁可以这样写:
rc = sqlite3_exec(db, sql, 0, 0, &errorMsg);
if(errorMsg)
printf("%s\n", errorMsg);
else
printf("success!\n");
判断出错的部分也可以这样写:

if( rc != SQLITE_OK )
{
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else
{
fprintf(stdout, "success!\n");
}

回调函数的原型

typedef int (*sqlite3_callback)(
void*, /* Data provided in the 4th argument of sqlite3_exec() */
int, /* The number of columns in row */
char**, /* An array of strings representing fields in the row */
char** /* An array of strings representing column names */
);

第一个参数通过sqlite3_exec的第第四个参数传入的
第二个参数是结果行的列数
第三个参数是行中列数据的指针
第四个参数是行中列名称的指针
如果sqlite3_exec的第三个参数回调函数指针不为空,那么它会为每个来自执行的SQL语句的结果行调用。
如果在执行sql语句中有错误发生,那么当前的语句的执行被停止,后续的语句也被跳过。
下面就是一个回调函数的具体例子:

static int callback(void *data, int argc, char **argv, char **ColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i=0; i<argc; i++){
printf("%s = %s\n", ColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}

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 */
);
// 不论数据库查询是否成功,都释放 char** 查询结果
void sqlite3_free_table(char **result);

第1个参数数据库对象。
第2个参数是 sql 语句,以\0结尾的字符串。
第3个参数是查询结果,它依然一维数组。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。
第4个参数是查询出多少条记录(多少行)。
第5个参数是多少个字段(多少列)。
第6个参数是错误信息。
pazResult返回的字符串数量实际上是(*pnRow+1)*(*pnColumn)
下面就是一个sqlite3_get_table()函数的具体例子:

result = sqlite3_get_table( db, “select * from table1”, &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], dbResult [index] );
++index;
// dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,
// 从第 nColumn 索引开始,后面都是字段值
}
printf( “--------\n” );
}
}
// 释放查询结果
sqlite3_free_table( dbResult );

还有一个例子:

char query(sqlite3 *db, const char *sql) {
printf("%s\n", sql);
char *select_str = "SELECT";
char *errorMsg;
char *str_str = strstr(sql, select_str);
if(str_str) {
printf("in it, %s\n", str_str);
int row = 0, column = 0, i = 0;
char **result;
sqlite3_get_table(db, sql, &result, &row, &column, &errorMsg);
printf("row:%d, column:%d\n", row, column);
for(; i < column * (row + 1); i++) {
printf("result[%d]=%s\n", i, result[i]);
}
}else{
sqlite3_exec(db, sql, 0, 0, &errorMsg);
}
if(errorMsg){
printf("%s\n", errorMsg);
}else{
printf("success!\n");
}
}

sqlite3.h中定义的助记符常量:

#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR 1 /* SQL error or missing database */
#define SQLITE_INTERNAL 2 /* 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 sqlite3_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 /* Unknown opcode in sqlite3_file_control() */
#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 /* Database is empty */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint 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_FORMAT 24 /* Auxiliary database format error */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
/* end-of-error-codes */

其他
SQLite 教程
http://www.runoob.com/sqlite/sqlite-tutorial.html
常用命令学习
http://yuanzhifei89.iteye.com/blog/1123870
http://blog.csdn.net/linchunhua/article/details/7184439
[API]
官方中的介绍:http://www.sqlite.org/cintro.html
http://www.cnblogs.com/kfqcome/archive/2011/06/27/2136999.html
http://blog.chinaunix.net/uid-8447633-id-3321394.html
使用VC将sqlite3.def转化为sqlite3.lib
http://www.letuknowit.com/topics/20120421/convert-sqlite-def-to-sqlite-lib.html/
windows系统中使用C/C++操作sqlite数据库示例程序
http://www.letuknowit.com/topics/20120422/use-c-or-cplusplus-connect-to-sqlite-in-windows.html/
http://www.cnblogs.com/luoxu34/p/5235737.html
SQLite的使用(包括编译安装的步骤)的更多相关文章
- Sqlite学习笔记(一)&&编译安装
Sqlite简介 sqlite是一个开源的嵌入式文件数据库,sqlite以动态链接库的方式供应用程序调用,所有的数据库对象都存储在同一个文件中. sqlite动态库非常小,最新的3.8.11版本也只有 ...
- mysql 5.6.25编译安装详细步骤
简略步骤: mysql5.6.25编译安装步骤: 下载mysql准备用户和组yum安装依赖解压mysqlcmake编译mysqlmake && make install ----时间约 ...
- Linux编译安装Mysql步骤
一. Centos 用 wget 下载需要的软件,保存到目录/home/zwl/MySql/下 wget http://dev.mysql.com/get/Downloads/MySQL-5.5/my ...
- linux系统编译安装软件的通用步骤
编译安装的步骤: 1.下载源代码,并解压 tar -xf package-version.tar.{gz|bz2|xz} 注意:展开后的目录通常为package-version 2.切换至源码 ...
- nginx软件的编译安装步骤
1.1 检查软件安装的系统环境 [root@web02 conf]# cat /etc/redhat-release CentOS release 6.8 (Final) [root@web02 co ...
- Nginx服务及编译安装
第1章 Nginx 1.1 nginx的概念 Nginx("engine x")是一个开源的.支持高性能.高并发的WWW服务和代理服务软件,具有高开发(特别是静态资源),占用系统资 ...
- nginx的下载、编译安装和启动
一.nginx简介 nginx(“engine x”)是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器.nginx是由Igor Sysoev为俄罗斯访问量第二的R ...
- MySQL5.7 的编译安装
转: 5.7的安装: https://www.insp.top/article/make-install-mysql-5-7 5.6的安装: https://www.chenyudong.com/ar ...
- CentOS7 编译安装nodejs,配置环境变量记录
每次都装,每次都查 阿里云备案了一个域名,续费了好多年,但是没钱买服务器,就挂在github上.今天收到消息:域名解析服务器不在阿里云,要被GG.只能咬牙买了个阿里云乞丐版. 所有服务都装好了,pin ...
随机推荐
- gen_server的enter_loop分析
http://my.oschina.net/astute/blog/119250?p=1 在看ranch user guide的过程中,发现实现protocol handler需要使用特殊的gen_s ...
- 无法写入预编译头文件,由于 IO 设备错误,无法运行此项请求的错误的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 早上查看服务器每日构建的情况,发现出现一个诡异的错误: fatal error C1085: 无法写入预编译头文件:& ...
- 在深入分析:Fragment与Activity一些互动的方式(一,使用Handler)
在这里,我不再具体介绍了编写更传统的方式,比如静态变量,静态方法.持久性,application全局变量.发送和接收广播等等.. 首先让我们介绍使用Handler实现Fragment与Activity ...
- 配置cordova的android开发环境(无android studio)
原文:配置cordova的android开发环境(无android studio) 趁元旦放假想试一下cordova,不想安装庞大的android studio,所以想最小化安装,居然花了一整天的时间 ...
- android 内存优化 性能优化
最近做一个android 的应用程序 总是出现内存高 和cpu高的问题困扰了好多天. 下面为自己从网上总结的和自己找到的问题. 1. WebView 控件: 使用了 WebView 控件一定要注意清 ...
- Array方法总结
一.不影响原数组产生一个新数组 slice:切片->返回新数组->复制数组:arr.slice(0) arrayObject.slice(start,end): 切片 var arr= [ ...
- Java--分布式系统高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- Delphi 获取外部程序句柄与发送消息
--记录下来备以后用 [打开外部程序.消息.句柄],技术有限,希望不要误人子弟了. 源码unit Unit1; interface uses Windows, Messages, SysUtils, ...
- .Net Remoting的双向通信和Windows Service的宿主服务
原文:.Net Remoting的双向通信和Windows Service的宿主服务 作为微软分布式技术之一的.Net Remoting,从性能.安全等各方面来说都是相对比较稳定的,也是一项比较成熟的 ...
- phpstorm 删除空行
思路: 用正则把所有空行找到,然后一键全部替换. 步骤:首先把 Regex 打上勾ctrl+f 搜索框就填写正则规则:^\nctrl+r 匹配到所有空行之后,点击[Replace all]即可