1.SQLite数据库简介 

 

轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库。传统服务器型数据

库用于管理多端设备,更加复杂

SQLite

是一个无服务器的数据库,是自包含的。这也称为嵌入式数据库,这意味着数据库引擎作

为应用程序的一部分运行。

MySQL

需要运行服务器,

MySQL

将需要客户端和服务器架构通过网络进行交互。

基于嵌入式的数据库主要有:

SQLite

Firebird

Berkeley DB

eXtremeDB

Firebird

是关系型数据库,功能强大,支持存储过程,

SQL

兼容等

SQLite

关系型数据库,体积小,支持

ACID

事务

Berkeley DB

并没有数据库服务器的概念,他的程序直接链接到应用程序中

eXtremeDB

是内存数据库,运行效率高

2.下载方式

https://www.sqlite.org/download.html

1.

把下载的文件

sqlite-autoconf-3390000.tar.gz

上传到开发板

2. tar xvf sqlite-autoconf-3390000.tar.gz

解压

3. cd sqlite-autoconf-3390000

进入文件夹

4. ./configure --prefix=/usr/local

配置安装路径在

/usr/local

5. make

编译

//

比较久

10

分钟

6. sudo make install

安装

 

3.SQLite的命令用法 

创建库:

方法1:

1. sqlite3

进入数据库

2. .open test.db

3. .quit

数据库退出后在命令当前路径创建数据库

test.db

方法2:

sqlite3 test.db //

在命令运行当前窗口创建数据库

test.db

在数据库命令下

.databases

列出当前打开的数据库

.quit

退出

SQLite有两种语法

创建一张表格 

语法1:

create table stu2(id Integer,name char,score Integer);

.table可以查看创建了几个表格。

.schema可以查看表格内容

语法2:

它创建了一个 COMPANY 表,ID 作为主键,NOT NULL 的约束表示在表中创建纪录时这些字段不能为 NULL;

CREATE TABLE COMPANY(

ID INT PRIMARY KEY NOT NULL,

NAME//名字 TEXT NOT NULL,

AGE//年龄 INT NOT NULL,

ADDRESS//地址 CHAR(50),

SALARY//薪水 REAL

);

插入/写入一条记录  (增加一行)

方法一:

insert into stu values(18130106,'huang',99);

insert into stu2 values(18130101,"gang",100); ''

""

都行

insert into stu(name,score) values("huanggang",98);

插入部分字段内容  

方法二:

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)

VALUES (1, 'Paul', 32, 'California', 20000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)

VALUES (2, 'Allen', 25, 'Texas', 15000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)

VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)

VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)

VALUES (5, 'David', 27, 'Texas', 85000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)

VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );

 查看/选择数据库的记录

select * from stu; //

查询所有字段的结果

select name,score from stu; //

查询数据库中部分字段的内容

删除一条记录

delete from stu where id = 18130101;  

更改一条记录

update stu set name = 'huangg' where id = 18130106; 

删除一张表

drop table stu; 

增加一列

 alter table stu add column sex char;

qlite3_open

(

const

char *

filename

,

sqlite3

**

ppDb

)

该例程打开一个指向

SQLite

数据库文件的连接,返回一个用于其他

SQLite

程序的数据库连接对象。

sqlite3_close

(

sqlite3

*

)

该例程关闭之前调用

sqlite3_open

()

打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完

成。

如果还有查询没有完成,

sqlite3_close

()

将返回

SQLITE_BUSY

禁止关闭的错误消息。

const

char *

sqlite3_errmsg

(

sqlite3

*

);

sqlite3_errcode

()

通常用来获取最近调用的

API

接口返回的错误代码

错误代码表

sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)

该例程提供了一个执行

SQL

命令的快捷方式,

SQL

命令由

sql

参数提供,可以由多个

SQL

命令组成。

在这里,第一个参数

sqlite3

是打开的数据库对象,

sqlite_callback

是一个回调,

data

作为其第一 个参数,errmsg

将被返回用来获取程序生成的任何错误。

sqlite3_exec

()

程序解析并执行由

sql

参数所给的每个命令,直到字符串结束或者遇到错误为止。

int

callback

(

void *

arg

,

int

column_size

,

char *

column_value

[],

char

*

column_name

[])

参数分析:

void

*

arg

:是

sqlite3_exec

函数的第四个参数

column_size

:数据库的字段 数

column_value

[]

:列的值

column_name

:字段名字

1.学生成绩管理系统(SQLite3)

