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次 文章链接
发表评论