linux下sqlite3的使用

本文介绍SQLite数据库的安装步骤、基本语法及C/C++编程接口使用方法,包括数据库的创建、表的创建、数据的插入、查询与删除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、sqlite-3.3.8编译安装

请阅读在安装包里的 INSTALL或者README 文件。SQLite已经内置了,你不需要安装任何附加的软件(additional software)。
Windows users可以下载SQLite扩展DLL。
这里简单介绍一下:
假设你得到的是源代码sqlite-3.3.8.tar.gz,这里将告诉你怎么编译它。
解压sqlite-3.3.8.tar.gz 到 /home目录下
For example:
tar zxvf sqlite-3.3.8.tar.gz -C /home
cd /home
mkdir sqlite-3.3.8-ix86
cd /home/sqlite-3.3.8-ix86/
../sqlite-3.3.8/configure --prefix=/home/sqlite-3.3.8-ix86
编译并安装,然后生成帮助文档
make && make install && make doc
如果出现下列错误
../sqlite-3.3.8/src/tclsqlite.c: In function `DbUpdateHandler':
../sqlite-3.3.8/src/tclsqlite.c:333: warning: passing arg 3 of `Tcl_ListObjAppendElement' makes pointer from integer without a cast
../sqlite-3.3.8/src/tclsqlite.c: In function `tclSqlFunc':
../sqlite-3.3.8/src/tclsqlite.c:419: warning: passing arg 1 of `Tcl_NewByteArrayObj' discards qualifiers from pointer target type
...
这个都是tcl相关的错误,可以先安装ActiveTcl以解决.假如你不需要tcl支持,那么这个错误可以这样避免:
cd /home/sqlite-3.3.8-ix86/
../sqlite-3.3.8/configure --disable-tcl --prefix=/home/sqlite-3.3.8-ix86
编译并安装,然后生成帮助文档
make && make install && make doc
不出意外,将不会出现错误,那么
Libraries have been installed in:
   /home/sqlite-3.3.8-ix86/lib
库文件已经生成在 /home/sqlite-3.3.8-ix86/lib 目录下
可执行文件sqlite3已经生成在 /home/sqlite-3.3.8-ix86/bin 目录下
下面创建一个新的数据库文件名叫"zieckey.db" (当然你可以使用不同的名字) 来测试数据库.
直接输入: /home/sqlite-3.3.8-ix86/bin/sqlite3 test.db
如果出现下面字样表明编译安装已经成功了.
SQLite version 3.3.8
Enter ".help" for instructions
sqlite>

二 、SQLite的基本语法