#include "stdio.h"

#include "stdlib.h"

#include "sqlite3.h"

#define DATABASE "stu.db"

int do_insert(sqlite3*db)//插入新一条学生数据

{

char*errmsg;

int id;

char name[32]={};

int score;

char sql[128]={};

printf("Input id:");

scanf("%d",&id);

getchar();

printf("Input name:");

scanf("%s",name);

getchar();

printf("Input score:");

scanf("%d",&score);

getchar();

sprintf(sql,"insert into stu(id,name,score)values(%d,'%s',%d);",id,name,score);

if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){

printf("%s\n",errmsg);

return -1;

}

else{

printf("Insert succesful\n");

}

return 0;

}

int do_delete(sqlite3*db)//删除一条学生数据

{

char*errmsg;

int id;

char sql[128]={};

printf("Input id:");

scanf("%d",&id);

getchar();

sprintf(sql,"delete from stu where id=%d;",id);

if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){

printf("%s\n",errmsg);

return -1;

}

else{

printf("Delete succesful\n");

}

return 0;

}

int do_update(sqlite3*db)//更新一个学生的成绩

{

char*errmsg;

int id,score;

char sql[128]={};

printf("Input id:");

scanf("%d",&id);

getchar();

printf("Input new score:");

scanf("%d",&score);

getchar();

sprintf(sql,"update stu set score=%d where id=%d;",score,id);

if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){

printf("%s\n",errmsg);

return -1;

}

else{

printf("Update succesful\n");

}

return 0;

}

int callback(void * para,int columncount,char ** columnvalue,char ** columnname)

{

for(int i=0;i

{

printf("%-11s",columnvalue[i]);

}

printf("\n");

return 0;

}

int do_query(sqlite3*db)//打印所有学生数据

{

char*errmsg;

if(sqlite3_exec(db,"select * from stu;",callback,NULL,&errmsg)!=SQLITE_OK){

printf("%s\n",errmsg);

return -1;

}

else{

printf("Update succesful\n");

}

return 0;

}

int main(int argc,char**argv)

{

sqlite3 *db;

char *errmsg;

int option;

if(sqlite3_open(DATABASE,&db)!=SQLITE_OK){//打开或新建数据库

printf("%s\n",sqlite3_errmsg(db));

exit(-1);

}

else{

printf("Open DATABASE success!\n");

}

if(sqlite3_exec(db,"create table stu(id Integer,name char,score Integer);",NULL,NULL,&errmsg)!=SQLITE_OK){//创建一张表

printf("%s\n",errmsg);

}

else{

printf("create table successful!\n");

}

while(1){

printf("*********************************************\n");

printf("1.Insert 2.delete 3.query 4.update 5.quit\n");

printf("Input Option:\n");

scanf("%d",&option);

getchar();

switch(option){

case 1:

do_insert(db);

break;

case 2:

do_delete(db);

break;

case 3:

do_query(db);

break;

case 4:

do_update(db);

break;

case 5:

sqlite3_close(db);

exit(1);

default:

printf("Input error!\n");

}

}

return 0;

}

2.从SQLite3数据库中读取数据并将存储到链表中

#include

#include

#include

typedef struct Node {

int id;

char name[100];

struct Node *next;

} Node;

//stpedef struct Node Node;的意思是Node代替struct Node这个结构体定义struct Node t1=Node t1

Node *head = NULL;//定义一个结构体指针为链表头

/*头插法*/

void addNode(int id, char *name) {

Node *newNode = (Node *)malloc(sizeof(Node));//定义一个结构体指针并开辟空间

newNode->id = id;

strcpy(newNode->name, name);

newNode->next = head;//新的指针指向原来的头

head = newNode;//新的指针被定义为头,实现了头插法

}

//exec的回调函数

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {

int id = atoi(argv[0]);//atoi将数字字符串转换为整数

char *name = argv[1];

addNode(id, name);

return 0;

}

int main() {

sqlite3 *db;

char *zErrMsg = 0;

int rc;

rc = sqlite3_open("test.db", &db);//打开指定数据库文件

if (rc != SQLITE_OK) {

fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));

return 0;

}else

{

printf("open success!\n");

}

char *sql = "SELECT * FROM students";

rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);

if (rc != SQLITE_OK) {

fprintf(stderr, "SQL error: %s\n", zErrMsg);

sqlite3_free(zErrMsg);

}else

sqlite3_close(db);//关闭数据库

Node *current = head;//再定义一个结构体指针指向链表头

