• [技术干货] Python操作Sqlite3
    Sqlite3 数据库介绍SQLite 是一个轻量级的数据库,它将整个数据库存储在一个磁盘文件中。SQLite 数据库具有以下特点:轻量级:SQLite 的数据库引擎只有一个动态链接库(libsqlite3),无需额外安装其他组件。高效性:SQLite 使用了高效的磁盘存储格式和索引技术,具有较好的性能。对于小规模的应用,SQLite 可以在内存中管理数据,进一步提高性能。跨平台:SQLite 支持多种操作系统,如 Windows、Linux、macOS 等,并且可以在不同的编程语言中使用。易于使用:SQLite 提供了简单的 API,方便开发者快速上手。数据库自给自足:SQLite 数据库包含了完整的 SQL 解析器、编译器和解释器,无需额外依赖其他数据库服务器。支持 SQL 标准:SQLite 支持大部分 SQL 92 标准,提供了丰富的 SQL 功能。开源免费:SQLite 是开源的,可以免费使用,适用于各种商业和非商业项目。。环境搭建SQLite 数据库是一个轻量级的数据库,它不需要额外安装。SQLite 数据库已经内置在许多操作系统和编程语言中,因此通常可以直接使用。 对于 Python 来说,你可以通过以下方式在命令行中检查 SQLite 是否已经内置:python -m sqlite3 如果输出 SQLite 版本信息,那么说明 Python 已经内置了 SQLite 数据库。然而,在某些情况下,你可能需要安装特定的 SQLite 版本或者相关工具。例如,在 Windows 上,你可以下载预编译的二进制文件并解压到指定目录,然后将该目录添加到系统环境变量中。在 Linux 和 macOS 上,你可以通过编译源代码来安装特定版本的 SQLite。注意:虽然 SQLite 数据库本身不需要安装,但你可能需要为特定编程语言的 SQLite 绑定(如 Python 的 sqlite3 模块)编写额外的代码或脚本。这些绑定库可能需要根据实际需求进行安装或配置。Python 操作Sqlite3 代码实战Python 操作 SQLite 数据库,可以使用内置的sqlite3模块。以下是一个简单的示例,展示了如何连接到 SQLite 数据库、创建表、插入数据和查询数据。首先,确保你已经安装了 SQLite 数据库。如果尚未安装,可以使用以下命令安装:pip install pysqlite3 接下来,看一个简单的 Python 代码示例:import sqlite3 # 连接到数据库(如果不存在,将创建一个名为 test.db 的文件) conn = sqlite3.connect('test.db') # 创建一个游标对象 cursor = conn.cursor() # 创建一个名为 users 的表 cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, age INTEGER NOT NULL ) ''') # 插入数据 cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30)) cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 25)) # 提交事务 conn.commit() # 查询数据 cursor.execute("SELECT * FROM users") rows = cursor.fetchall() # 打印查询结果 for row in rows: print(row) # 关闭游标和连接 cursor.close() conn.close() 这个示例首先连接到名为test.db的 SQLite 数据库(如果不存在,则创建一个)。然后创建一个名为users的表,包含id、name和age三个字段。接着插入两条数据,并查询所有数据并打印。运行上述代码,你将看到以下输出:(1, 'Alice', 30) (2, 'Bob', 25) 这表明数据已成功插入并从数据库中查询出来。注意:在实际应用中,为了确保数据安全和一致性,建议在使用完数据库后,始终关闭游标和连接。如本示例所示。
  • [技术干货] SQLite 3.43.0 发布,又有啥新功能?【转】
    SQLite 开发团队于 2023 年 08 月 24 日发布了 SQLite 3.43.0 版本。本文给大家分析一下该版本的更新。全文索引SQLite 3.43.0 增加了 Contentless-Delete FTS5 索引。这是一种 FTS5 全文索引的变种,不存储被索引的内容,同时支持数据的删除操作。例如:CREATE VIRTUAL TABLE f1 USING fts5(a, b, c, content='', contentless_delete=1);    1Contentless-delete 表与 Contentless 表的区别在于:    Contentless-delete 表支持 DELETE 以及 INSERT OR REPLACE INTO 语句;    Contentless-delete 表支持 UPDATE 语句,前提是所有用户定义的字段都指定了新的数据;    Contentless-delete 表不支持 FTS5 删除命令。例如:-- 支持以下 UPDATE 语句UPDATE f1 SET a=?, b=?, c=? WHERE rowid=?;-- 不支持以下 UPDATE 语句,因为字段 c 没有指定新的数据UPDATE f1 SET a=?, b=? WHERE rowid=?;    1    2    3    4    5除非存在旧版本的后向兼容需求,推荐使用 Contentless-delete 表。日期时间函数新版本增强了日期时间相关的函数。首先是增加了“±YYYY-MM-DD HH:MM:SS.SSS”形式的时间偏移量,例如:select date('2023-01-01', '+1000-01-01');3023-02-02    1    2其次,新版本增加了 timediff(A, B) 函数,计算从时间 B 到达时间 A 所需的时间。例如:select timediff('2023-06-01', '2023-01-01');+0000-05-00 00:00:00.000    1    2timediff() 函数返回的格式是字符串,方便阅读。如果想要返回精确的时间差(天数、秒数等),可以使用两个 julianday() 或 unixepoch() 函数相减。字符串函数SQLite 3.43.0 增加了一个 octet_length(X) 字符串函数,用于返回字符串 X 占用的字节数。例如:select octet_length('Hello');5select octet_length('你好');6    1    2    3    4    5octet_length(X) 以字节为单位,而不是字符为单位。因此,不同数据库字符集可能返回不同的长度。C 语言接口SQLite 3.43.0 新增了一个 sqlite3_stmt_explain(S,E) API,用于改变预编译语句的 EXPLAIN 设置。如果参数 E 设置为 0,S 就是一个普通的预编译语句;如果 E 设置为 1,S 就变成一个以 EXPLAIN 开始的 SQL 语句;如果E 设置为 2,S 就变成一个以 EXPLAIN QUERY PLAN 开始的 SQL 语句。查询优化查询优化器增强包括:    LEFT JOIN 强度削减优化扩展至 RIGHT JOIN 以及 FULL JOIN,并且重命名为 OUTER JOIN 强度消减优化。    改进了 OUTER JOIN 强度消减优化使用的理论证明器,减少了假阴性的情况。Decimal 扩展新版本增强了与 decimal 扩展相关的内容:    新增函数 decimal_pow2(N),返回 2.0 的 N 次方,N 为 -2000 到 +2000 之间的整数;    新增函数 decimal_exp(X),以科学计数法形式(e+NN)返回 X 的十进制数字;    对于浮点数 X,decimal(X) 函数将会返回完全扩展的精确数字。例如:select decimal_pow2(10);+1.024e+03select decimal_exp(12.3);+1.2300000000000000710542735760100185871124267578125e+01select decimal(12.3);12.300000000000000710542735760100185871124267578125    1    2    3    4    5    6    7    8JSON 性能某些情况下,对于大型 JSON 字符串的处理性能获得翻倍提升。————————————————版权声明:本文为CSDN博主「不剪发的Tony老师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/horses/article/details/132535127
  • [技术干货] SQLite3中的SQL基本语句和高级语句【转】
    一、SQL基本语句1. 创建表:至少需要包含一个表名和一个字段名,创建基本表:    CREATE TABLE stu  (id int, name text, score real);    基本表会在数据库中永久存在。创建临时表:CREATE TEMP TABLE stu  (id int, name text, score real);    临时表是暂时存活,一旦连接断开就会自动销毁。字段解析:stu:表名id/name/score:字段名int/text/real:类型SQLite有五种类型:integer、real、text、blob、null。创建表允许在字段后添加约束:CREATE TABLE stu  (id int primary key, name text, score real); 为字段id添加主键。2. 修改表:修改表的结构增加一个无初始值字段:alter table stu add column <字段名> <类型>;增加一个有初始值字段:alter table stu add column <字段名> <类型> default value;修改表名:alter table <tablename_old> rename to <tablename_new>3. 数据库查询:select是SQL中最大、最复杂的命令。最常见的select命令由 select、from、where组成:    select * from <table_name>;1.关系操作:大部分SQL实现中,select语句提供了混合、比较、过滤数据的“关系操作”。通常分为以下三类。    基本操作:限制、投影、笛卡儿积、联合、差、重命名。基本操作定义了基础的关系操作    附加操作:交叉、自然连接、赋值。附加操作提供了频繁操作的快速方式,由基本操作组成。    扩展操作:广义投影、左外连接、右外连接、全外连接。扩展操作对基本操作和附加操作的扩展。    所有这些操作都定义在关系中,也就是我们说的表。他们将一个或多个关系操作作为输入,然后产生另一个关系的输出。如:     select name from(select name, id from(select *from stu));    最里层的输出作为次里层的输入,次里层的输出作为最外层的输入。2.select命令与管道操作select命令用一系列子句将很多关系操作组合在一起,每个子句代表一种特定的关系操作。select [distinct] heading from tables where predicate group by columns having predicates order by columns limit count,offset;在这里插入图片描述3.过滤:where是一个过滤器值:真实的数字(1,2,3)或者字符串(“xxxxx”)。操作符:一个或多个值作为输入产生一个新值作为输出。二元操作符:算术操作符:+ - * / :输入数值产生一个数值关系操作符:< > = :比较值和值产生一个逻辑结果逻辑操作符:AND OR NOT IN:根据输入产生具体真假值 如:(x > 5)AND (y < 2)LIKE与GLOB操作符:用于匹配通配符指定模式的文本,匹配成功返回查找到的内容,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%';        1    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 '?23’ 查找第二位为2,且以3结尾的任意值    where salary glob ‘2???3’ 查找长度为5,且以2开头以3结尾的任意值。     例子:select * from company where age glob '2*';                14. 限定和排序:使用limit和offset关键字限定结果集的大小和范围。limit限定返回记录最大数,offset指定偏移量。例子:从id的第三位提取三个记录。desc降序 asc升序(默认)select *from company order by id limit 3 offset 2;    15. 函数和聚合:SQLite提过了很多函数和聚合,可用在不同的子句中,如:计算绝对值(abs()),字符串格式函数,字符串大小写转化(upper(),lower())。例子:select id, upper(name),length(name) from company where length(name)<5;    1聚合:是一类特殊的函数如:sum()、count()、avg()、min()、max()。例子:select count(*) from company;    16. 分组:group by:把集合分为多个组例子:select id count(*) from company group by id;    1约束:having 对group by起到了约束作用,having对每个组应用过滤,通过过滤的组传递给select子句做聚合和映射。having子句必须出现在group by 子句之后,order by之前。例子:select *from company group by name having count(age>20);    查找年纪大于20岁的记录    17.去重:distinct与select一起使用,消除重复记录,只获取唯一一次的记录。例子:select distinct name from company;    18.多表连接:连接(join)是多表数据工作的关键,它的输出作为其他子句的输入。一个表中字段的值与另一个表中字段值对应,这样就存在了关联。要实现连接,数据库需要找到匹配的行,对于第一个表的每一行,数据库都要查询第二个表的所有行,寻找那些连接字段具有相同值得行。然后将他们包含的输入关系中。    内连接:通过表中两个字段进行连接。内连接使用关系代数中一种集合操作-交叉。找出同时存在两个集合的相同元素。     例子:select * from foods inner join food_types on foods.id = food_types.id;        1    交叉连接:两个表之间没有任何联系,强制将他们连在一起,称为交叉连接或笛卡尔积。两个表之间行与行之间没有联系没有连接,只是简单组合在一起。    外连接:外连接选择内连接的所有行外加一些关系之外的行。外连接有三种:左外连接、右外连接、全外连接。    自然连接:通过表中共有的字段名称将两个表连接起来。自然连接会连接两个表中具有相同名称的字段。9.别名:如果表名很长的话可以简化对表重命名例子: 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;    1    210.子查询:子查询是指select语句中嵌套select语句。11.复合查询与子查询相反,它是使用三种特殊的关系操作符(联合、交叉连接和差集)处理多个查询结果。对应关键字:union、intersect和except。1.涉及的关系的字段数目必须相等。2. 只能有一个oder by 子句,并且在复合查询的末尾处,对联合结果进行排序。3.union子句:操作输入的两个关系:A和B,将A和B联合成只包含A和B中非重复字段的单一关系。如果想保留重复数据则使用union all。例子:SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID UNION SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;    14.except子句:找出在A但不在B的行。例子:SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID except SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;            112.NULL:未知的、不可知的特殊占位符,不是真、不是假、不是空、不是零。二、SQL高级语句1.修改数据:insert、update、delete。1.插入记录:insert:向表中插入数据: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 stu values(null, select id from stu2 where name='xxx'); //插入一组     insert into stu select * from stu2;    //将stu2 数据插入stu1中。     create table stu as select * from stu2;    //创建stu并插入stu2中数据。    1    2    3    4    52.更新记录:update:修改表中一行或者多行中一个字段或者多个字段的记录。当遇到unqiue约束时候,更新可能会失败。例子:update stu set id=4,score=99.9 where id=5;    13.删除记录:delete例子:delete from stu where id=4;     //按条件删除记录    delete from stu;  //删除表中所有记录    1    22.数据完整性用于定义和保护表内部和表之间的数据关系。有四种完整性:域完整性、实体完整性、引用完整性、用户自定义完整性。数据完整性是通过约束实现的。约束就是对字段存储值得一种限制,数据库对字段中存储值进行完整性约束强制实施。字段级约束包括:not null、unique、primary key、foreign key、check和collate。1.实体完整性:    主键:primary key:行必须在某种方式上是唯一的。主键必须由带有unique(唯一性)约束的一个或一组字段组成。unique约束是主键的基础。主键提供自增长功能。表默认会创建一个主键(64-bit类型)。    我们也可以自己创建主键,可以定义在多个字段,也不必要是int型。    unique:唯一性约束:保证一个或一组字段的所有值互不相同,如果视图插入一个重复值,将引发非法约束终止操作。2.域完整性:定义中的字段值必须是字段定义范围内的。由两部分组成:类型检查和范围检查。默认值、not null 和 check以及排序。    默认值:如果insert时候没有为该字段指定值,则关键字default为字段设定一个默认值。还接受3种预留定义格式的ANSI/ISO保留字,用于生成时间日期。     current_time: hh:mm:ss     current_date: yyyy-mm-dd     current_timestamp: yyyy-mm-dd hh:mm:ss        1        2        3    not null:该约束保证该字段不为null。如果给限制not null的字段insert或者update 为null则报错。一般与default一起使用,未赋值的时候使用默认值。    check:测试要插入或者更新的字段值,如果不满足则报错。     例子:create table stu (id integer primary key, name text not null, phone text not null default 'unknown', unique(name, phone),check(length(phone)>7));        1    外键:确保一个表中关键字从另一个表中引用,且数据在另一个表中实际存在。     例子:create table food (id integer primary key, type_id integer references food_types(id) on delete restrict deferrable initially deferred, name text);         delete restrict:阻止这样的删除,如果删除food_types表中id,那么food中id没有父id存在,则阻止删除事务。         deferrable:控制定义的约束立即强制实施还是延迟执行。        1        2        33.存储类SQLite有五个原始数据类型,integer(整数)、real(浮点数)、text(字符串)、blob(二进制)、null。在SQLite中不同存储类的值可以存储在同一个字段中。他们可以排序 null < integer/real < text < blob4.视图即虚拟表,也称派生表,因为他们的内容都是派生自其他表的查询结果。视图虽然看起来像基本表,但是他们不是,基本表是永久的,他们是动态产生的。视图是只读的,无法进行insert、update、delete。创建视图create view name as select id from stu;    name:视图名称    1删除视图:drop view name;    1查询视图:创建完视图之后就可以像查询表一样查询视图:select *from name;    15.索引一种用来在某种条件下加速查询的结构。SQLite使用B-tree做索引。索引会增加数据库的大小,索引可以加快查询速度,但是会降低insert、update、和delete的速度。基本语法:CREATE INDEX checkin_f_query on checkin_f;    checkin_f_query:索引名。checkin_f索引所在的表名。    1唯一索引:不允许重复的值插入表中。CREATE UNIQUE INDEX checkin_f_query on checkin_f (userid, check_in_time);    索引值是唯一的。    1单例索引:基于一个表上一个列的索引。CREATE INDEX checkin_f_query on checkin_f (userid);    1删除索引:DROP INDEX checkin_f_query;    16.触发器是数据库的回调函数,当具体表发生特定的数据库事件时,会执行对应的SQL语句。触发器是通过名称、行为、表定义的。行为由一系列SQL命令组成,当发生某些特定事件时触发器就会执行这些命令。可以通过关键字before和after来指定是在事发前执行还是事发后执行。事件包括具体在表中执行的delete、update、insert。例子:当 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错误处理:定义事件发生执行前可以使用触发器阻止事件,也可以在发生后使用触发器检查事件。SQL函数raise()函数供触发器使用,该函数允许在触发器内产生错误。函数定于:raise(resolution, err_msg);参数:resolution:冲突解决策略,replace、abort、fail、ignore、rollback     err_msg:错误消息7.事务事务定义了一组SQL命令的边界,这组命令或者作为一个整体被全部执行,或者都不执行。事务的范围:事务由三个命令控制:begin、commit、rollback。begin开始一个事务,begin之后的所有操作都可以被取消。commit提交事务开始后所执行的所有操作。rollback回滚begin之后的所有操作。冲突解决:既可以在SQL命令中指定也可以在表和索引中执行。处理约束违法的方法replace:当违反了唯一性约束时,SQL将违反的记录删除,以插入或者修改新的记录替代。当违反not null约束时就使用该字段的默认值来替代null,如果没有默认字段则使用abort的处理方式。ignore:当违反约束时选择忽视,SQL命令继续执行,违反约束的行保持不变,且不报错。fail:当违反约束时,SQLite终止命令,但是不恢复之前已经修改过的记录。abort:当违反约束时,SQLite恢复命令所做的所有改变并终止。是SQLite默认的解决办法。rollback:当违反约束时,执行回滚-终止当前命令和整个事务。当前命令所作的改变和事务中之前所作的改变都被回滚。例子:sqlite> begin;     sqlite> insert or replace into table (col_List) values (value_list);     sqlite> commit;数据库锁:SQLite采用粗粒度锁,当一个连接要写数据库时,所有其他的连接都被锁住,直到写连接结束它的事务。SQLite有一个加锁表,帮助不同的写数据库能够在最后一刻加锁,以保证最大的并发性。SQLite有五种不同的锁状态:未加锁、共享、预留、未决和排它。数据库在同一时刻只能有一种锁状态。    未加锁:最初的状态,连接却没有访问数据库或者已经begin一个事务时,都是未加锁状态。    共享锁:为了从数据库读数据,连接必现进入共享锁,多个连接可以同时获得并保持共享锁,多个连接可以同一时刻同时从一个数据库读数据。但是如果有共享锁没有释放就不可以写数据。    预留锁:如果想要写数据,必须获取一个预留锁,一个数据库只能有一个预留锁,预留锁可以与共享锁共存,他不会影响其他连接继续获取共享锁。一旦连接获取到预留锁就可以写数据库,但是只写到缓存中,并没有写到磁盘中。    排它锁:当一个连接写完数据想要提交时候,就需要从预留锁提升为排它锁。但是在这之前需要先提升为未决锁,获得未决锁之后其他连接就不可以继续获得共享锁,但是拥有共享锁的仍可以继续工作。此时拥有未决锁的连接等待其他获得共享锁的连接释放共享锁。当其他共享锁都释放完之后,未决锁提升为排它锁,此时就可以对数据库进行修改,然后保存到数据库文件。事务的类型:SQLite有三种不同的事务,他们以不同的锁状态启动事务。begin [deferred | immediate | exclusive] transaction;deferred:直到使用时候才获取锁immediate:在begin执行时候视图获取预留锁,成功则写数据库,失败则返回SQLITE_BUSY错误。exclusive:获取数据库的排它锁。成功就可以对数据库进行任意操作。8.数据库管理控制数据库如何操作附加数据库:SQLite允许使用attach命令将多个数据库附加到当前连接上。当附加上一个数据库时,他的所有内容在当前数据库文件的全局范围内都是可存取的。语法:attach database filename as database_name; filename:数据库文件名。database_name:引用数据库和对象的逻辑名称。数据库配置:SQLite没有配置文件,它所有配置文件都是用编译指示来实现的。连接缓冲区大小:缓存区尺寸大小的编译指示控制一个连接可以在内存中使用多少个数据库页。缓冲区越大,连接在获取排它锁之前所做的事就越多。查看缓冲区大小:pragma cache_size;  设置缓冲区大小:pragma cache_size=10000;   获取数据库信息:pragma database_list;    //列出所有附着的数据库pragma index_info;        //列出索引内字段的相关信息pragma index_list;        //列出表中索引信息pragma table_info;        //列出表中所有字段信息写同步:SQLite会在关键时候将所有的变化提交到磁盘以确保事务的持久性。可以通过synchronous编译指示来实现。该编译指示有三种:    full:在关键的暂停以确保所有数据都写入磁盘,最安全但是比较慢。    normal:会在绝大多数关键点暂停,没有full频繁。    off:将数据抛给操作系统后继续执行,一旦断电或者崩溃数据库将无法保存到数据。————————————————版权声明:本文为CSDN博主「青湦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_34934140/article/details/121539905
  • [数据库类] 鸿蒙系统2.0 不支持sqlite中的over() 函数吗
    我发现同样的程序,同样的sql,在小米等android设备上是可以执行的,但是在鸿蒙2.0上却执行失败,譬如select count() over(),在鸿蒙上就执行失败了,而select count()成功了,难道鸿蒙不支持over()函数的实现?
  • [安装] 问题求助_windows源码编译,sqlite编译报错
    cmake小白,windows 编译mindspore master(r1.7),出现上图报错,参考其它帖子设置过FROM_GITEE,问题依旧。
  • [技术干货] SQLite 实现if not exist 类似功能的操作
    需要实现:12345if not exists(select * from ErrorConfig where Type='RetryWaitSeconds')begin  insert into ErrorConfig(Type,Value1)  values('RetryWaitSeconds','3')end只能用:123insert into ErrorConfig(Type,Value1)select 'RetryWaitSeconds','3'where not exists(select * from ErrorConfig where Type='RetryWaitSeconds')因为 SQLite 中不支持SP补充:sqlite3中NOT IN 不好用的问题在用sqlite3熟悉SQL的时候遇到了一个百思不得其解的问题,也没有在google上找到答案。虽然最后用“迂回”的方式碰巧解决了这个问题,但暂时不清楚原理是什么,目前精力有限,所以暂时记录下来,有待继续研究。数据库是这样的:1234567891011121314151617181920212223CREATE TABLE book ( id integer primary key, title text, unique(title));CREATE TABLE checkout_item ( member_id integer, book_id integer, movie_id integer, unique(member_id, book_id, movie_id) on conflict replace, unique(book_id), unique(movie_id));CREATE TABLE member ( id integer primary key, name text, unique(name));CREATE TABLE movie ( id integer primary key, title text, unique(title));该数据库包含了4个表:book, movie, member, checkout_item。其中,checkout_item用于保存member对book和movie的借阅记录,属于关系表。问一:哪些member还没有借阅记录?SQL语句(SQL1)如下:1SELECT * FROM member WHERE id NOT IN(SELECT member_id FROM checkout_item);得到了想要的结果。问二:哪些book没有被借出?这看起来与上一个是类似的,于是我理所当然地运行了如下的SQL语句(SQL2):1SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item);可是——运行结果没有找到任何记录! 我看不出SQL2与SQL1这两条语句有什么差别,难道是book表的问题?于是把NOT去掉,运行了如下查询语句:1SELECT * FROM book WHERE id IN(SELECT book_id FROM checkout_item);正确返回了被借出的book,其数量小于book表里的总行数,也就是说确实是有book没有借出的。接着google(此处省略没有营养的字),没找到解决方案。可是,为什么member可以,book就不可以呢?它们之前有什么不同?仔细观察,发现checkout_item里的book_id和movie_id都加了一个unique,而member_id则没有。也许是这个原因?不用id了,换title试试:1234SELECT * FROM book WHERE title NOT IN(  SELECT title FROM book WHERE id IN( SELECT book_id FROM checkout_item));确实很迂回,但至少work了。。。问题原因:当NOT碰上NULL事实是,我自己的解决方案只不过是碰巧work,这个问题产生跟unique没有关系。邱俊涛的解释是,“SELECT book_id FROM checkout_item”的结果中含有null值,导致NOT也返回null。当一个member只借了movie而没有借book时,产生的checkout_item中book_id就是空的。解决方案是,在选择checkout_item里的book_id时,把值为null的book_id去掉:1SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item WHERE book_id IS NOT NULL);总结我在解决这个问题的时候方向是不对的,应该像调试程序一样,去检查中间结果。比如,运行如下语句,结果会包含空行:1SELECT book_id FROM checkout_item而运行下列语句,结果不会包含空行:1SELECT member_id FROM checkout_item这才是SQL1与SQL2两条语句执行过程中的差别。根据这个差别去google,更容易找到答案。当然了,没有NULL概念也是我“百思不得其解”的原因。转载自https://www.jb51.net/article/203321.htm
  • [技术干货] 自定义扩展插件——数据库sqlite3相关控件
        1. SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎;    2. 整个数据库存储在一个单个的文件中,数据导入导出备份恢复都是复制文件,维护难度为零;    3. 读取速度快。    4. 最简单的理解是,对比其他数据库,最大区别在于在使用前不需要配置,直接使用即可。    插件导入Studio后,见下图所示,共有4个控件,连接、关闭、执行查询和执行。“执行查询sql语句”控件和“执行sql语句”控件区别在于后者可执行多条语句,可以是增删改查,但没有返回值,需要返回查询的结果则需要使用前者。(1)使用教程见附件“dbsqlite3教程_前部分.mp4”,“dbsqlite3教程_后部分.mp4”;(2)教程中样例见“Template.zip”中“Sqlite3_Template.zip”;(3)sqlite3与excel交互场景可见“Template.zip”中“Sqlite3_Excel_Template.zip”;(4)Sqlite3插件见“ext_dbsqlite3_1_0_0.zip”;(5)Sqlite可视化工具见“DB.Browser.for.SQLite-3.11.0-beta3-win64.zip”,适用于win10/64位,其他系统可在百度自行下载。
  • [技术干货] SQLite 数据类型
    SQLite 数据类型是一个用来指定任何对象的数据类型的属性。SQLite 中的每一列,每个变量和表达式都有相关的数据类型。您可以在创建表的同时使用这些数据类型。SQLite 使用一个更普遍的动态类型系统。在 SQLite 中,值的数据类型与值本身是相关的,而不是与它的容器相关。SQLite 存储类每个存储在 SQLite 数据库中的值都具有以下存储类之一:存储类描述NULL值是一个 NULL 值。INTEGER值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。REAL值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。TEXT值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。BLOB值是一个 blob 数据,完全根据它的输入存储。SQLite 的存储类稍微比数据类型更普遍。INTEGER 存储类,例如,包含 6 种不同的不同长度的整数数据类型。SQLite Affinity 类型SQLite 支持列上的类型 affinity 概念。任何列仍然可以存储任何类型的数据,但列的首选存储类是它的 affinity。在 SQLite3 数据库中,每个表的列分配为以下类型的 affinity 之一:Affinity描述TEXT该列使用存储类 NULL、TEXT 或 BLOB 存储所有数据。NUMERIC该列可以包含使用所有五个存储类的值。INTEGER与带有 NUMERIC affinity 的列相同,在 CAST 表达式中带有异常。REAL与带有 NUMERIC affinity 的列相似,不同的是,它会强制把整数值转换为浮点表示。NONE带有 affinity NONE 的列,不会优先使用哪个存储类,也不会尝试把数据从一个存储类强制转换为另一个存储类。SQLite Affinity 及类型名称下表列出了当创建 SQLite3 表时可使用的各种数据类型名称,同时也显示了相应的应用 Affinity:数据类型AffinityINTINTEGERTINYINTSMALLINTMEDIUMINTBIGINTUNSIGNED BIG INTINT2INT8INTEGERCHARACTER(20)VARCHAR(255)VARYING CHARACTER(255)NCHAR(55)NATIVE CHARACTER(70)NVARCHAR(100)TEXTCLOBTEXTBLOBno datatype specifiedNONEREALDOUBLEDOUBLE PRECISIONFLOATREALNUMERICDECIMAL(10,5)BOOLEANDATEDATETIMENUMERICBoolean 数据类型SQLite 没有单独的 Boolean 存储类。相反,布尔值被存储为整数 0(false)和 1(true)。Date 与 Time 数据类型SQLite 没有一个单独的用于存储日期和/或时间的存储类,但 SQLite 能够把日期和时间存储为 TEXT、REAL 或 INTEGER 值。存储类    日期格式TEXT格式为 "YYYY-MM-DD HH:MM:SS.SSS" 的日期。REAL从公元前 4714 年 11 月 24 日格林尼治时间的正午开始算起的天数INTEGER从 1970-01-01 00:00:00 UTC 算起的秒数。您可以以任何上述格式来存储日期和时间,并且可以使用内置的日期和时间函数来自由转换不同格式。参考文章:http://www.manongjc.com/sqlite/sqlite_data_types.html
  • [技术干货] 报“ModuleNotFoundError:No module named ‘_sqlite3’”错误解决方法
    【问题描述】报“ModuleNotFoundError:No module named ‘_sqlite3’”错误,详细如下:【解决方法】1)、获取sqlite-autoconf-3240000.tar.gz并上传到系统/home/路径https://www.sqlite.org/2018/sqlite-autoconf-3240000.tar.gz2)解压sqlite-autoconf-3240000.tar.gz并进入sqlite-autoconf-3240000/路径cd /home/tar -xvzf sqlite-autoconf-3240000.tar.gzcd sqlite-autoconf-3240000/3)编译安装./configure --prefix=/usr/local/sqlitemake -j48 && make install -j484)重新进入python3安装目录并修改setup.py文件cd ../Python-3.7.0/vi setup.py查找" sqlite_inc_paths" 新增如下内容'/usr/local/sqlite/include','/usr/local/sqlite/include/sqlite3',5)重新编译Python-3.7.0./configure --enable-loadable-sqlite-extensionsmake -j48 && make install -j48
  • [技术干货] SQLite数据库
    Android SQLite,是一款轻量级的关系型数据库。在很多嵌入式设备都用来存储数据。SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够了,因而特别适合在移动设备上使用。(内存小就是王道)SQLite数据类型存储类描述NULL值是一个 NULL 值。INTEGER值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。REAL值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。TEXT值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。BLOB值是一个 blob 数据,完全根据它的输入存储。SQLiteDatabase的介绍Android提供了创建和是用SQLite数据库的API。SQLiteDatabase代表一个数据库对象,提供了操作数据库的一些方法。在Android的SDK目录下有sqlite3工具,我们可以利用它创建数据库、创建表和执行一些SQL语句。下面是SQLiteDatabase的常用方法。方法描述openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)打开或创建数据库insert(String table,String nullColumnHack,ContentValues values)插入一条记录delete(String table,String whereClause,String[] whereArgs)删除一条记录query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)查询一条记录update(String table,ContentValues values,String whereClause,String[] whereArgs)修改记录execSQL(String sql)执行一条SQL语句close()关闭数据库打开或创建数据库在Android 中使用SQLiteDatabase的静态方法openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)打开或者创建一个数据库。它会自动去检测是否存在这个数据库,如果存在则打开,不存在则创建一个数据库;创建成功则返回一个SQLiteDatabase对象,否则抛出异常FileNotFoundException。下面是创建名为“stu.db”数据库的代码:openOrCreateDatabase(String path,SQLiteDatabae.CursorFactory factory)参数1 数据库创建的路径参数2 一般设置为null就可以了db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.lingdududu.db/databases/stu.db",null);创建表创建了一张用户表,属性列为:id(主键并且自动增加)、sname(学生姓名)、snumber(学号)private void createTable(SQLiteDatabase db) { // 创建表SQL语句 String stu_table="CREATE TABLE IF NOT EXISTS usertable(_id integer primary key autoincrement,sname text,snumber text)"; // 执行SQL语句 db.execSQL(stu_table); }参考文章:https://tiimor.cn/Android%E9%BB%84%E9%87%91%E7%AF%87-SQLite%E6%95%B0%E6%8D%AE%E5%BA%93/(非常不错一篇文章满满的细节,建议细细品)
  • [技术干货] sqlite嵌入式数据库的移植和使用
    sQlite是D. Richard Hipp 用C语言编写的开源嵌入式数据库引擎。它是完全独立的,没有外部依赖性。占用资源非常低,在嵌人式设备中,只需要几百KB的内存。它能够支持Windows, Limux等主流操作系统,可与Tel, PHP和Java等程序语言结合,提供ODBC接口,其处理速度甚至令开源世界著名的数据库管理系统MysQL和PostgreSQL.望尘莫及。solie对50192标准的支持包括索引、限制、触发和查看,支持原子的、一致的、独立的和持久(ACID)的事务。在内部, SoLite由SQL编译器、内核、后端以及附件几个组件组成。 sqlite通过利用虚拟机和虚拟数据库引擎(VDBE) ,使调试、修改和扩展SQLite的内核变得更加方便。所有sql,语句都被编译成易读的,可以在SQLite虚拟机中执行的程序集。现在项目需要使用SOLite数据库,需要将SQLite移植到ARM 2440嵌人式主机中,并续写一个简单的测试程序。现在项目需要使用sqlite数据库  需要将sqlite移植到arm2440嵌入式主机中并编写一个简单的测试程序项目实施步骤:1)下载并编译sqlite2)下载到arm虚拟机并使用sqlite如何下载编译sqlite从http://www.sqlite.org/download.html下载sqlite文件 当前版本是:3.9.2 文件名为:sqlite-autoconf-3090200.tar.gz解压并查看当前目录及install文件# tar zsf sqlite -autoconf-309200.tar,gz#lsaclocal.m4 configure.ac #itmain.sh #Readme#sqlite3ext.hconfig guess depcomp  make file.am  shell.c sqlite3.hconfig.sub  install  makefile.in sqlite 3.1 sqlite 3.pc inconfigure install-sh missing sqlite3.c tea创建一个目录build进入主目录在这个目录中将进行交叉编译在build目录中运行sqlite-autoconf-309200中的configure脚本 生成makefile文件 代码如下:../configure--host=ARM-LINUX -- PREFIX =/opt/sqlite-autoconf-309200/build 选项host指定的是用arm交叉编译器进行编译 选项prefix后面的鲤鱼精是编译安装后目标存放的目录可以任意设置#mkdir build  #cd mkdir #../configure --houst=arm-linux--prefix=/opt/sqlite-autoconf-309200/build#ls#config.log config.log config.status libtool makefile sqlite3.pc#make #makeinstall#lsbin  include  libtool  sqlite3  sqlite3.pcconfig.log  lib   makefile  sqlite3.lo  sqkite3-shell.oconfig.status  libsqlite3.la share  sqlite3.o sqlite3-sqlite3.o编译和安装完成后 在/root/sqlite-autoconf-309200/bulid 目录中会生成3个目标文件夹  分别是bin  include和lib下载到arm虚拟机并使用sqlite 分别将bin下的文件下载到开发板的/user/bin目录中去 lib下的所有文件下载到开发板的/lib目录中即可nclude目录下是sqlite的c语言api的头文件编译时会用到下面示例在arm虚拟机中测试 将root/sqlite-autoconf-309200/build目录中的bin和lib分别复制到/opt/root_qtopia/usr/bin与root_qyopia/lib/目录中#cd /opt/sqlite-autoconf-309200/build#cd bin#cp *.*/opt/root_qtopia/usr/bin#cd..#cd lib#cp *.*/opt/root_qtopia/lib/启动虚拟机 在arm虚拟机终端中运行 sqlite3 tst.db测试运行是否正常#sqlite3 tst.db sqlite version.................sql使用命令行管理数据库 在运行.help会列出常用的命令说明 这里我就不打出来了  也可以在官网中 去查看作者:仙女本仙
  • [技术干货] SQLite 错误码整理
    #define SQLITE_OK 0 /* 成功 | Successful result */ /* 错误码开始 */ #define SQLITE_ERROR 1 /* SQL错误 或 丢失数据库 | SQL error or missing database */ #define SQLITE_INTERNAL 2 /* SQLite 内部逻辑错误 | Internal logic error in SQLite */ #define SQLITE_PERM 3 /* 拒绝访问 | Access permission denied */ #define SQLITE_ABORT 4 /* 回调函数请求取消操作 | Callback routine requested an abort */ #define SQLITE_BUSY 5 /* 数据库文件被锁定 | The database file is locked */ #define SQLITE_LOCKED 6 /* 数据库中的一个表被锁定 | A table in the database is locked */ #define SQLITE_NOMEM 7 /* 某次 malloc() 函数调用失败 | A malloc() failed */ #define SQLITE_READONLY 8 /* 尝试写入一个只读数据库 | Attempt to write a readonly database */ #define SQLITE_INTERRUPT 9 /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */ #define SQLITE_IOERR 10 /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* 数据库磁盘映像不正确 | The database disk image is malformed */ #define SQLITE_NOTFOUND 12 /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */ #define SQLITE_FULL 13 /* 因为数据库满导致插入失败 | Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* 无法打开数据库文件 | Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* 数据库锁定协议错误 | Database lock protocol error */ #define SQLITE_EMPTY 16 /* 数据库为空 | Database is empty */ #define SQLITE_SCHEMA 17 /* 数据结构发生改变 | The database schema changed */ #define SQLITE_TOOBIG 18 /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* 由于约束违例而取消 | Abort due to constraint violation */ #define SQLITE_MISMATCH 20 /* 数据类型不匹配 | Data type mismatch */ #define SQLITE_MISUSE 21 /* 不正确的库使用 | Library used incorrectly */ #define SQLITE_NOLFS 22 /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* 授权失败 | Authorization denied */ #define SQLITE_FORMAT 24 /* 附加数据库格式错误 | Auxiliary database format error */ #define SQLITE_RANGE 25 /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */ #define SQLITE_NOTADB 26 /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */ #define SQLITE_ROW 100 /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing */ /* 错误码结束 */
  • [技术干货] SQLite速度评测代码
    SQLite 效率太低,批量插入1000条记录,居然耗时 2 分钟!下面是他发给我的测试代码。using System.Data;using System.Data.Common;using System.Data.SQLite;// 创建数据库文件File.Delete("test1.db3");SQLiteConnection.CreateFile("test1.db3");DbProviderFactory factory = SQLiteFactory.Instance;using (DbConnection conn = factory.CreateConnection()){// 连接数据库conn.ConnectionString = "Data Source=test1.db3";conn.Open();// 创建数据表string sql = "create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";DbCommand cmd = conn.CreateCommand();cmd.Connection = conn;cmd.CommandText = sql;cmd.ExecuteNonQuery();// 添加参数cmd.Parameters.Add(cmd.CreateParameter());// 开始计时Stopwatch watch = new Stopwatch();watch.Start();// 连续插入1000条记录for (int i = 0; i < 1000; i++){cmd.CommandText = "insert into [test1] ([s]) values (?)";cmd.Parameters[0].Value = i.ToString();cmd.ExecuteNonQuery();}// 停止计时watch.Stop();Console.WriteLine(watch.Elapsed);}哎~~~~ 一个常识性的错误,我加几行代码 (新增代码标记 "// <-------------------")。using System.Data;using System.Data.Common;using System.Data.SQLite;// 创建数据库文件File.Delete("test1.db3");SQLiteConnection.CreateFile("test1.db3");DbProviderFactory factory = SQLiteFactory.Instance;using (DbConnection conn = factory.CreateConnection()){// 连接数据库conn.ConnectionString = "Data Source=test1.db3";conn.Open();// 创建数据表string sql = "create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";DbCommand cmd = conn.CreateCommand();cmd.Connection = conn;cmd.CommandText = sql;cmd.ExecuteNonQuery();// 添加参数cmd.Parameters.Add(cmd.CreateParameter());// 开始计时Stopwatch watch = new Stopwatch();watch.Start();DbTransaction trans = conn.BeginTransaction(); // <-------------------try{// 连续插入1000条记录for (int i = 0; i < 1000; i++){cmd.CommandText = "insert into [test1] ([s]) values (?)";cmd.Parameters[0].Value = i.ToString();cmd.ExecuteNonQuery();}trans.Commit(); // <-------------------}catch{trans.Rollback(); // <-------------------throw; // <-------------------}// 停止计时watch.Stop();Console.WriteLine(watch.Elapsed);}执行一下,耗时 0.2 秒。这差距是不是太大了点?为什么只是简单启用了一个事务会有这么大的差距呢?很简单,SQLite 缺省为每个操作启动一个事务,那么原代码 1000 次插入起码开启了 1000 个事务,"事务开启 + SQL 执行 + 事务关闭" 自然耗费了大量的时间,这也是后面显示启动事务后为什么如此快的原因。
  • [技术干货] 使用Python对SQLite数据库操作
    QLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在IOS和Android的APP中都可以集成。Python内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表是数据库中存放关系数据的集合,一个数据库里面通常都包含多个表,比如学生的表,班级的表,学校的表,等等。表和表之间通过外键关联。要操作关系数据库,首先要连接到数据库,一个数据库连接称为Connection。连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果。一、连接数据库import sqlite3 #数据库名 db_name = "test.db" #表名 table_name = "catalog" conn = sqlite3.connect(db_name)二、打开游标rs = conn.cursor()三、建表sql = 'create table ' + table_name + ' (id varchar(20) primary key, pid integer, name varchar(10))' try: rs.execute(sql) print("建表成功") except: print("建表失败")四、增,删,改,查操作# 增:增加三条记录 sql = "Insert into " + table_name + " values ('001', 1, '张三')" try: rs.execute(sql) #提交事务 conn.commit() print("插入成功") except: print("插入失败") sql = "Insert into " + table_name + " values ('002', 2, '李四')" try: rs.execute(sql) #提交事务 conn.commit() print("插入成功") except: print("插入失败") sql = "Insert into " + table_name + " values ('003', 3, '王五')" try: rs.execute(sql) #提交事务 conn.commit() print("插入成功") except: print("插入失败") # 删:删除pid等于3的记录 sql = "Delete from " + table_name + " where pid = 3" try: rs.execute(sql) conn.commit() print("删除成功") except: print("删除失败") # 改:将pid等于2的记录的pid改为1 sql = "Update " + table_name + " set pid = 1 where pid = 2" try: rs.execute(sql) conn.commit() print("修改成功") except: print("修改失败") # 查 # 查询数据库中所有表名 sql = "Select name From sqlite_master where type = 'table'" res = rs.execute(sql) print(res.fetchall()) # 查询表中所有记录 sql = "Select * from " + table_name try: res = rs.execute(sql) print(res.fetchall()) except: print([])五、关闭游标rs.close()六、关闭数据库连接conn.close()
  • [技术干货] python 连接sqlite及简单操作
    直接给大家贴代码了,具体代码如下所示:import sqlite3 #查询 def load(table): #连接数据库 con = sqlite3.connect("E:/Datebase/SQLiteStudio/Park.db") #获得游标 cur = con.cursor() #查询整个表 cur.execute('select *from '+table) lists = ['name','password'] if table == 'login': #将数据库列名存入字典 colnames = {desc[0] for desc in cur.description} 将字典和数据库的数据一起存入列表,获得了记录字典 rowdicts = [dict(zip(lists, row)) for row in cur.fetchall()] else: rowdicts = [] for row in cur: rowdicts.append(row) con.commit() cur.close() return rowdicts #插入数据 def insert_data(ID,name,money): con = sqlite3.connect("E:/Datebase/SQLiteStudio/Park.db") cur = con.cursor() #使用SQL语句插入 cur.execute('insert into Charge values (?,?,?)', (ID,name, money)) #插入后进行整表查询,看是否成功插入 cur.execute('select *from Charge') print(cur.fetchall()) con.commit() cur.close()
总条数:35 到第
上滑加载中