这一章我们将会学习到sqlite的基本语法,sqlite的语法现象和SQL92是比较相象的,
或者说sqlite3兼容大部份SQL92的语法现象。
下面我们看看怎么用这些语法现象来创建数据库以及对数据库的各种操作。
2.1 新建一个数据库
例如我们想新建一个数据库命名为zieckey.db ,可以直接在shell下输入 sqlite3 zieckey.db ,
前提是:先进放sqlite的安装文件夹下然后执行下面的操作:
# ./sqlite3 zieckey.db
SQLite version 3.0.8
Enter ".help" for instructions
sqlite>
这里 SQLite version 3.0.8 是SQLite的版本信息。也就是说本文使用的sqlite版本为 version 3.0.8 .
这样就创建了一个新的数据库文件,命名为 zieckey.db
2.2 创建表和插入值
刚刚我们创建了一个新的数据库zieckey.db,加入我们想在其中新建一个名为 SensorData 的表,其包含五个列元素。
可以用CREATE TABLE语法命令。
CREATE TABLE语句基本上就是"CREATE TABLE"关键字后跟一个新的表名以及括号内的一堆定义和约束。表名可以是字符串或者标识符。以"sqlite_"开头的表名是留给sqlite数据库引擎使用的。每个字段的定义是字段名后跟字段的数据类型,接着是一个或多个的字段约束。字段的 数据类型并不限制字段中可以存放的数据。更多信息,参见sqlite的CREATE TABLE语法。
这里具体作法如下:
# sqlite3 zieckey.db
SQLite version 3.0.8
Enter ".help" for instructions
sqlite> CREATE TABLE SensorData(
...> ID INTEGER PRIMARY KEY,
...> SensorID INTEGER,
...> SiteNum INTEGER,
...> Time VARCHAR(12),
...> SensorParameter REAL
...> );
注意sqlite下除了特殊命令都要以分号 “;” 结尾,否则它将一直等待第一个分号的出现才判断这条命令结束。
现在我们可以用 schema 命令看看我们刚刚创建的表。具体作法如下:
sqlite> .schema
CREATE TABLE SensorData(
ID INTEGER PRIMARY KEY,
SensorID INTEGER,
SiteNum INTEGER,
Time VARCHAR(12),
SensorParameter REAL
);
sqlite>
.schema 是用来查看数据库中所有的表的定义内容。如果后面跟了具体的表名称,则显示该表的内容。
假如我们想想SensorData表中插入具体列元素值,该怎么办呢?这里可以用INSERT语句。
INSERT语句有两种基本形式。一种带有"VALUES"关键字,在已有表中插入一个新的行。若不定义字段列表,那么值的数目将与表中的字段数目相同。否则值的数目须与字段列表中的字段数目相同。不在字段列表中的字段被赋予缺省值或NULL(当未定义缺省值)。
INSERT的第二种形式从SELECT语句中获取数据。若未定义字段列表,则从SELECT得到的字段的数目必须与表中的字段数目相同,否则应与定义的字段列表中的字段数目相同。SELECT的每一行结果在表中插入一个新的条目。SELECT可以是简单的或者复合的。如果SELECT语句带有 ORDER BY子句,ORDER BY会被忽略。
这里我们可以这样做:
sqlite> INSERT INTO "SensorData" VALUES(NULL, 1, 0, '200605011206', 18.9);
sqlite> INSERT INTO "SensorData" VALUES(2, 1, 0, '200605011306', 16.4);
sqlite> INSERT INTO "SensorData" VALUES(3, 1, 0, '200605011406', 15.3);
sqlite> INSERT INTO "SensorData" VALUES(4, 1, 0, '200605011506', 15.5);
sqlite>
很简单对不对?简直太easy了。
2.3 在线帮助
前面两节,我们已经知道了sqlite语法最基本的用法。下面可以看看如何获得联机帮助。
很简单,输入 .help 就行了。注意要help前加上“.”,这与上面说的以分号结尾有点不同,因为help命令被视为特殊命令。
sqlite> .help
.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
.mode MODE ?TABLE? Set output mode where MODE is on 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>
这里看到的命令都带有“.”开头,或者说sqlite下,只有这些命令是需要带“.”的。我们会经常用到的命令有:
.output FILENAME
.output stdout
.quit
.read FILENAME
.schema ?TABLE?
.dump ?TABLE? ...
.echo ON|OFF
.exit
在下面会涉及到这些具体内容的。我们慢慢来。

2.4 查看当前数据库下的所有表
当数据库越来越大时,我们也许并不太记得数据库中有多少个表了,这时就需要查看当前数据库下的有些什么表。
我们可以用 .tables 命令 。
sqlite> .tables
SensorData
sqlite>
2.5 退出sqlite3
对于初学者,也许不知道怎么安全退出,不过如果是从头看到此处的读者也许已经知道了,
因为刚才 .help 命令已经告诉我们答案了。安全退出有两个命令:.exit 和 .quit
好了,我们已经新建一个名为zieckey.db的数据库,并在其中新建一个名为 SensorData 的表.
现在我们想退出,那么可以用到刚刚提到的 .exit 和 .quit 命令。
例如我们可以这样退出:
sqlite> .exit
这里需要说明一下,如果不是用 .exit 和 .quit 这两个命令退出,我们对数据库的修改有可能丢失。

三、在Linux下用C/C++语言操纵SQLite数据库

1. 说明
这里我们假设你已经编译好了sqlite的库文件 :
libsqlite3.a libsqlite3.la libsqlite3.so libsqlite3.so.0 libsqlite3.so.0.8.6 pkgconfig
和可执行文件 : sqlite3
我们再假设你的sqlite3的安装目录在 /usr/local/sqlite3 目录下。
如果不是,我们可以这样做,将你的安装文件复制到 /usr/local/sqlite3 这个目录,
这样我们好在下面的操作中更加统一,从而减少出错的概率
例如:[root@localhost home]# cp -rf sqlite-3.3.8-ix86/ /usr/local/sqlite3
这里假设 /home/sqlite-3.3.8-ix86/ 是你的安装目录,也就是说你的sqlite原来就是安装在这里
这样之后,我们的sqlite3的库文件目录是:/usr/local/sqlite3/lib
可执行文件 sqlite3 的目录是: /usr/local/sqlite3/bin
头文件 sqlite3.h 的目录是: /usr/local/sqlite3/include
可以用ls命令查看下:
[root@localhost sqlite]# ls /usr/local/sqlite3/lib
libsqlite3.a libsqlite3.la libsqlite3.so libsqlite3.so.0 libsqlite3.so.0.8.6 pkgconfig
        