while (current != NULL)//遍历链表,打印链表数据

{

printf("ID: %d, Name: %s\n", current->id, current->name);

current = current->next;

}

return 0;

}

首先,程序定义了一个 Node 结构体,表示链表中的结点。每个结点包含一个整数类型的 id 字段,一个字符数组类型的 name 字段和一个指向下一个结点的指针 next。

接下来,程序定义了一个全局变量 head,表示链表的头指针。初始时,头指针被设置为 NULL。

然后,程序定义了一个 addNode 函数,用于向链表中添加新结点。该函数接受两个参数:一个整数 id 和一个字符串 name。函数首先使用 malloc 函数为新结点分配内存空间,并将传入的 id 和 name 参数分别赋值给新结点的对应字段。然后,使用头插法将新结点插入到链表中。

接下来,程序定义了一个回调函数 callback。该函数会在 SQLite 数据库查询时被调用,并接收查询结果作为参数。函数首先从参数中提取出查询结果中的 id 和 name 字段,并调用 addNode 函数将这些数据添加到链表中。

在 main 函数中,程序首先打开 SQLite 数据库,并检查是否打开成功。然后,定义一个 SQL 查询语句,并使用 sqlite3_exec 函数执行该查询语句。在执行查询时,SQLite 会调用之前定义的回调函数,并将查询结果传递给回调函数。

查询完成后,程序关闭 SQLite 数据库,并遍历链表,打印出每个结点中存储的数据。

3.将链表中的数据传给SQLite3数据库

#include

#include

#include

typedef struct node//定义结构体变量,通过typedef 将struct node 定义为 Node,struct node t1 = Node t1

{

int data;

struct node *next;

}Node;

Node *head = NULL;//定义一个结构体指针变量指向链表头部

int insert_to_lianbiao(int data)//头插法动态建立链表,将数据插入链表

{

Node *new = (Node*)malloc(sizeof(Node));

new -> data = data;

new -> next = head;

head = new;

}

void disp()//遍历链表并打印数据

{

Node *temp = head;

while(temp != NULL)

{

printf("%d\n",temp->data);

temp = temp->next;

}

}

void send_to_db(sqlite3* db) //通过sqlite3_exec()接口函数先创建一张表文件,再向表中写入数据

{

char *errorMes;

char* sql = "create table test(data Integer);";

int ret,res;

char buffer[1024];

Node *temp = head;//定义一个结构体指针变量指向链表头

ret = sqlite3_exec(db,sql,NULL,0,&errorMes);

if(ret != SQLITE_OK)

{

printf("error:%s\n",errorMes);

exit(-1);

}

while(temp != NULL)

{

sprintf(buffer,"insert into test values(%d)",temp->data);//将数据和命令写入buffer

res = sqlite3_exec(db,buffer,NULL,0,&errorMes);//再通过exec执行

if(res != SQLITE_OK)

{

printf("error:%s\n",errorMes);

sqlite3_free(errorMes);

exit(-1);

}

temp = temp -> next;//遍历链表

}

}

int main()

{

sqlite3 *db;

int rc;

insert_to_lianbiao(1);//向链表写入数据

insert_to_lianbiao(2);

insert_to_lianbiao(3);

disp();

rc = sqlite3_open("test.db",&db);//打开数据库文件

if(rc != SQLITE_OK)

{

printf("Open error!\n");

exit(-1);

}else

{

printf("Open success!\n");

}

send_to_db(db);//向数据库写入数据

sqlite3_close(db);//关闭数据库

return 0;

}

这个程序的主要目的是将链表中的数据发送到SQLite3数据库。下面是程序中每一步的详细解释:

首先,我们定义了一个名为Node的结构体,它包含一个整型数据data和一个指向下一个节点的指针next。然后,我们定义了一个全局变量head,它是链表的头节点。接下来,我们定义了一个名为insert的函数,它用于在链表的头部插入新节点。这个函数接受一个整型参数data,表示要插入的数据。函数内部首先创建一个新节点,并将其数据设置为data,然后将其指向当前的头节点,并将头节点更新为新节点。然后,我们定义了一个名为display的函数,它用于打印链表中的所有数据。函数内部使用一个临时指针遍历链表,并打印每个节点的数据。接下来,我们定义了一个名为send_to_db的函数,它用于将链表中的数据发送到SQLite3数据库。这个函数接受一个指向sqlite3数据库对象的指针作为参数。函数内部首先定义了一条SQL语句,用于创建一个名为test的表,如果该表不存在。然后执行这条SQL语句。接着,函数使用一个临时指针遍历链表,并对于每个节点,都构造一条SQL插入语句,并执行该语句,将节点中的数据插入到数据库中。在主函数中,我们首先调用insert函数三次,向链表中插入三个数据:1、2和3。然后调用display函数打印链表中的所有数据。接下来,我们调用sqlite3_open函数打开一个名为test.db的SQLite3数据库。如果打开失败,则打印错误信息并退出程序;否则打印成功信息。然后,我们调用之前定义的send_to_db函数,将链表中的数据发送到数据库中。最后,我们调用sqlite3_close函数关闭数据库。

