-
2021-09-18 09:56:23
Sqlite3 数据库基本操作
1、sqlite3命令
1.打开数据库: sqlite3 <*.db>
2.系统命令: 以’.'开头
.quit : 退出sqlite3 .help : 查看帮助文档 .database: 显示当前打开的数据库 .tables : 查看所有的表 .schema <table_name> :查看表结构 .indices <table_name> :查看表索引 查看系统目录 .mode col .headers on sqlite> select type, name, tbl_name, sql from sqlite_master order by type; 查看查询计划: explain query plan + 正常sql语句,该命令对于长时间查询有很大作用 explain query plan select * from stu;
3.数据导入导出
将表test数据导出到test.csv文件中 .output test.csv .separator , select * from test; 将test.csv文件导入到test2表中(test与test2表格式一样) .import test.csv test2
4.SQL命令: 以’;'结尾
1、创建表
CREATE TABLE stu (id int, name text, score real); 表名 字段名 整型 字符串 小数 CREATE TABLE stu (id int primary key, name text, score real); 注:把id字段设置为主键(在表中唯一) 创建插入式: create table foods2 as select *from foods; 创建表foods2 并将foods表中数据插入 缺点:源表中得任何约束都不会定义在新表中(自增长字段、索引、UNIOUE约束),如果定义为UNIOUE的字段中插入重复的值,sqlite会报错停止。
2、删除表
drop table <table_name>;
3、向表中添加记录
insert into <table_name> values(value1, value2, ....); insert into stu values(1, 'ZhangSan', 89.9); //插入整条数据 insert into stu(id, name) values(5, 'XiaoMing'); //只插入部分字段 insert into device_hw_param_renzheng value(1,0,5,50,'1'); 多行插入: insert into foods2 select * from foods; //将foods表所有数据插入到表foods2中,表foods2 和foods 格式保证一样
4、查询
1)查询表中所有记录 select * from <table_name>; 格式显示查找记录 .mode col .headers on select *from <table_name>; 2)按条件查询 select * from stu where name='LiSi'; select * from stu where name='root' and passwd='123456'; //同时满足条件1和2 select * from stu where name='LiSi' or id=3; //同时满足条件1或者2 select score from stu where name='LiSi' or id=3; //满足条件的某列 select name,score from stu where name='LiSi' or id=3; 限定和排序查询 select * from stu limit n offset m; //只查询前n条记录 从m+1开始 select * from stu order by id desc; //按id从大到小进行排序 desc降序 asc升序 3)删除 delete from stu where id=4; //按条件删除记录 delete from stu; //删除表中所有记录 5、更新:当有约束时会停止更新报错:PRIMARY KEY must be unique update stu set id=4,score=99.9 where id=5;(不加where所有行都会被更新) 6、增加字段: alter table stu add column <字段名> <类型>; //增加一个无初始值字段 alter table stu add column <字段名> <类型> default value; //增加一个有初始值字段 alter table <tablename_old> rename to <tablename_new> 修改表名 7、删除字段 1)create table stu as select no, name, score from student; 2) drop table student; 3) alter table stu rename to student;
2、sqlite3编程接口:
头文件: sqlite3.h 编译时: -lsqlite3 1、sqlite3_open:打开数据库 int sqlite3_open(char *path, sqlite3 **db); 参数: path: 数据库文件路径 db: 指向sqlite句柄的指针 返回值:成功返回0,失败返回错误码(非零值) 2、sqlite3_close:关闭sqlite数据库 int sqlite3_close(sqlite3 *db); 返回值:成功返回0,失败返回错误码 3、sqlite3_errmsg: 获取错误信息 const char *sqlite3_errmsg(sqlite3 *db); 返回值:返回错误信息 4、sqlite3_exec: 执行SQL操作 int sqlite3_exec(sqlite3 *db, const char *sql, sqlite3_callback callback, void *, char **errmsg); 参数: db:数据库句柄 sql:SQL语句 callback:回调函数 errmsg:错误信息指针的地址 返回值:成功返回0,失败返回错误码 typedef int (*sqlite3_callback)(void *para, int f_num, \ char **f_value, char **f_name); 功能:每找到一条记录自动执行一次回调函数 参数: para:传递给回调函数的参数 f_num:记录中包含的字段数目 f_value:包含每个字段值的指针数组 f_name:包含每个字段名称的指针数组 返回值:成功返回0,失败返回-1 5、不使用回调函数执行SQL语句 int sqlite3_get_table(sqlite3 *db, const char *sql, \ char ***resultp, int*nrow, int *ncolumn, char **errmsg); 功能:执行SQL操作 参数: db:数据库句柄 sql:SQL语句 resultp:用来指向sql执行结果的指针 nrow:满足条件的记录的数目(行) ncolumn:每条记录包含的字段数目(列) errmsg:错误信息指针的地址 返回值:成功返回0,失败返回错误码 6、准备语句:准备语句(prepared statement)对象一个代表一个简单SQL语句对象的实例,这个对象通常被称为“准备语句”或者“编译好的SQL语句”或者就直接称为“语句”。 语句对象的生命周期经历这样的过程: l 使用sqlite3_prepare_v2或相关的函数创建这个对象 2 使用sqlite3_bind_*()给宿主参数(host parameters)绑定值 sqlite3_bind_int(sqlite3_stmt*,int,int); sqlite3_bind_double(sqlite3_stmt*,int,double); sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void *)); 参数:sqlite3_stmt*:准备语句变量指针。 int:sqlite3_stmt变量参数的序号索引值,规定最左侧的sql参数的索引值为1,也就是说参数索引值从1开始。 第三个参数:要给第二个参数指向的变量的实际值,第二个参数可以指向不同的索引值。 第四个参数:第三个参数的长度。 第五个参数:一般为NULL。 3 通过调用sqlite3_step一次或多次来执行这个sql 4 使用sqlite3——reset()重置这个语句,然后回到第2步,这个过程做0次或多次 5 使用sqlite3_finalize()销毁这个对象 int sqlite3_prepare(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail); 功能:这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。 这个接口需要一个数据库连接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句 参数:db:数据指针 zSql:sql语句,使用UTF-8编码 nByte:如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止 pzTail:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符 ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。 返回值:如果执行成功,则返回SQLITE_OK,否则返回一个错误码。 7、 PRAGMA synchronous:获取或设置当前磁盘的同步模式,该模式控制积极的sqlite如何将数据写入物理存储 PRAGMA值:0或OFF: 不进行同步 很快,但是可能会导致数据库损坏,定期备份并且少量数据丢失可接受,选择off 1或NORMAL:在关键的磁盘操作的每个序列后同步 较快但是有概率导致数据库损坏 2或FULL: 在每个关键的磁盘操作后同步 安全但是很慢
3、事务:一个或多个更改数据库的扩展
命令: begin transaction:开始处理事务 commit transaction/end transaction:保存更改, rollback transaction:回滚所做的更改 begin transaction:启动事务,直到遇到下一个commit或rollback,当数据库关闭或发生错误时,也会回滚。 commit:把事务调用的更改保存到数据库中 rollback:撤销尚未保存到数据库的事务命令,只能撤销上自次发出的commit或rollback命令以来的事务。
4、like和glob子句:
用于匹配通配符指定模式的文本,匹配成功返回true,glob区分大小写 like: % _ where salary like '200%' 查找以200开头的任意值 where salary like '%200%' 查找任意位置包含200的任意值 where salary like '_00%' 查找第二位和第三位为00的任意值 where salary like '2_%_%' 查找以2开头、且长度至少为3个字符的任意值 where salary like '%2' 以2结尾的任意值 where salary like '_2%3' 查找第二位为2,且以3结尾的任意值 where salary like '2___3' 查找长度为5,且以2开头以3结尾的任意值。 例子:select * from company where age Like '2%'; glob: * ? where salary glob '200*' 查找以200开头的任意值 where salary glob '*200*' 查找任意位置包含200的任意值 where salary glob '?00*' 查找第二位和第三位为00的任意值 where salary glob '2??' 查找以2开头、且长度至少为3个字符的任意值 where salary glob '*2' 以2结尾的任意值 where salary glob '?2*3' 查找第二位为2,且以3结尾的任意值 where salary glob '2???3' 查找长度为5,且以2开头以3结尾的任意值。 例子:select * from company where age glob '2*';
5、limit 和 offset
例子:select *from company limit 3 offset 2; 从第三位提取三个记录
6、having:
having子句允许指定条件来过滤将出现在结果中的分组结果,having子句必须出现在group by 子句之后,order by之前。 例子:select *from company group by name having count(age>20); 查找年纪大于20岁的记录
7、distinct
distinct:与select一起使用,消除重复记录,只获取唯一一次的记录。 例子:select distinct name from company;
8、约束:
约束是在表的数据列上强制执行的规则。 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); 创建新表,其中id、name、age 不为空。 DEFAULT 约束:当某列中没有指定值时,为该列提供默认值 UNIQUE 约束:确保某列值是不同的 PRIMARY KEY 约束:主键,唯一标识 "integer primary key"创建的主键确保值是唯一的 "integer primary key autoincrement"创建的主键新插入数据值会比当前值大,达到最大值时返回SQLITE_FULL. CHECK 约束:确保某列中的所有值都满足一定条件
9、内连接
内连接:从两表之间找出相同值得行 select * from foods inner join food_types on foods.id = food_types.id; select * from foods, food_types where foods.id = food_types.id;
10、别名
别名:在from子句中对表得重命名 select foods.name, food_types.name from foods, food_types where foods.type_id = food_types.id limit 10; select f.name, t.name from foods f, food_types t where f.type_id = t.id limit 10;
11、触发器
触发器:是数据库的回调函数,他会在指定数据库事件发生时自动调用。 1. 触发器可以指定在特定数据库表发生delete、insert、update时触发,或在一个或多个表的列发生变化时更新触发。 2. WHEN子句和触发器动作可能使用表单 NEW.col-name和OLD.col-name的引用插入、删除、更新的行元素,col-name是与触发器关联表的列名称。 3. 如果有WHEN语句,则只针对WHEN子句为真的指定执行SQL语句,如果没用WHEN语句,则针对所有执行SQL语句。 4. before和after关键字决定何时执行触发器动作,决定在关联行的插入、修改、删除之前或者之后触发触发器。 当 record_f_num > 12000时候,删除checkin_f 表中时间最早的一条记录 CREATE TRIGGER checkin_max_12K after update on log WHEN new.key='record_f_num' AND new.value>12000 BEGIN delete from checkin_f where check_in_time in (select check_in_time from checkin_f order by check_in_time limit 1 offset 0); END
12. 索引
索引:加速数据检索 1. 基本语法:CREATE INDEX checkin_f_query on checkin_f; 2. 单例索引:基于一个表上一个列的索引。CREATE INDEX checkin_f_query on checkin_f (userid); 3. 唯一索引:不允许重复的值插入表中。CREATE UNIQUE INDEX checkin_f_query on checkin_f (userid, check_in_time); 4. 删除索引:DROP INDEX checkin_f_query
更多相关内容 -
Sqlite3类库,包括sqlite3.dll、sqlite3.h和sqlite3.lib
2019-04-19 13:43:09Sqlite3类库,sqlite数据库开发时,需要用到Sqlite3类库,快速开发必备。 -
sqlite3.h、sqlite3.lib、sqlite3.dll
2018-03-21 23:23:2132位及64位的sqlite3.h、sqlite3.lib、sqlite3.dll下载 -
SQlite3库及头文件分享
2016-02-26 15:58:32文件列表:1)sqlite3.h;2)sqlite3.lib;3)sqlite3.dll; 学习VS2010/MFC下数据库编程已经有一段时间了,大多是在网站上浏览一些资源,这些资源大多以VC6.0位开发环境,而在VS2010下往往出现问题,所幸看到了... -
sqlite3.exe绿色版 下载
2013-10-01 17:27:26SQLite是一款轻型的数据库,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作... -
svn 出错误清理工具sqlite3.exe
2016-09-18 13:22:40当svn 出现clean up 死循环时,或者...1.把sqlite3.exe放到.svn文件夹下 2.在.svn目录下打开命令行输入以下语句: sqlite3 wc.db "delete from work_queue" sqlite3 wc.db "delete from wc_lock" 3. svn 执行clean up -
SQLite数据库使用(sqlite3 c++)
2022-03-29 09:21:59本文只针对sqlite3 c++ API调用。 1、基础知识 sqlite3只是一个嵌入式数据库引擎,占用资源非常底,可以适用于Windows和Linux,而且sqlite3只是一个文件,不需要服务器进程。 sqlite3 c++ api接口只需要引用...本文只针对sqlite3 c++ API调用。
1、基础知识
sqlite3只是一个嵌入式数据库引擎,占用资源非常底,可以适用于Windows和Linux,而且sqlite3只是一个文件,不需要服务器进程。
sqlite3 c++ api接口只需要引用sqlite3.h头文件就行。
常用术语:表(table)、字段(column,列,属性)、记录(row,record)。
存储类型:integer(整型)、real(浮点型)、text(文本字符串)、blob(二进制数据)。
关键字:select、insert、update、delete、from、creat、where、desc、order、by、group、table、alter、view、index等,数据库中不能使用关键字命名表和字段。
2、数据库语句
2.1、创建或打开数据库
对应c++代码
//不存在即创建数据库 sqlite3* db; int res = sqlite3_open(sql_name,&db); if(res) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); qDebug() << "database failed to open "; } else{ qDebug() << "database open sucess"; }
2.2、数据定义语句
- 新建表 ⟹ create:create table 表名 (字段名1 字段类型1,字段名2 字段类型2,。。。); create table if not exists 表名 (字段名1 字段类型1,字段名2 字段类型2,。。。);
CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL);
- 删除表 ⟹ drop:dorp table 表名;drop table if exists 表名;
DROP TABLE IF EXISTS t_person;
对应c++代码:
//回调函数 static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; }
//判断表是否存在 /* Create SQL statement */ char *sql = "CREATE TABLE IF NOT EXISTS COMPANY(" \ //只是创建表 "CREATE TABLE COMPANY(" "ID INT PRIMARY KEY NOT NULL," \ "TIME_START TEXT NOT NULL," \ "TIME_END TEXT NOT NULL," \ "DETECT_IP TEXT NOT NULL," \ "CONTAINER_NUM TEXT NOT NULL," \ "REAL_RESULTS TEXT NOT NULL," \ "DETECT_RESULTS TEXT NOT NULL," \ "DETECT_TIME TEXT NOT NULL," \ "NOTE TEXT NOT NULL);"; /* Execute SQL statement */ char *zErrMsg = 0; int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Table created successfully\n"); }
//若存在则删除表 /* drop SQL statement */ char *sql_d = "DROP TABLE IF EXISTS COMPANY;"; //删除表不做判断 "DROP TABLE COMPANY(" /* Execute SQL statement */ char *zErrMsg = 0; int rc = sqlite3_exec(db, sql_d, NULL, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Table drop successfully\n"); }
2.3、数据操作语句
- 添加表中的数据 ⟹ insert:insert into 表名 (字段1,字段2,。。。) values (字段1的值,字段2的值);字符串内容用单引号。
INSERT INTO t_person (name, age) VALUES ('大明', 22);
- 修改表中的数据 ⟹ update:update 表名 set 字段1 = 字段1的值,字段2 = 字段2的值,。。。;
UPDATE t_person SET name = '小明', age = 10; // 把表中name字段的值全部改成小明,age字段的值全部改成10。
UPDATE t_person SET age = 12 WHERE name = '小明'; // 把表中name字段值是小明的age值改为12。
- 删除表中的数据 ⟹ delete:delete from 表名;delete from 表名 where 字段 = 字段值。
DELETE FROM t_person; // 删除表中的所有记录。
DELETE FROM t_person WHERE age = 25; // 删除表中字段age等于25的这条记录。
DELETE FROM t_person WHERE age > 12 AND age < 15; // 删除表中年龄大于12且小于15的记录。
写入数据方式一:
sqlite3* db; int res = sqlite3_open(sql_name,&db); if(res) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); qDebug() << "database failed to open "; } else{ qDebug() << "database2 open sucess"; } /* INSERT SQL statement */ ID += 1; time_start =QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz").toLongLong(); time.start(); char *zErrMsg = 0; std::string local_ip = "'192.168.53.21'"; int64_t time_end =QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz").toLongLong(); std::string container_num = "'#^XH^123456^42G1^'"; QString isEmptoy = "'空箱'"; //char detect_results = 0x00; std::string detect_results_sql; std::string note = "''" ; qDebug()<< "detect_results : "<<detect_results; detect_results_sql = "'未执行检测'"; note = "'设备防夹保护触发,设备停止运动'"; int timeElapsed = time.elapsed(); qDebug()<< "timeElapsed : "<<timeElapsed<<" ms"; //float detect_time = float(time_end -time_start)/1000; float detect_time = float(timeElapsed)/1000; std::string sql_add = "INSERT INTO COMPANY (ID,TIME_START,TIME_END,DETECT_IP,CONTAINER_NUM,REAL_RESULTS,DETECT_RESULTS,DETECT_TIME,NOTE) " "VALUES(" + std::to_string(ID)+","+ std::to_string(time_start)+","+ std::to_string(time_end)+","+local_ip+"," ""+container_num+","+isEmptoy.toStdString()+","+detect_results_sql+","+std::to_string(detect_time)+","+note+"); " ; /* Execute SQL statement */ int rc = sqlite3_exec(db, sql_add.c_str(), callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "INSERT2 created successfully\n"); } sqlite3_close(db); }
写入数据方式二:
第二种写入数据的方式------------------------------------------ sqlite3_exec(db,"begin;",0,0,0); int64_t time_start =QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz").toLongLong(); std::string local_ip = "192.168.53.21"; sqlite3_stmt *stmt; const char* sql_insert = "INSERT INTO COMPANY (ID,TIME_START,DETECT_IP) VALUES(?,?,? );" ; int ret = sqlite3_prepare_v2(db,sql_insert,-1,&stmt,0); if(ret == SQLITE_OK) { sqlite3_bind_int(stmt,1,1); sqlite3_bind_int64(stmt,2,time_start); //sqlite3_bind_text(stmt,2,local_ip.c_str(),-1,SQLITE_STATIC); sqlite3_bind_text(stmt,3,local_ip.c_str(),-1,SQLITE_STATIC); ret = sqlite3_step(stmt); // if(rc != SQLITE_DONE) // { // fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); // sqlite3_close(db); // } sqlite3_reset(stmt); sqlite3_finalize(stmt); } else { fprintf(stderr, "SQL error: %s\n", zErrMsg); } sqlite3_exec(db,"commit;",0,0,0); sqlite3_free(zErrMsg);
2.3查询数据
- select:select 字段1, 字段2, 。。。 from 表名;select 字段1, 字段2, 。。。 from 表名 where 字段 = 某值;select * from 表名;(查询所有的字段)
- 表别名:select 字段1 别名, 字段2 别名,。。。from 表名 别名;select 字段1 别名, 字段2 as 别名,。。。from 表名 as 别名;select 别名.字段1,别名.字段2,。。。from 表名 别名;
SELECT name, age FROM t_person WHERE age < 80;
SELECT * FROM t_person WHERE age < 80;
SELECT name, age nianling FROM t_person ren WHERE ren.age > 80 AND nianling < 90;
- 计算记录条数:select count(字段或者*) from 表名;
SELECT count(name) FROM t_person ren WHERE ren.age > 80;
SELECT count(*) FROM t_person ren WHERE ren.age > 80;
- where:where 字段 = 某值;where 字段 is 某值;where 字段 != 某值;where 字段 is not 某值;where 字段 > 某值;where 字段1 = 某值1 and 字段2 < 某值2;where 字段1 = 某值1 or 字段2 > 某值2;
- order by:select * from 表名 order by 字段(默认升序);select * from 表名 order by 字段 desc(降序);select * from 表名 order by 字段 asc(升序);select * from 表名 order by 字段1 asc(先按字段1升序),字段2 desc(再按字段2降序);
SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC; // 先按年龄降序,再按名字升序。
- limit:select * from 表名 limit 数值1,数值2;分页查询,数值1表示跳过前面多少条,数值2表示取出之后多少条。select * from 表名 limit 数值2;(跳过前面0条,相当于select * from 表名 limit 0,数值2,表示最前面多少条数据)
SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC LIMIT 3, 5; // 先筛选,后排序,再分页。
- like:模糊查询,select 字段1, 字段2, 。。。 from 表名 where 字段 like %某值%;
SELECT * FROM t_person WHERE name like '%明%';
查询ID:(用处:获取当前数据库的所写的行数)
//获取当前数据库最大ID值 char **dbresult; int nrow,ncolumn; char *sql_select = "SELECT * from COMPANY"; res = sqlite3_get_table(db,sql_select,&dbresult,&nrow,&ncolumn,&zErrMsg); if(res == SQLITE_OK) { //查询成功 ID = nrow; qDebug() << "nrow :" << nrow; } else{ fprintf(stderr, "SQL error: %s\n", zErrMsg); qDebug() << "SELECT error :" ; } //释放 dbresult 的查询结果 sqlite3_free_table(dbresult);
3、Ubuntu和nano安装sqlite3
3.1、Ubuntu安装sqlite3
sudo apt-get install sqlite3 //查看版本信息 sqlite3 -version
3.2、nano安装sqlite3
使用apt在Nano上安装,但是找不到sqlite3.h,所以只能使用源码编译。
下载源码:SQLite Download Page
//解压 tar xvzf sqlite-autoconf-3310100.tar.gz //进入sqlite文件夹 cd sqlite-autoconf-3310100 //配置文件 ./configure //开始编译 make //写入系统文件中 sudo make install //查看文件路径 dpkg -L sqlite3
-
Sqlite3+VB
2015-02-06 08:00:10非原创,感谢原作者。VB下使用Sqlite3,网上代码很多,但要筛选使用。这个测试可用。因为博客没法上传文件,所以上传在这里。 -
sqlite3.zip
2017-03-31 09:55:27SQLite3占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。SQLite3能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如Tcl、PHP、Java等,还有ODBC接口,同样比起... -
ASqlite3 Delphi xe 中文修改版
2013-10-08 21:18:57function TASQLite3DB.SQLite3_ExecSQL(TheStatement: string; Fields : TFields): integer; 具体修改说明可以参见 http://www.360doc.com/showweb/0/0/319640034.aspx. 测试 TASqlite3Table,TASqlite3Query使用... -
SQLite3-轻量级数据库
2022-03-09 00:37:29SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常...SQLite主页:SQLite Home Page
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2021年已经接近有21个年头,SQLite也迎来了一个版本 SQLite3 已经发布。下面介绍 SQLite3 的使用方法。
目录
2. 非回调使用sql语句查询数据库 (sqlite3_get_table)
8. 释放查询结果 (sqlite3_free_table)
一、文件准备
以下文件均从SQLite官网下载。
- sqlite-amalgamation-3380000.zip
- sqlite-dll-win64-x64-3380000.zip
二、编译静态库
本节介绍文件 sqlite3.lib 的编译方法。
1. 编译文件
- 模块定义文件:sqlite3.def
2. 编译过程
开始 --> Visual Studio 2022 --> x64 Native Tools Command Prompt for VS 2022
- 打开 sqlite3.def 文件的路径
cd /d D:\tmp-source\qt-hmi\SQL\sqlite-dll-win64-x64-3330000
- 生成 sqlite3.lib 文件
LIB /DEF:sqlite3.def /machine:X64 //64位 LIB /DEF:sqlite3.def /machine:X86 //32位
3. 拓展-当只有dll文件时
- 需要先通过 dll 文件生成 def 文件
dumpbin /exports sqlite3.dll > sqlite3.def LIB /DEF:sqlite3.def /machine:X64 //64位 LIB /DEF:sqlite3.def /machine:X86 //32位 // OR LIB /DEF:sqlite3.def /machine:i386 /out:sqlite3.lib
4. 文件使用说明
包含 sqlite3.h 头文件,将 sqlite3.lib 库文件链接到项目中即可。
#pragma comment (lib, "sqlite3.lib")
三、编译动态库
本节介绍编译 sqlite.dll 的方法以及编译环境的配置。
1. 编译文件
- 头文件:sqlite3.h
sqlite3ext.h - 源文件:sqlite3.c
- 模块定义文件:sqlite3.def
2. 编译环境配置
此处仅展示32位dll文件编译环境配置
- 创建 win32 项目,设置 常规 --> 配置类型 和 高级(VS2022) --> 目标文件拓展名 为 .dll
- C/C++ --> 预处理器 --> 预处理器定义 (添加)
SQLITE3_EXPORTS SQLITE_ENABLE_RTREE SQLITE_ENABLE_COLUMN_METADATA SQLITE_ENABLE_FTS5
- C/C++ --> 不使用预编译头
- 链接器 --> 输入 --> 附加库依赖项 (添加) sqlite3.lib 文件
- 链接器 --> 输入 --> 模块定义文件 (添加) sqlite3.def 文件
3、文件使用说明
将编译完成的动态库和可执行程序放置同一目录下。
四、SQLite3常用函数
1. 创建/打开数据库 (sqlite3_open)
int sqlite3_open( const char *szFilename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ );
功能:创建/打开数据库。
参数:szFilename:数据库路径及名称;
ppDb:数据库句柄。
返回值:执行成功返回 SQLITE_OK (值为0),否则返回其他值。2. 非回调使用sql语句查询数据库 (sqlite3_get_table)
int sqlite3_get_table( sqlite3 *pDb, /* An open database */ const char *szSql, /* 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 */ );
功能:非回调执行sql语句。
参数:pDb:数据库句柄;
szSql:要执行的SQL语句;
pazResult:查询结果 (一维数组);
pnRow:查出结果数据条数 (查询结果行数);
pnColumn:查出结果包含的字段数 (查询结果列数);
pzErrMsg:程序报错时输出的错误信息。
返回值:执行成功返回 SQLITE_OK,否则返回其他值。
备注:pazResult的字段值是连续的一维数组,索引区间 [0, pnColumn-1] 内存储字段名称,从索引 pnColumn 开始,后面都存字段内容。3. 回调执行sql语句 (sqlite3_exec)
int sqlite3_exec( sqlite3 *pDb, /* The database on which the SQL executes */ const char *szSql, /* The SQL to be executed */ sqlite3_callback xCallback, /* Invoke this callback routine */ void *pArg, /* First argument to xCallback() */ char **pzErrMsg /* Write error messages here */ );
功能:执行零个或多个SQL 语句 (增删查改),查询的结果返回给回调函数 xCallback。
参数:pDb:数据库句柄;
szSql:待执行的SQL 语句字符串,以’\0’结尾;
xCallback:回调函数,用来处理查询结果,如果不需要回调 (比如做insert 或者delete 操作时),可以输入NULL;
pArg:要传入回调函数的指针参数,没有可以置为NULL;
paErrMsg:返回错误信息,注意是指针的指针。
返回值:执行成功返回 SQLITE_OK,否则返回其他值。4. 回调函数 (callback)
typedef int (*sqlite3_callback)( void *para, int nColCount, char **pazResult, char **pazColName );
功能:由用户处理查询的结果。
参数:para:从sqlite3_exec() 传入的参数指针;
nColCount:查询到的这一条记录有多少个字段(即这条记录有多少列);
pazResult:查询出来的数据都保存在这里 (char* 的一 维数组,以‘\0’结尾);
pazResultName:与 pazResult 对应,表示对应数据的字段名称。
返回值:执行成功返回 SQLITE_OK,否则返回其他值。5. 调试数据库 (*sqlite3_errmsg)
const char *sqlite3_errmsg(sqlite3 *pDB);
功能:获取最近调用的 API 返回的错误信息 (错误信息以 UTF-8 编码返回,并在下一次调用任何SQLite API 时被自动清除)。
输入参数:pDB:打开的数据库句柄。
返回值:错误信息字符串的指针。6. 关闭数据库 (sqlite3_close)
int sqlite3_close(sqlite3 *pDb);
功能:关闭数据库。
参数:pDb:数据库句柄。
返回值:执行成果返回 SQLITE_OK,若句柄繁忙返回 SQLITE_BUSY。7. 释放错误信息 (sqlite3_free)
void sqlite3_free(void *pErrMsg );
功能:释放存放错误信息的内存空间。
参数:pErrMsg: 返回的错误信息。8. 释放查询结果 (sqlite3_free_table)
void sqlite3_free_table(char ***pazResult);
参数:pazResult:查询结果 (一维数组)。
五、程序示例
下面的程序中展示了前文所述方法的具体用法。
// Win32ConsoleApp.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" using namespace std; bool bCallbackFlag = true; // 回调函数 static int callback(void* NotUsed, int nColCount, char** pazResult, char** pazResultName) { if (bCallbackFlag == true) { for (int nIndex = 0; nIndex < nColCount; ++nIndex) { printf("%s\t", pazResultName[nIndex] ? pazResultName[nIndex] : "NULL"); } printf("\n"); printf("-----------------------\n"); bCallbackFlag = false; } for (int nIndex = 0; nIndex < nColCount; ++nIndex) { printf("%s\t", pazResult[nIndex] ? pazResult[nIndex] : "NULL"); } printf("\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { typedef struct cPerson { char* name; int age; char* sex; } cPerson; cPerson OfficePerson[] = { "David", 22, "man", "Eve", 28, "man", "Frand", 21, "woman" }; sqlite3 *pDb; // 数据库句柄 char *szErrMsg; // 错误信息 // 打开数据库连接 long nRet = sqlite3_open("people.db", &pDb); assert(SQLITE_OK == nRet); // 使用sqlite3_exec()创建表 const char *szSql = "CREATE TABLE IF NOT EXISTS person(name VARCHAR(128)," "age INTEGER," "sex VARCHAR(7)" ");"; nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &szErrMsg); if (nRet != SQLITE_OK) { printf("%s\n", szErrMsg); sqlite3_close(pDb); return 1; } // 使用sqlite3_exec()删除字段 szSql = "DELETE FROM person;"; nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &szErrMsg); if (nRet != SQLITE_OK) { printf("%s\n", szErrMsg); sqlite3_close(pDb); return 1; } // 使用sqlite3_exec()插入数据 szSql = "INSERT INTO person(name,age,sex) VALUES(\"Alice\",15,\"woman\");"; nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &szErrMsg); assert(SQLITE_OK == nRet); szSql = "INSERT INTO person(name,age,sex) VALUES(\"Bob\",18,\"man\");"; nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &szErrMsg); assert(SQLITE_OK == nRet); szSql = "INSERT INTO person(name,age,sex) VALUES(\"Charli\",11,\"man\");"; nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &szErrMsg); assert(SQLITE_OK == nRet); // 使用sqlite3_exec()查询数据 printf("===== query by sqlite3_exec() =====\n\n"); szSql = "SELECT name,age,sex FROM person;"; nRet = sqlite3_exec(pDb, szSql, callback, NULL, &szErrMsg); assert(SQLITE_OK == nRet); // 使用sqlite3_get_table()查询数据 printf("\n\n===== query by sqlite3_get_table() =====\n\n"); szSql = "SELECT name,age,sex FROM person;"; int nRow, nCol; char **pazResult; nRet = sqlite3_get_table(pDb, szSql, &pazResult, &nRow, &nCol, &szErrMsg); assert(SQLITE_OK == nRet); for (int nIndex = 0; nIndex < nCol; ++nIndex) { printf("%s\t", pazResult[nIndex] ? pazResult[nIndex] : "NULL"); } printf("\n"); printf("-----------------------\n"); for (int nIndex = nCol; nIndex < (nRow+1)*nCol; ++nIndex) { printf("%s\t", pazResult[nIndex] ? pazResult[nIndex] : "NULL"); if ((nIndex+1)%nCol == 0) { printf("\n"); } } // 使用sqlite3_prepare_v2(), sqlite3_bind_...() 插入数据 const char* pzTail; sqlite3_stmt* pstmt; szSql = "INSERT INTO person(name,age,sex) VALUES(?,?,?);"; nRet = sqlite3_prepare_v2(pDb, szSql, strlen(szSql), &pstmt, &pzTail); assert(SQLITE_OK == nRet); for (int nIndex = 0; nIndex < sizeof(OfficePerson) / sizeof(cPerson); ++nIndex) { int nCol = 1; sqlite3_bind_text(pstmt, nCol++, OfficePerson[nIndex].name, strlen(OfficePerson[nIndex].name), NULL); sqlite3_bind_int(pstmt, nCol++, OfficePerson[nIndex].age); sqlite3_bind_text(pstmt, nCol++, OfficePerson[nIndex].sex, strlen(OfficePerson[nIndex].sex), NULL); sqlite3_step(pstmt); sqlite3_reset(pstmt); } sqlite3_finalize(pstmt); // 使用sqlite3_prepare_v2(), sqlite3_column_...() 查询数据 printf("\n\n====== query by sqlite3_prepare_v2() ======\n\n"); const unsigned char* pTmp; int age; szSql = "SELECT name,age,sex FROM person;"; nRet = sqlite3_prepare_v2(pDb, szSql, strlen(szSql), &pstmt, &pzTail); assert(SQLITE_OK == nRet); bool nPrintFlag = true; while (true) { if (nPrintFlag == true) { printf("name\tage\tsex\n"); printf("-----------------------\n"); nPrintFlag = false; } nRet = sqlite3_step(pstmt); if (SQLITE_DONE == nRet) { sqlite3_finalize(pstmt); break; } if (SQLITE_ROW == nRet) { int nCol = 0; pTmp = sqlite3_column_text(pstmt, nCol++); printf("%s\t", pTmp); age = sqlite3_column_int(pstmt, nCol++); printf("%d\t", age); pTmp = sqlite3_column_text(pstmt, nCol++); printf("%s\n", pTmp); continue; } printf("something error.\n"); sqlite3_finalize(pstmt); break; } sqlite3_close(pDb); // 关闭数据库 return 0; }
六、数据库管理工具介绍
本节内容源自博客园某位博主,进行简单排版。原文链接如下:SQLite可视化管理工具汇总 - Man_华 - 博客园 (cnblogs.com)
1. 免费且保持更新
截至 2012/9/14 最新版本 SQLiteSpy 1.9.1 – 28 Jul 2011
单文件,界面设计紧凑,较稳定,功能较少,创建表与添加数据均需sql语句,快捷键教方便,
作为数据浏览和修改工具极佳,视图编码为utf-8,对gbk2312显示乱码。能满足一般的应用,但没有导出数据表功能,同时只能打开一个数据库文件,不支持二进制字段编辑。- SQLiteStudio:http://sqlitestudio.one.pl/
【推荐】开源,单文件;
更新及时,功能完善的sqlite2和sqlite3工具,视图编码支持utf8。支持导出数据格式:csv、html、plain、sql、xml。可同时打开多个数据库文件,支持查看和编辑二进制字段。- SQLiteExpert:SQLite administration | SQLite Expert
个人免费 ,需安装;
功能非常强大,如果上述两款不能满足,就试试这个吧。- SQLite Manager (Firefox插件):https://addons.mozilla.org/zh-cn/firefox/addon/sqlite-manager/
基本功能齐全,可以将数据表导出为sql数据格式。
2. 免费但可能已停止更新
- Sqlite3Explorer:http://www.singular.gr/sqlite/
两年未更新,截至2012/9/14最新版本 V3.04 04/12/2010;但xp下只是别gbk2312编码,界面紧凑,功能全面。
- SQLite Database Browser (作者使用):http://sqlitebrowser.sourceforge.net/
简单易用,具有基本数据库管理查询功能,并且能够导入和导出数据表,支持sql文件和csv两种方式。似乎不再更新,截至2012/9/14最新版本:Version 2.0b1 released - Based on Qt4.6 - 12/09/2009。
功能齐全,界面有多语言,带导出功能,很久未更新,只识别sqlite2,可用于sqlite2到sqlite3的转换,win xp下视图的编码为gbk2312,对utf-8显示乱码。截至2012/9/14最新版本 [0.8.3.2]大概是2007年10月份。
3. 收费版-通常功能丰富且更新及时
- Sqlite.Developer:http://www.sqlitedeveloper.com
有中文版。
- SQLite Code Factory:Database tools for MySQL, SQL Server, PostgreSQL, SQLite, Oracle, DB2, Firebird by SQL Maestro Group
非商业单用户,该公司出品了很多数据库管理工具,如同类产品 SQLite Maestro。
需安装。
- Navicat for SQLite:Navicat GUI | DB Admin Tool for MySQL, PostgreSQL, MongoDB, MariaDB, SQL Server, Oracle & SQLite client
很好用,很强大,不过价格较高,适合企业使用。
-
Delphi使用SQLite3内存数据库
2014-11-11 16:22:58Delphi使用SQLite3,包括本地数据库和内存数据库,本地数据库加载到内存,内存数据库备份到本地,使用sqlite simple delphi包装类。 -
sqlite3 加密 解密
2013-05-23 10:45:13一般的sqlite3不带加密功能,此包提供加密解密功能,让数据更安全 windows上生成lib,和dll文件放到你的工程下面即可 其他平台如cocos2d-x 移到android上只需将sqlite3secure.c编译到工程里面即可 -
delphi+sqlite3带加密Demo
2012-08-07 10:16:051、获取sqlite3.dll,去网上下载wxsqlite3的最新版本代码,解压后其中有一个sqlite3目录,其中有编译好的版本,lib目录下的是原版本,secure目录下有aes128和aes256两个带加密的版本,直接拿其中任一个sqlite3.dll... -
mfc数据库sqlite3的基本操作
2018-11-14 11:31:24包括数据库的创建,添加表格,插入、删除,修改数据等功能。 -
一文掌握SQLite3基本用法
2021-08-10 17:31:58导入/导出数据库 sqlite3 test.db .dump > filename --导出 sqlite3 test.db 导入 上面的转换流整个 testDB.db 数据库的内容到 SQLite 的语句中,并将其转储到 ASCII 文本文件 testDB.sql 中。您可以通过简单的...目录
一、基本语法
1.常用指令
.open filename --打开文件 -- 注解 .show --显示SQLite 命令提示符的默认设置 .q --退出 .databases --显示数据库(注:显示打开的数据库) .help --帮助 .dump --导入导出数据库 .tables --查看表
2.数据类型
存储类型 描述 NULL 空值 int 整形 text 一个文本字符串 blob 一个blob数据 integer 一个带符号的整数,根据值的大小存储在1、2
、3、4、6或8字节中
real 值是一个浮点值,存储为8字节的浮点数 ...... ...... 3.创建数据库
.open test.db --没有就创建 sqlite3 DatabaseName.db
上面的命令将在当前目录下创建一个文件 testDB.db。该文件将被 SQLite 引擎用作数据库。如果您已经注意到 sqlite3 命令在成功创建数据库文件之后,将提供一个 sqlite> 提示符。
.databases 命令用于检查它是否在数据库列表中。
.open 操作
4. 导入/导出数据库
sqlite3 test.db .dump > filename --导出 sqlite3 test.db < filename --导入
上面的转换流整个 testDB.db 数据库的内容到 SQLite 的语句中,并将其转储到 ASCII 文本文件 testDB.sql 中。您可以通过简单的方式从生成的 testDB.sql 恢复,如下所示 我删掉testDB.db后:
5.创建表
--注意,在打开数据库时才能操作 CREATE TABLE database_name.table_name( column1 datatype PRIMARY KEY(one or more columns), column2 datatype, column3 datatype, ..... columnN datatype, );
CREATE TABLE 是告诉数据库系统创建一个新表的关键字。CREATE TABLE 语句后跟着表的唯一的名称或标识。您也可以选择指定带有 table_name 的 database_name。
如上图所示,我们创建了COMPANY DEPARTMENT两个表。其中ID 作为主键,NOT NULL 的约束表示在表中创建纪录时这些字段不能为 NULL。
6.查看表的详细信息
.schema --注意:打开数据库时才能操作
7.删除表
DROP TABLE database_name.table_name;
如上,删除了名为DEPARTMENT的表
8.插入数据
INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)] VALUES (value1, value2, value3,...valueN);
在这里,column1, column2,...columnN 是要插入数据的表中的列的名称。
如果要为表中的所有列添加值,您也可以不需要在 SQLite 查询中指定列名称。但要确保值的顺序与列在表中的顺序一致。SQLite 的 INSERT INTO 语法如下:
INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);
现在,我已经创建了COMPANY表,如下
CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
现在,下面的语句将在 COMPANY 表中创建六个记录:
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 );
输出结果如下:
我们也可以使用第二种语法在COMPANY 表中创建一个记录,如下所示:
INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );
输出结果如下:
9.格式化输出
.header on .mode column .timer on --开启CPU定时器 SELECT * FROM table_name; --显示表table_name
非格式化输出
格式化输出
10.输出表
完整输出
.header on .mode column SELECT * FROM COMPANY;
输出指定列
.header on .mode column SELECT ID, NAME, SALARY FROM COMPANY; --只输出ID, NAME和SALARY三列
设置输出列的宽度
.width num1,num1,num3.... SELECT * FROM COMPANY;
下面 .width 命令设置第一列的宽度为 10,第二列的宽度为 20,第三列的宽度为 10。输出结果如下:
11.运算符
sqlite运算符主要用于 SQLite 语句的 WHERE 子句中执行操作,如比较和算术运算。
运算符用于指定 SQLite 语句中的条件,并在语句中连接多个条件。
算术运算符:
运算符 描述 实例 + 加法 - 把运算符两边的值相加 a + b 将得到 30 - 减法 - 左操作数减去右操作数 a - b 将得到 -10 * 乘法 - 把运算符两边的值相乘 a * b 将得到 200 / 除法 - 左操作数除以右操作数 b / a 将得到 2 % 取模 - 左操作数除以右操作数后得到的余数 b % a will give 0 比较运算符
运算符 描述 实例 == 检查两个操作数的值是否相等,如果相等则条件为真。 (a == b) 不为真。 = 检查两个操作数的值是否相等,如果相等则条件为真。 (a = b) 不为真。 != 检查两个操作数的值是否相等,如果不相等则条件为真。 (a != b) 为真。 <> 检查两个操作数的值是否相等,如果不相等则条件为真。 (a <> b) 为真。 > 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 (a > b) 不为真。 < 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 (a < b) 为真。 >= 检查左操作数的值是否大于等于右操作数的值,如果是则条件为真。 (a >= b) 不为真。 <= 检查左操作数的值是否小于等于右操作数的值,如果是则条件为真。 (a <= b) 为真。 !< 检查左操作数的值是否不小于右操作数的值,如果是则条件为真。 (a !< b) 为假。 !> 检查左操作数的值是否不大于右操作数的值,如果是则条件为真。 (a !> b) 为真。 逻辑运算符
运算符 描述 AND AND 运算符允许在一个 SQL 语句的 WHERE 子句中的多个条件的存在。 BETWEEN BETWEEN 运算符用于在给定最小值和最大值范围内的一系列值中搜索值。 EXISTS EXISTS 运算符用于在满足一定条件的指定表中搜索行的存在。 IN IN 运算符用于把某个值与一系列指定列表的值进行比较。 NOT IN IN 运算符的对立面,用于把某个值与不在一系列指定列表的值进行比较。 LIKE LIKE 运算符用于把某个值与使用通配符运算符的相似值进行比较。 GLOB GLOB 运算符用于把某个值与使用通配符运算符的相似值进行比较。GLOB 与 LIKE 不同之处在于,它是大小写敏感的。 NOT NOT 运算符是所用的逻辑运算符的对立面。比如 NOT EXISTS、NOT BETWEEN、NOT IN,等等。它是否定运算符。 OR OR 运算符用于结合一个 SQL 语句的 WHERE 子句中的多个条件。 IS NULL NULL 运算符用于把某个值与 NULL 值进行比较。 IS IS 运算符与 = 相似。 IS NOT IS NOT 运算符与 != 相似。 || 连接两个不同的字符串,得到一个新的字符串。 UNIQUE UNIQUE 运算符搜索指定表中的每一行,确保唯一性(无重复)。 位运算符
p q p & q p | q 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 下面直接上例子
我有COMPANY 表如下:
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
用 SELECT列出SALARY 大于 50,000.00 的所有记录:
SELECT * FROM COMPANY WHERE SALARY > 50000;
输出结果如下:
用 SELECT列出SALARY 等于的所有记录:
SELECT * FROM COMPANY WHERE SALARY = 20000;
输出结果如下:
用 SELECT列出AGE 大于等于 25 且SALARY大于等于 65000.00的所有记录:
SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000;
输出结果如下:
12.where子句
SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件。如果满足给定的条件,即为真(true)时,则从表中返回特定的值。您可以使用 WHERE 子句来过滤记录,只获取需要的记录。WHERE 子句不仅可用在 SELECT 语句中,它也可用在 UPDATE、DELETE 语句中,等等。用例参考运算符。
13.删除记录表中的数据
SQLite中,删除记录表数据为DELETE语句,我们可以使用带有 WHERE 子句的 DELETE。
语法如下:
DELETE FROM table_name WHERE [condition];
我们有以下记录表:
删除ID为7的列:
DELETE FROM COMPANY WHERE ID = 7;
再次输出结果:
14.update语句
SQLite 的 UPDATE 查询用于修改表中已有的记录。可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新。
语法:
UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];
注:这三行实为同一行。
现在我有数据表如下:
把COMPANY表中ID 为 6 的客户地址改为Texas:
UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;
修改结果:
如果您想修改 COMPANY 表中 ADDRESS 和 SALARY 列的所有值,则不需要使用 WHERE 子句,UPDATE 查询如下:
UPDATE COMPANY SET ADDRESS = 'Texas', SALARY = 20000.00;
修改结果:
二、C/C++操作
1.接口API
下面接口能满足我们的基本需求,需要学习更多的操作,我们可以参考官方文档。
序号 API & 描述 1 sqlite3_open(const char *filename, sqlite3 **ppDb) 该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。
如果 filename 参数是 NULL 或 ':memory:',那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。
如果文件名 filename 不为 NULL,那么 sqlite3_open() 将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。
2 sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg) 该例程提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。
在这里,第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。
sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。
3 sqlite3_close(sqlite3*) 该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。
如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。
2.连接数据库
下面的 C 代码段显示了如何连接到一个现有的数据库。如果数据库不存在,那么它就会被创建,最后将返回一个数据库对象。
#include <stdio.h> #include <sqlite3.h> int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully\n"); } sqlite3_close(db); }
编译命令
gcc lianjie.c -l sqlite3
运行结果
终端输入ls -l命令发现多了个test.db文件,如图:
3.创建表
C语言创建表与终端创建操作差不多,只不过命令由sqlite3_exec()函数的sql参数传入。格式如下:
sql = "CREATE TABLE COMPANY(" \ "ID INT PRIMARY KEY NOT NULL," \ "NAME TEXT NOT NULL," \ "AGE INT NOT NULL," \ "ADDRESS CHAR(50)," \ "SALARY REAL );";
示例代码:
#include <stdio.h> #include <stdlib.h> #include <sqlite3.h> static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; /* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stdout, "Opened database successfully\n"); } /* Create SQL statement */ sql = "CREATE TABLE COMPANY(" \ "ID INT PRIMARY KEY NOT NULL," \ "NAME TEXT NOT NULL," \ "AGE INT NOT NULL," \ "ADDRESS CHAR(50)," \ "SALARY REAL );"; /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Table created successfully\n"); } sqlite3_close(db); return 0; }
输出结果:
再次ls -l:
我们可以看到,test.db文件大小明显变大了。
4.插入数据
与创建表类似,sql参数设为:
sql = "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 );";
示例代码:
#include <stdio.h> #include <stdlib.h> #include <sqlite3.h> static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; /* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully\n"); } /* Create SQL statement */ sql = "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 );"; /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Records created successfully\n"); } sqlite3_close(db); return 0; }
输出结果:
5.查表操作
sqlite3_exec()给我们提供了一个回调函数,其声明如下:
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_callback()函数;没有,退出
用法讲完了,下面看例子:
#include <stdio.h> #include <stdlib.h> #include <sqlite3.h> static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; const char* data = "Callback function called"; /* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully\n"); } /* Create SQL statement */ sql = "SELECT * from COMPANY"; /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully\n"); } sqlite3_close(db); return 0; }
上面程序显示了如何从前面创建的 COMPANY 表中获取并显示记录,输出结果如下:
这里我没有特殊指明查询条件,表示查询全部。
6.数据删除操作
sql参数设置:
sql = "DELETE from COMPANY where ID=2; " \\删除ID等于2的行 "SELECT * from COMPANY"; \\显示表
这里跟上面不同的是多了一个命令,表面sql参数可由多个命令组成。
示例代码:
#include <stdio.h> #include <stdlib.h> #include <sqlite3.h> static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; const char* data = "Callback function called"; /* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully\n"); } /* Create merged SQL statement */ sql = "DELETE from COMPANY where ID=2; " \ "SELECT * from COMPANY"; /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully\n"); } sqlite3_close(db); return 0; }
输出:
7.UPDATE 操作
操作示例:
#include <stdio.h> #include <stdlib.h> #include <sqlite3.h> static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; const char* data = "Callback function called"; /* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully\n"); } /* Create merged SQL statement */ sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \ "SELECT * from COMPANY"; /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully\n"); } sqlite3_close(db); return 0; }
输出结果:
三:结语
现在,关于sqlite3的基本用法都讲完了,有不对的地方欢迎指出。
-
c++:MFC中sqlite3的使用(附实际案例)
2021-06-23 12:47:01MFC中sqlite3的使用sqlite3介绍sqlite3安装常用API函数操作流程接口函数执行sql语句函数回调函数MFC中案例实践控制台实践 sqlite3介绍 SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL ... -
SQLite3:对SQLite3加密
2021-06-18 14:58:24发现两款不错的开源加密工具:sqleet和SQLite3MultipleCiphers -
SQLite3下载与安装
2021-11-25 15:43:06一、SQLite概述: 1.简介:SQLite是一款开源的、嵌入式关系型数据库,它在便携性、易用性、紧凑型、高效性和可靠性有突出的表现。...2.体系结构:SQLite拥有简洁、模块化的体系结构,可以划分为3个子系统和8个独立 -
Sqlite3写性能优化-每秒百万条写入
2021-12-21 22:24:39sqlite3写入速度很慢?那一定是没有找到合适的方法,本文测试了几种方法并提供了测试源代码 -
【SQLite3+Qt开发】SQLite3简要介绍+在Qt5中的使用步骤
2022-04-02 00:29:58SQLite3简要介绍+在Qt5中使用步骤 -
sqlite3 API详解
2019-05-07 15:30:31int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); int sqlite3_bind_... -
sqlite表更新添加字段——sqlite3
2020-08-25 18:54:42sqlite_master结构 1.sql语句:SELECT * from sqlite_master where name = '表名' and sql like '%字段名%'//查询表中有无要...int sql_exec(sqlite3 *db, const char *sql) { int res; sqlite3_stmt *stmt = NULL -
sqlite3可视化工具
2017-01-11 11:35:19sqlite3可视化工具 -
Android中的sqlite3的安装和使用, /system/xbin/sqlite3[1]: syntax error: ‘(‘ unexpected问题解决,...
2022-03-18 11:36:59Android系统采用了sqlite3数据库,这是一个关系型数据库,而且是一个轻量级的,广泛应用于嵌入式系统中。 -
Qt下使用SQLite3
2012-06-21 09:47:49编译环境:QT4.5+qt-creator2.4+arm-linux-gcc 4.3.3 程序是通过在QT槽函数中调用SQLite3的API来实现对数据库中的数据操作,这里我们默认嵌入式Linux中已经移植类SQLite3,程序中将调用SQLite3的库文件。 -
VB 应用最新SQLite3.DLL动态库的方法
2012-08-29 17:41:56SQLite3.DLL动态库不支持VB工程引用,Olaf Schmmidt大侠基于SQLite3.DLL开发的vbRichClient.dll动态库,VB可以直接引用,但是不是最新的SQLite3.DLL,如果想用在VB中用最新版SQLite3.DLL,可以借鉴这个例子。 -
python+sqlite3-数据库增删改查操作
2021-12-12 00:48:34python+sqlite3-数据库增删改查操作 -
SQLite 命令行客户端 sqlite3 使用指南
2020-10-20 12:27:09本文介绍了 SQLite 命令行客户端 sqlite3 的下载安装以及使用方法,包括数据库的管理、模式对象的查看、sqlite3 的各种设置、脚本的执行和查询结果的导出、SQLite 归档功能、读写二进制文件、执行操作系统命令等。 -
SQLite3数据库
2021-04-08 08:08:53目录数据库系统数据库系统结构图数据库的基本概念SQLite3数据库简介创建SQLite数据库附加数据库AttachSQLite3点命令SQLite数据库逻辑对象SQL92标准SQLite不支持的特性SQLite数据类型 数据库系统 数据库系统结构图 ...