好拉,现在开始我们的Linux下sqlite3编程之旅。
2. 开始
这里我们现在进行一个测试。
现在我们来写个C/C++程序,调用 sqlite 的 API 接口函数。
下面是一个C程序的例子,显示怎么使用 sqlite 的 C/C++ 接口. 数据库的名字由第一个参数取得且第二个参数或更多的参数是 SQL 执行语句. 这个函数调用sqlite3_open() 在 16 行打开数据库,并且sqlite3_close() 在 25 行关闭数据库连接。
[root@localhost temp]# vi opendbsqlite.c
按下 i 键切换到输入模式,输入下列代码:
// name: opendbsqlite.c
// This prog is used to test C/C++ API for sqlite3.It is very simple,ha!
// Author : zieckey      All rights reserved.
// date : 2006/11/13
#include <stdio.h>
#include <sqlite3.h>
int main( void )
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;

//打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
rc = sqlite3_open("zieckey.db", &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 0;
}
else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");

sqlite3_close(db); //关闭数据库
return 0;
}

退出,保存。(代码输入完成后,按下 Esc 键,然后输入:   :wq   ,回车就好拉)
好拉,现在编译:[root@localhost temp]# gcc opendbsqlite.c -o db.out
或者遇到这样的问题:
[root@localhost temp]# gcc opendbsqlite.c -o db.out
opendbsqlite.c:11:21: sqlite3.h: 没有那个文件或目录
opendbsqlite.c: In function `main':
opendbsqlite.c:19: `sqlite3' undeclared (first use in this function)
opendbsqlite.c:19: (Each undeclared identifier is reported only once
opendbsqlite.c:19: for each function it appears in.)
opendbsqlite.c:19: `db' undeclared (first use in this function)
这是由于没有找到头文件的原因。
也许会碰到类似这样的问题:
[root@localhost temp]# gcc opendbsqlite.c -o db.out
/tmp/ccTkItnN.o(.text+0x2b): In function `main':
: undefined reference to `sqlite3_open'
/tmp/ccTkItnN.o(.text+0x45): In function `main':
: undefined reference to `sqlite3_errmsg'
/tmp/ccTkItnN.o(.text+0x67): In function `main':
: undefined reference to `sqlite3_close'
/tmp/ccTkItnN.o(.text+0x8f): In function `main':
: undefined reference to `sqlite3_close'
collect2: ld returned 1 exit status
这是个没有找到库文件的问题。
下面我们着手解决这些问题。
由于用到了用户自己的库文件,所用应该指明所用到的库,我们可以这样编译:
[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3
我用用 -lsqlite3 选项就可以了(前面我们生成的库文件是 libsqlite3.so.0.8.6 等,
去掉前面的lib和后面的版本标志,就剩下 sqlite3 了所以是 -lsqlite3 )。
如果我们在编译安装的时候,选择了安装路径,例如这样的话:
.......
# ../sqlite/configure --prefix=/usr/local/sqlite3
# make
.......
这样编译安装时,sqlite的库文件将会生成在 /usr/local/sqlite3/lib 目录下
sqlite的头文件将会生成在 /usr/local/sqlite3/include 目录下
这时编译还要指定库文件路径,因为系统默认的路径没有包含 /usr/local/sqlite3/lib
[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib
如果还不行的话,可能还需要指定头文件 sqlite3.h 的路径,如下:
[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include
这样编译应该就可以了 ,运行:
[root@localhost temp]# ./db.out
./db.out: error while loading shared libraries: libsqlite3.so.0: cannot open shared object file: No such file or directory
运行是也许会出现类似上面的错误。
这个问题因为刚刚编译的时候没有选择静态编译,那么按照默认的编译就动态编译的。
动态编译后,由于可执行文件在运行时要调用系统库文件,
那么沿着系统默认的库文件搜索路径搜索,就可能找不到我们现在所需的库文件。
致使出现 "error while loading shared libraries" 等错误。
我们可以这样解决:
方法一:静态编译
在编译时加上 -static 参数,例如
[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include -static
[root@localhost temp]# ll
总用量 1584
-rwxr-xr-x    1 root     root      1596988 11月 13 10:50 db.out
-rw-r--r--    1 root     root          614 11月 13 10:31 opendbsqlite.c
可以看到输出文件 db.out ,其大小为: 1596988k
运行,好了,没有出现错误
[root@localhost temp]# ./db.out
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
方法二:重新配置系统环境变量 LD_LIBRARY_PATH
这时需要指定 libsqlite3.so.0 库文件的路径,也就是配置系统环境变量 LD_LIBRARY_PATH ,
使系统能够找到 libsqlite3.so.0 。
去掉 -static ,再编译:
[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include
[root@localhost temp]# ll
总用量 36
-rwxr-xr-x    1 root     root        12716 11月 13 10:56 db.out
-rw-r--r--    1 root     root          614 11月 13 10:31 opendbsqlite.c
[root@localhost temp]#
可以看到输出文件 db.out ,其大小为: 12716k,比刚才的静态编译要小得多。
所以我们推荐使用动态编译的方法。
好了,现在我们来指定系统环境变量 LD_LIBRARY_PATH 的值
在shell下输入:
[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH
看看现在系统环境设置:
[root@localhost temp]#env
SSH_AGENT_PID=3511
HOSTNAME=localhost.localdomain
DESKTOP_STARTUP_ID=
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
GTK_RC_FILES=/etc/gtk/gtkrc:/root/.gtkrc-1.2-gnome2
WINDOWID=29388238
OLDPWD=/mnt/usb/wuruan/sqlite
QTDIR=/usr/lib/qt-3.1
USER=root
LD_LIBRARY_PATH=/usr/local/sqlite3/lib:
LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:
SSH_AUTH_SOCK=/tmp/ssh-XXt14q3a/agent.3456
SESSION_MANAGER=local/localhost.localdomain:/tmp/.ICE-unix/3456
USERNAME=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
INPUTRC=/etc/inputrc
PWD=/mnt/usb/wuruan
XMODIFIERS=@im=fcitx
LANG=zh_CN.GB18030
GDMSESSION=Default
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
HOME=/root
SHLVL=2
LANGUAGE=zh_CN.GB18030:zh_CN.GB2312:zh_CN
GNOME_DESKTOP_SESSION_ID=Default
BASH_ENV=/root/.bashrc
LOGNAME=root
LESSOPEN=|/usr/bin/lesspipe.sh %s
DISPLAY=:0.0
G_BROKEN_FILENAMES=1
COLORTERM=gnome-terminal
XAUTHORITY=/root/.Xauthority
_=/bin/env
看到了吧,LD_LIBRARY_PATH这一行开始就是sqlite3的库文件路径:
LD_LIBRARY_PATH=/usr/local/sqlite3/lib: ............
好拉,现在再运行
[root@localhost temp]# ./db.out
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
是不是很有成就感阿 ,呵呵,这个上手还是很快的。

3. 插入:insert   
刚刚我们知道了怎么调用 sqlite3 的C/C++的API函数接口,下面我们看看怎么在C语言中向数据库插入数据。

好的,我们现编辑一段c代码,取名为 insert.c
// name: insert.c
// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !
// Author : zieckey      All rights reserved.
// date : 2006/11/18
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#define _DEBUG_
int main( void )
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;

rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 0;
}
else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");
//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中
char *sql = " CREATE TABLE SensorData(
      ID INTEGER PRIMARY KEY,
     SensorID INTEGER,
      SiteNum INTEGER,
      Time VARCHAR(12),
      SensorParameter REAL
      );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
        printf("%s\n",zErrMsg);
    #endif

//插入数据
sql = "INSERT INTO \"SensorData\" VALUES( NULL , 1 , 1 , '200605011206', 18.9 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
sql = "INSERT INTO \"SensorData\" VALUES( NULL , 1 , 1 , '200605011306', 16.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

sqlite3_close(db); //关闭数据库
return 0;
}

好的,将上述代码写入一个文件,并将其命名为 insert.c 。
解释:
sqlite3_exec的函数原型说明如下:
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 */
);

编译:
[root@localhost temp]# gcc insert.c -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include
insert.c:28:21: warning: multi-line string literals are deprecated
[root@localhost temp]#
执行
[root@localhost temp]# ./a.out
./a.out: error while loading shared libraries: libsqlite3.so.0: cannot open shared object file: No such file or directory
[root@localhost temp]#
同样的情况,如上文处理方法:
[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH
[root@localhost temp]# ./a.out
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
(null)
(null)
(null)
[root@localhost temp]#
运行成功了,好了,现在我们来看看是否插入了数据
[root@localhost temp]# /usr/local/sqlite3/bin/sqlite3 zieckey.db
SQLite version 3.3.8
Enter ".help" for instructions
sqlite> select * from SensorData;
1|1|1|200605011206|18.9
2|1|1|200605011306|16.4
sqlite>
哈哈,已经插入进去了,不是吗?
很简单是不?
4. 查询: SELETE
好了,我们知道了怎么调用 sqlite3 的C/C++的API函数接口去创建数据库、创建表格、并插入数据,
下面我们看看怎么在C语言中查询数据库中的数据。

好的,我们现编辑一段c代码,取名为 query.c
// name: query.c
// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !
// Author : zieckey      All rights reserved.
// date : 2006/11/18
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#define _DEBUG_
int main( void )
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;

rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 0;
}
else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");
//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中
char *sql = " CREATE TABLE SensorData(
      ID INTEGER PRIMARY KEY,
     SensorID INTEGER,
      SiteNum INTEGER,
      Time VARCHAR(12),
      SensorParameter REAL
      );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
        printf("zErrMsg = %s \n", zErrMsg);
    #endif

//插入数据
sql = "INSERT INTO \"SensorData\" VALUES(NULL , 1 , 1 , '200605011206', 18.9 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

sql = "INSERT INTO \"SensorData\" VALUES(NULL , 1 , 1 , '200605011306', 16.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

int nrow = 0, ncolumn = 0;
char **azResult; //二维数组存放结果
//查询数据
/*
int sqlite3_get_table(sqlite3*, const char *sql,char***result , int *nrow , int *ncolumn ,char **errmsg );
result中是以数组的形式存放你所查询的数据,首先是表名,再是数据。
nrow ,ncolumn分别为查询语句返回的结果集的行数,列数,没有查到结果时返回0
*/
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
int i = 0 ;
printf( "row:%d column=%d \n" , nrow , ncolumn );
printf( "\nThe result of querying is : \n" );

for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s\n", i , azResult[i] );
//释放掉 azResult 的内存空间
sqlite3_free_table( azResult );

#ifdef _DEBUG_
        printf("zErrMsg = %s \n", zErrMsg);
    #endif
sqlite3_close(db); //关闭数据库
return 0;
}

我们这里用到了一个查询的语句是 "SELECT * FROM SensorData " ,
在C语言中对应的函数接口是 sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
这个函数接口的解释在程序中已经注释。
下面我们编译运行下看看,
[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH
[root@localhost temp]# gcc query.c -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include
query.c:29:21: warning: multi-line string literals are deprecated
[root@localhost temp]# ./a.out
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
zErrMsg = (null)
row=2 column=5

The result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 1
azResult[6] = 1
azResult[7] = 1
azResult[8] = 200605011206
azResult[9] = 18.9
azResult[10] = 2
azResult[11] = 1
azResult[12] = 1
azResult[13] = 200605011306
azResult[14] = 16.4
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 为空,表明在执行过程中没有错误信息。
5. 删除:delete
下面我们看看怎么在C语言中删除数据库中的特定的数据。

好的,我们现编辑一段c代码,取名为 delete.c

// name: delete.c
// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !
// Author : zieckey      All rights reserved.
// date : 2006/11/18
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#define _DEBUG_
int main( void )
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;

rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 0;
}
else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");
//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中
char *sql = " CREATE TABLE SensorData(
      ID INTEGER PRIMARY KEY,
     SensorID INTEGER,
      SiteNum INTEGER,
      Time VARCHAR(12),
      SensorParameter REAL
      );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
        printf("zErrMsg = %s \n", zErrMsg);
    #endif

//插入数据
sql = "INSERT INTO \"SensorData\" VALUES(NULL , 1 , 1 , '200605011206', 18.9 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

sql = "INSERT INTO \"SensorData\" VALUES(NULL , 23 , 45 , '200605011306', 16.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );

sql = "INSERT INTO \"SensorData\" VALUES(NULL , 34 , 45 , '200605011306', 15.4 );" ;
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );


int nrow = 0, ncolumn = 0;
char **azResult; //二维数组存放结果
//查询数据
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
int i = 0 ;
printf( "row:%d column=%d \n" , nrow , ncolumn );
printf( "\nThe result of querying 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 , 0 , 0 , &zErrMsg );
#ifdef _DEBUG_
        printf("zErrMsg = %s \n", zErrMsg);
    #endif
sql = "SELECT * FROM SensorData ";
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
printf( "\n\n\n\nrow:%d column=%d " , nrow , ncolumn );
printf( "\nAfter deleting , the result of querying is : \n" );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s\n", i , azResult[i] );

//释放掉 azResult 的内存空间
sqlite3_free_table( azResult );

#ifdef _DEBUG_
        printf("zErrMsg = %s \n", zErrMsg);
    #endif
sqlite3_close(db); //关闭数据库
return 0;

}
下面我们编译运行看看,效果如何
[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH
[root@localhost temp]# gcc delete.c -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include
delete.c:29:21: warning: multi-line string literals are deprecated
[root@localhost temp]# ./a.out
You have opened a sqlite3 database named zieckey.db successfully!
Congratulations! Have fun ! ^-^
zErrMsg = (null)
row=3 column=5

The result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 1
azResult[6] = 1
azResult[7] = 1
azResult[8] = 200605011206
azResult[9] = 18.9
azResult[10] = 2
azResult[11] = 23
azResult[12] = 45
azResult[13] = 200605011306
azResult[14] = 16.4
azResult[15] = 3
azResult[16] = 34
azResult[17] = 45
azResult[18] = 200605011306
azResult[19] = 15.4
zErrMsg = (null)

row:2 column=5
After deleting , the result of querying is :
azResult[0] = ID
azResult[1] = SensorID
azResult[2] = SiteNum
azResult[3] = Time
azResult[4] = SensorParameter
azResult[5] = 2
azResult[6] = 23
azResult[7] = 45
azResult[8] = 200605011306
azResult[9] = 16.4
azResult[10] = 3
azResult[11] = 34
azResult[12] = 45
azResult[13] = 200605011306
azResult[14] = 15.4
zErrMsg = (null)

从程序输出结果就可以看出,在删除数据前,我们有三条记录,
删除数据后我们发现,数据库内记录少了。从而实现了我们的删除数据目的。

四、Qt下SQLite数据库的使用

1、Qt对数据库的支持  

Qt中的数据库模块QtSql模块提供了对数据库的支持,该模块中的众多类基本上可分为3层:

    1.用户接口层
    QSqlQueryModel :Read-only data model for SQL result sets
    QSqlTableModel :Editable data model for a single database table
    QSqlRelationalTableModel :Editable data model for a single database table, with foreign key support

    2.SQL接口层
    QSqlDatabase 
    QSqlError 
    QSqlField 
    QSqlIndex 
    QSqlQuery 
    QSqlRecord 
    QSqlRelation 
    QSqlRelationalDelegate 
    3.sql驱动层
    QSqlResult 
    QSqlDriver
    QSqlDriverCreator 
    QSqlDriverCreatorBase 
    QSqlDriverPlugin 

 用户接口层:

    这个层中的几个类实现了将数据库中的数据链接到窗口部件上,这些类是使用模型/框架来实现的,它们是高层次的抽象,不熟SQL也可以来操作数据库.

 SQL 接口层:

    提供了对数据库的访问.

 驱动层:

    为具体的数据库和SQL接口层提供了底层的桥梁.

2、Qt下连接数据库的方法

    //指定连接数据库的驱动
    QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE"); 
    //连接到的主机名
    db.setHostName("bigblue"); 
    //连接到的数据库名称
    db.setDatabaseName("flightdb"); 
    //用户名
    db.setUserName("acarlson"); 
    //密码
    db.setPassword("123456"); 
    bool ok=db.open(); 

 3、Qt驱动数据库的实例

3.1工程文件:database.pro

    SOURCES += \ 
        main.cpp 
     
    QT += sql 
     
    HEADERS += \ 
        connection.h 

 3.2头文件:connection.h

    #ifndef CONNECTION_H 
    #define CONNECTION_H 
    #include <QMessageBox> 
    #include <QSqlDatabase> 
    #include <QSqlQuery> 
     
    static bool createConnection() 
    { 
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); 
        db.setDatabaseName(":memory:"); 
        if (!db.open()) { 
            QMessageBox::critical(0, "Cannot open database", 
                "Unable to establish a database connection.", QMessageBox::Cancel); 
            return false; 
        } 
        QSqlQuery query; 
        query.exec("create table student (id int primary key, " 
                   "name varchar(20))"); 
        query.exec("insert into student values(0, 'LiMing')"); 
        query.exec("insert into student values(1, 'LiuTao')"); 
        query.exec("insert into student values(2, 'WangHong')"); 
         
     
         
        return true; 
    } 
     
    #endif // CONNECTION_H 

3.3主文件main.cpp

    #include <QApplication> 
    #include <QSqlDatabase> 
    #include <QDebug> 
    #include <QStringList> 
    #include "connection.h" 
    #include <QVariant> 
     
    int main(int argc, char *argv[]) 
    { 
        QApplication a(argc, argv); 
     
        // 创建数据库连接 
        if (!createConnection()) return 1; 
        // 使用QSqlQuery查询整张表 
        QSqlQuery query; 
        query.exec("select * from student"); 
        while(query.next()) 
        { 
            qDebug() << query.value(0).toInt() << query.value(1).toString(); 
        } 
     
        return a.exec(); 
    } 

 4、使用sqlite

由于sqlite属于轻量级的数据库,不需要配置,不需要安装,也不需要管理员,所以也就没必要像操作mysql等数据库一样的设置主机,用户和密码了。样例如下:

#include <QApplication>
#include <QTextEdit>
#include <QString>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDriver>
#include <QDateTime>
#include <QDebug>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QTextEdit display;
    display.resize(400, 160);
    display.show();  //下面进行数据库的设置
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");  //使用sqlite数据库驱动 
    db.setDatabaseName("test");  //我们之前建立的数据库
bool ok = db.open();  //尝试连接数据库
if (ok)
    {  //这里用text已经成功连上数据库
        QSqlQuery query;  //新建一个查询的实例
if (query.exec("select * from student"))   //尝试列出 student 表的所有记录
        {  //本次查询成功
int numRows = 0;  //询问数据库驱动,是否驱动含有某种特性 
if (db.driver()->hasFeature(QSqlDriver::QuerySize))
            {
                numRows = query.size();  //如果支持结果影响的行数,那么直接记录下来
            }
else
            {
                query.last(); //否则定位到结果最后,qt 文档说,这个方法非常慢
                numRows = query.at() + 1;
                query.seek(-1);
            }
            QString name, age;
            display.append("==========================================="); 
while(query.next())
            {  //定位结果到下一条记录
                name = query.value(0).toString();
                age = query.value(1).toString();
                QString result = name + " " + age;
                display.append(result);
            }
            display.append("===========================================");
            display.append(QString("totally %1 rows").arg(numRows) );
        }
else
        {  //如果查询失败,用下面的方法得到具体数据库返回的原因
            QSqlError error = query.lastError();
            display.append("From mysql database: " + error.databaseText());
        }
    }
else
    {  //打开数据库失败,显示数据库返回的失败描述
        display.append("cannot open database.");
        display.append("Reason: " + db.lastError().databaseText());
    }
    QApplication::connect(&app, SIGNAL(lastWindowClose()), &app, SLOT(quit()));
return app.exec();
}

<think>好的,我现在需要帮助用户找到关于在Linux系统下使用sqlite3函数的教程、示例和说明文档。根据用户提供的引用资料,我需要先整理这些信息,然后生成相关的回答和相关问题。 首先,用户给出的四个引用都是关于SQLite3Linux上的使用,包括安装、基本命令、函数接口如sqlite3_open和sqlite3_close的使用示例。引用[1]和[4]提到了sqlite3_open函数的用法,引用[2]和[3]涉及安装和基本命令操作。引用[4]还提供了一个C语言的示例代码,展示了如何打开和关闭数据库,并处理错误。 接下来,我需要按照用户的系统级指令来组织回答。用户要求所有行内数学表达式用$...$,但这个问题不涉及数学公式,所以可能不需要处理这部分。独立公式需要用$$...$$,同样这里可能不适用。需要确保LaTeX语法正确,但同样问题中没有数学内容,可能不需要。用中文回答,生成相关问题,并在引用处添加标识。 用户的问题是关于Linux使用sqlite3函数的教程、示例和文档。根据引用,我需要分步骤说明,比如安装、基本命令、编程接口的使用(如打开/关闭数据库、执行SQL语句、错误处理等),并提供示例代码。引用中的示例代码可以展示如何打开数据库,检查错误,然后关闭。可能还需要提到其他函数如sqlite3_exec和sqlite3_prepare_v2,但引用中没有提到这些,所以可能需要根据现有引用内容来组织,避免引入外部知识。 然后需要生成相关问题,可能涉及性能优化、事务处理、与其他数据库对比、错误处理技巧等,这些都要基于现有的引用内容。例如,引用中提到嵌入式使用和零配置,可以生成相关问题。 需要注意引用标识的正确添加,比如在提到安装时引用[2][3],函数接口引用[1][4]。确保每个引用只在相关的地方标注,比如打开数据库的函数说明引用[1]和示例代码引用[4]。 现在开始组织回答结构: 1. 安装SQLite3:根据引用[2][3],说明在Linux上的安装方法,如使用包管理器安装。 2. 命令行使用:引用[2]中提到的运行sqlite3进入命令行,创建数据库,执行SQL命令。 3. 函数接口教程:引用[1][4]中的sqlite3_open和sqlite3_close函数,示例代码展示如何打开和关闭数据库,错误处理。 4. 其他常用函数:虽然引用中没有详细说明,但可以提及sqlite3_exec和预处理语句,但可能没有详细示例,需要根据现有内容处理。 5. 参考文档:建议查看官方文档和man page,引用[3]提到零配置特性,可能可以链接到官方资源。 相关问题部分,需要生成三个问题,可能包括事务处理、性能优化、与其他数据库对比,这些在引用中有相关点,比如嵌入式使用、零配置等。 需要检查是否所有引用都被正确引用,比如引用[4]的代码示例,引用[1]的函数说明,引用[2][3]的安装和命令行使用。确保回答结构清晰,分步骤说明,每个部分末尾正确标注引用。 可能还需要注意用户提到的“使用中文回答”,所以所有内容用中文表达,避免术语错误。例如,“sqlite3_open()函数用于打开数据库”需要正确翻译和描述。 现在开始撰写回答: 首先,安装部分,引用[2][3]说明安装步骤。然后命令行使用,创建数据库和执行命令。接着是编程接口,使用C语言的示例代码,引用[4]的代码,说明sqlite3_open和sqlite3_close的使用,错误处理。然后提到其他函数如sqlite3_exec,但引用中没有示例,可能需要简要说明。最后推荐官方文档和man page。 相关问题部分,生成关于事务处理、性能优化、与其他嵌入式数据库对比的问题,这些都与引用中的内容相关,比如SQLite适合嵌入式场景,零配置等。 确保每个引用只在被引用的地方标注,例如安装部分标注[2][3],函数接口部分标注[1][4]。</think>### Linux系统下SQLite3函数使用教程 #### 一、安装SQLite3Linux系统中,可通过包管理器直接安装: ```bash sudo apt-get install sqlite3 # Debian/Ubuntu sudo yum install sqlite3 # CentOS/RedHat ``` 安装完成后,运行 `sqlite3` 进入命令行交互模式[^2][^3]。 #### 二、基础命令行操作 1. **创建/打开数据库** ```bash sqlite3 test.db # 创建或打开名为test.db的数据库 ``` 2. **执行SQL语句** ```sql CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT); INSERT INTO users (name) VALUES (&#39;Alice&#39;); SELECT * FROM users; ``` 输入 `.exit` 退出命令行[^2]。 #### 三、C语言函数接口使用 通过SQLite3的C API可编程操作数据库,以下为关键函数示例: 1. **打开数据库** ```c #include <sqlite3.h> sqlite3 *db; int ret = sqlite3_open("test.db", &db); if (ret != SQLITE_OK) { fprintf(stderr, "数据库打开失败: %s\n", sqlite3_errmsg(db)); return -1; } else { printf("数据库打开成功\n"); } ``` `sqlite3_open()` 返回操作状态码,需检查是否成功[^1][^4]。 2. **执行SQL语句** ```c char *err_msg = NULL; const char *sql = "CREATE TABLE users (id INT, name TEXT);"; ret = sqlite3_exec(db, sql, 0, 0, &err_msg); if (ret != SQLITE_OK) { fprintf(stderr, "SQL错误: %s\n", err_msg); sqlite3_free(err_msg); } ``` `sqlite3_exec()` 用于执行非查询类SQL语句。 3. **关闭数据库** ```c sqlite3_close(db); // 释放资源 ``` #### 四、错误处理与调试 - **获取错误信息**:`sqlite3_errmsg(db)` 返回最后一次操作的错误描述。 - **事务处理**:通过 `BEGIN TRANSACTION` 和 `COMMIT` 提升批量操作性能。 #### 五、参考文档 1. **官方文档**:[SQLite官方文档](https://www.sqlite.org/docs.html) 包含完整API说明。 2. **Linux Man Page**:终端输入 `man sqlite3` 查看函数手册。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值