这是一个简单的示例程序,它演示了如何在C语言中使用SQLite数据库和链表。该程序创建了一个简单的数据库,其中包含一个表,用于存储用户信息(姓名和年龄)。程序还定义了一个链表结构,用于在内存中存储用户信息。程序包含了从数据库中查询数据并将其存储在链表中,以及将链表中的数据插入到数据库中的功能。

#include

#include

#include

#include

typedef struct User {

char name[100];

int age;

struct User *next;

} User;

User *create_user(const char *name, int age) {

User *user = malloc(sizeof(User));

strcpy(user->name, name);

user->age = age;

user->next = NULL;

return user;

}

void free_users(User *users) {

User *tmp;

while (users != NULL) {

tmp = users;

users = users->next;

free(tmp);

}

}

void print_users(User *users) {

while (users != NULL) {

printf("Name: %s, Age: %d\n", users->name, users->age);

users = users->next;

}

}

int select_callback(void *data, int argc, char **argv, char **col_name) {

User **users = data;

User *user = create_user(argv[0], atoi(argv[1]));

user->next = *users;

*users = user;

return 0;

}

User *select_users(sqlite3 *db) {

User *users = NULL;

char *err_msg = NULL;

if (sqlite3_exec(db, "SELECT name, age FROM users", select_callback, &users, &err_msg) != SQLITE_OK) {

fprintf(stderr, "Failed to select data: %s\n", err_msg);

sqlite3_free(err_msg);

free_users(users);

return NULL;

}

return users;

}

int insert_user(sqlite3 *db, const char *name, int age) {

char sql[1024];

snprintf(sql, sizeof(sql), "INSERT INTO users(name, age) VALUES('%s', %d)", name, age);

char *err_msg = NULL;

if (sqlite3_exec(db, sql, NULL, NULL, &err_msg) != SQLITE_OK) {

fprintf(stderr, "Failed to insert data: %s\n", err_msg);

sqlite3_free(err_msg);

return -1;

}

return 0;

}

int main()

{

sqlite3 *db;

if (sqlite3_open(":memory:", &db) != SQLITE_OK)

{

fprintf(stderr, "Failed to open database: %s\n", sqlite3_errmsg(db));

return -1;

}

char *err_msg = NULL;

if (sqlite3_exec(db, "CREATE TABLE users(name TEXT, age INTEGER)", NULL, NULL, &err_msg) != SQLITE_OK)

{

fprintf(stderr, "Failed to create table: %s\n", err_msg);

sqlite3_free(err_msg);

sqlite3_close(db);

return -1;

}

insert_user(db, "Alice", 20);

insert_user(db, "Bob", 30);

User *users = select_users(db);

print_users(users);

free_users(users);

}

select_callback 函数是 SQLite 的回调函数,它在执行 sqlite3_exec 函数时被调用。该函数的第三个参数 argv 是一个字符串数组,其中包含了查询结果中的一行数据。argv 数组中的每个元素都对应查询结果中的一列。

在这个示例程序中,我们执行了如下查询语句:

"SELECT name, age FROM users"

这条查询语句从 users 表中查询了两列数据:name 和 age。因此,当 select_callback 函数被调用时,argv[0] 包含了查询结果中的 name 列的值,而 argv[1] 包含了查询结果中的 age 列的值。

例如,如果查询结果包含如下数据:

name | age

-----|-----

Alice| 20

Bob | 30

那么当 select_callback 函数第一次被调用时,argv[0] 的值为 "Alice",而 argv[1] 的值为 "20"。当 select_callback 函数第二次被调用时,argv[0] 的值为 "Bob",而 argv[1] 的值为 "30"。

callback这个回调函数有几列就会执行几次,第一次argv[0]获取第一列的数据,第二次argv[1]获取第二列的数据,但是必须return0,不然会出错,只运行1次

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: