linux下C语言编程操作数据库(sqlite3)
来源:互联网 发布:日本球员 中超 知乎 编辑:程序博客网 时间:2024/05/16 10:49
前言:C语言中通过调用 sqlite 的函数接口来实现对数据库的管理(创建数据库、创建表格、插入数据、查询、数据、删除数据等),掌握sqlite数据库的语法,以及sqlite提供的函数接口,那么在linux下C语言编程操作数据库就变得简单了。
Centos系统一般默认是没有安装sqlite3数据库的,所以我们要到其官网下载,我下载的版本是 sqlite-3.6.16.tar.gz
[zoulei@CentOS sqlite]$ wget http://www.sqlite.org/sqlite-3.6.16.tar.gz进入下载目录,解压文件sqlite-3.6.16.tar.gz解压后生成sqlite-3.6.16目录. cd 进入sqlite-3.6.16
[zoulei@CentOS sqlite]$ tar -xzvf sqlite-3.6.16.tar.gz[zoulei@CentOS sqlite]$ cd sqlite-3.6.16[zoulei@CentOS sqlite-3.6.16]$
执行配置脚本,生成相关文件之后使用make命令编译
[zoulei@CentOS sqlite-3.6.16]$ ./configure[zoulei@CentOS sqlite-3.6.16]$ make[zoulei@CentOS sqlite-3.6.16]$ sudo make install安装完成之后会在sqlite-3.6.16目录下生成sqlite3等文件
在linux下sqlite3具体怎么操作,可以参考这篇博客:点击打开链接
看代码:sqlite.c
/********************************************************************************* * Copyright: (C) 2017 zoulei * All rights reserved. * * Filename: insert.c * Description: This file i * * Version: 1.0.0(2017年06月22日) * Author: zoulei <zoulei121@gmail.com> * ChangeLog: 1, Release initial version on "2017年06月22日 19时31分12秒" * ********************************************************************************/#include <stdio.h>#include <stdlib.h>#include "sqlite3.h"#define _DEBUG_int main(int argc, char**argv){ sqlite3 *db=NULL; int len; int i=0; int nrow=0; int ncolumn = 0; char *zErrMsg =NULL; char **azResult=NULL; //二维数组存放结果 /* 打开数据库 */ len = sqlite3_open("user",&db); if( len ) { /* fprintf函数格式化输出错误信息到指定的stderr文件流中 */ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));//sqlite3_errmsg(db)用以获得数据库打开错误码的英文描述。 sqlite3_close(db); exit(1); } else printf("You have opened a sqlite3 database named user successfully!\n"); /* 创建表 */ char *sql = " CREATE TABLE SensorData(\ ID INTEDER PRIMARY KEY,\ SensorID INTEGER,\ siteNum INTEGER,\ Time VARCHAR(12),\ SensorParameter REAL\ );" ; sqlite3_exec(db,sql,NULL,NULL,&zErrMsg);#ifdef _DEBUG_ printf("%s\n",zErrMsg); sqlite3_free(zErrMsg);#endif /*插入数据 */ char*sql1 ="INSERT INTO 'SensorData'VALUES(NULL,1,2,201430506201,13.5);"; sqlite3_exec(db,sql1,NULL,NULL,&zErrMsg); char*sql2 ="INSERT INTO 'SensorData'VALUES(NULL,3,4,201530506302,14.5);"; sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg); char*sql3 ="INSERT INTO 'SensorData'VALUES(NULL,5,6,201630506413,18.6);"; sqlite3_exec(db,sql3,NULL,NULL,&zErrMsg); /* 查询数据 */ sql="select *from SensorData"; sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg ); printf("nrow=%d ncolumn=%d\n",nrow,ncolumn); printf("the result is:\n"); for(i=0;i<(nrow+1)*ncolumn;i++) { printf("azResult[%d]=%s\n",i,azResult[i]); } /* 删除某个特定的数据 */ sql="delete from SensorData where SensorID = 1 ;"; sqlite3_exec( db , sql , NULL , NULL , &zErrMsg );#ifdef _DEBUG_ printf("zErrMsg = %s \n", zErrMsg); sqlite3_free(zErrMsg);#endif /* 查询删除后的数据 */ sql = "SELECT * FROM SensorData "; sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg ); printf( "row:%d column=%d\n " , nrow , ncolumn ); printf( "After deleting , the result is : \n" ); for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ ) { printf( "azResult[%d] = %s\n", i , azResult[i] ); } sqlite3_free_table(azResult);#ifdef _DEBUG_ printf("zErrMsg = %s \n", zErrMsg); sqlite3_free(zErrMsg);#endif sqlite3_close(db); return 0;}
代码分析:
其实操作数据库无非就是如何调用sqlite3提供的API,以及如何使用相应的语句操作sqlite3数据库进行增,删,改,查等。那么下面我们着重分析
一下sqlite3提供的函数接口。
1.打开数据库函数接口
原型:int sqlite3_open(const char * filename, sqlite3 **ppDb);
int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */);用这个函数开始数据库操作。需要传入两个参数,一是数据库文件名,比如:我的虚拟机~/sqlite/路径下的user文件,文件名不需要一定存在,如果此文件不存在,sqlite会自动建立它。如果它存在,就尝试把它当数据库文件来打开。二是sqlite3**,即前面提到的关键数据结构。这个结构底层细节如何,不需要管它。函数返回值表示操作是否正确,如果是SQLITE_OK则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考sqlite3.h 文件。
2.关闭数据库函数接口
原型:int sqlite3_close(sqlite3**ppDb);
ppDb为我们使用sqlite3_open()函数打开的数据库链接(对应我写的程序中的db变量)。
3.执行sql语句函数接口
原型:int sqlite3_exec(sqlite3*,const char*sql,sqlite_callback,void*data,char**errmsg);
int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be executed */ sqlite_callback, /* Callback function */ void *, /* 1st argument to callback function */ char **errmsg /* Error msg written here */);
这就是执行一条sql 语句的函数,
第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。
第2个参数const char*sql是一条sql 语句,以\0结尾。
第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。通常设为NULL。
第4个参数void*是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。
第5个参数char** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf("zErrMsg = %s \n", zErrMsg)得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个char*得到具体错误提示。
************************************************************************************************************************
说明:通常,sqlite3_callback 和它后面的void*这两个位置都可以填NULL。填NULL表示你不需要回调。比如你做insert 操作,做delete操作,就没有必要使用回调。而当你做select 时,就要使用回调,因为sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。虽然回调显得代码整齐,但有时候你还是想要非回调的select 查询。这可以通过sqlite3_get_table 函数做到。
原型:sqlite3_get_table(sqlite3*db,const char*zsql,char***pazResult,int*nrow,int*ncolumn,char**zErrmsg);
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);第1个参数不再多说,看前面的例子。
第2个参数是sql 语句,跟sqlite3_exec 里的sql 是一样的。是一个很普通的以\0结尾的char*字符串。
第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:字段名称,后面是紧接着是每个字段值。
第4个参数是查询出多少条记录(即查出多少行,不包括字段名那行)。
第5个参数是多少个字段(多少列)。
第6个参数是错误信息,跟前面一样,这里不多说了。
pazResult返回的字符串数量实际上是(*pnRow+1)*(*pnColumn),因为前(*pnColumn)个是字段名。
注意:如果提供 了errmsg,用来创建错误消息的内存是在堆上分布的。 故在调用后,应该检查一下是否为null值,如果有错误发生,使用sqlite3_free()释放errmsg占用的内存。
*************************************************************************************************************************************************************************
编译运行:
[zoulei@CentOS sqlite]$ gcc sqlite.c -o sqlite -l sqlite3[zoulei@CentOS sqlite]$ ./sqlite
You have opened a sqlite3 database named user successfully!
table SensorData already exists
nrow=3 ncolumn=5
the result is:
azResult[0]=ID
azResult[1]=SensorID
azResult[2]=siteNum
azResult[3]=Time
azResult[4]=SensorParameter
azResult[5]=(null)
azResult[6]=1
azResult[7]=2
azResult[8]=201430506201
azResult[9]=13.5
azResult[10]=(null)
azResult[11]=3
azResult[12]=4
azResult[13]=201530506302
azResult[14]=14.5
azResult[15]=(null)
azResult[16]=5
azResult[17]=6
azResult[18]=201630506413
azResult[19]=18.6
zErrMsg = (null)
row:2 column=5
After deleting , the result is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = siteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = (null)
azResult[6] = 3
azResult[7] = 4
azResult[8] = 201530506302
azResult[9] = 14.5
azResult[10] = (null)
azResult[11] = 5
azResult[12] = 6
azResult[13] = 201630506413
azResult[14] = 18.6
zErrMsg = (null)
从程序输出结果就可以看出,在删除数据前,我们有三条记录,删除数据后我们发现,数据库内记录少了。从而实现了我们的删除数据目的。
****************************************************************************************************************************************************************************************
注意:这里我们可以看到,azResult 的前面 5 个数据正好是我们的表 SensorData 的列属性,之后才是我们要查询的数据。所以我们
的程序中才有 i<( nrow + 1 ) * ncolumn 的判断条件:
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s/n", i , azResult[i] );
输出中有 zErrMsg = (null) 这样的字句,这是 zErrMsg 保留的错误信息,正如你所看到的,zErrMsg 为空,表明在执行过程中没有错误信息。
***************************************************************************************************************************************************************************
遇到的问题:
问题解决:
出现上述问题是因为没有找到库文件的问题。
由于用到了用户自己的库文件,所以应该指明所用到的库,我们可以这样编译:
[zoulei@CentOS sqlite]$ gcc sqlite.c -o sqlite -l sqlite3
通过find命令找出sqlite3依赖的库:
[zoulei@CentOS sqlite-3.6.16]$ find -name "libsqlite3.so"
./.libs/libsqlite3.so
[zoulei@CentOS sqlite-3.6.16]$ cd ./.libs
[zoulei@CentOS .libs]$ ls
所以用 -l sqlite3 选项就可以了(由于编译生成的库文件是 libsqlite3.so.0.8.6 等,去掉前面的lib和后面的版本标志,就剩下 sqlite3 了所以是 -l sqlite3 )
- linux下C语言编程操作数据库(sqlite3)
- Linux下C语言中sqlite3数据库的操作
- 在Linux下用C语言操作数据库sqlite3(建立数据库)
- 在Linux下用C语言操作数据库sqlite3(建立数据库)
- 在Linux下用C语言操作数据库sqlite3(查询)
- 在Linux下用C语言操作数据库sqlite3(插入)
- 在Linux下用C语言操作数据库sqlite3(查询)
- linux c编程操作数据库(sqlite3应用)
- linux c编程操作数据库(sqlite3应用)
- linux c编程操作数据库(sqlite3应用)
- linux c编程操作数据库(sqlite3应用)
- linux c编程操作数据库(sqlite3应用)
- linux c编程操作数据库(sqlite3应用)
- linux c编程操作数据库(sqlite3应用)
- linux下c语言操作sqlite3(1)
- 如何在Linux下用C/C++语言操作数据库sqlite3(很不错!设计编译链接等很多问题!)
- 如何在Linux下用C/C++语言操作数据库sqlite3
- 如何在Linux下用C/C++语言操作数据库sqlite3 2007-11-22 17:06
- win10自带的 快速截图功能
- 蓝牙核心技术概述(三): 蓝牙协议规范(射频、基带链路控制、链路管理)
- JM8.6的解码端去方块滤波代码详述
- 下载jar包 pom文件配置 网址
- Hibernate 分页的两种方式
- linux下C语言编程操作数据库(sqlite3)
- 浅谈WebLogic和Tomcat
- 蓝牙核心技术概述(四):蓝牙协议规范(HCI、L2CAP、SDP、RFOCMM)
- 解码器输出PSNR为0表示什么
- [bigdata-111] spring-cloud-07 api网关服务
- Source Insight 使用
- 关于intellij idea删除project工作空间关联的问题
- Spark源码解析:RDD
- iOS Hacker LLDB 和 debugserver 实例调试