基于 SQLite 3 的 C/C++ 学习:2-高级操作与有关函数

背景

基于 SQLite 3 的 C/C++ 学习:开发流程 与 基本函数 中,我们简单介绍了有关 SQLite3 函数的使用。

这一讲我们更加深入地介绍一些更加高级的操作。

附加数据库(ATTACH)/分离数据库(DETACH)

在实际的开发中,我们可以给数据库起别名。

数据库名称 main 和 temp 被保留用于主数据库和存储临时表及其他临时数据对象的数据库。无法被附加或分离。

# 附加
ATTACH DATABASE 'file_name' AS 'database_name'; # 分离
DETACH DATABASE 'Alias-Name';

例程:

$ ./sqlite3 example.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints. sqlite> .database
main: /home/schips/sqlite/example.db ## 起别名
sqlite> ATTACH DATABASE 'example.db' as exp; sqlite> .database
main: /home/schips/sqlite/example.db
exp: /home/schips/sqlite/example.db ## 取消别名
sqlite> DETACH DATABASE exp; sqlite> .database
main: /home/schips/sqlite/example.db

创建/删除表

创建表

CREATE TABLE 语句用于在任何给定的数据库创建一个新表。创建基本表,涉及到命名表、定义列及每一列的数据类型。

CREATE TABLE table_name(
column1 datatype PRIMARY KEY(one or more columns),
column2 datatype,
column3 datatype,
.....
columnN datatype,
);

约束

约束是在表的数据列上强制执行的规则。这些是用来限制可以插入到表中的数据类型。这确保了数据库中数据的准确性和可靠性。

约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。

以下是在 SQLite 中常用的约束。

  • 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
);
  • DEFAULT 约束:当某列没有指定值时,为该列提供默认值。
CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL DEFAULT 50000.00
);
  • UNIQUE 约束:确保某列中的所有值是不同的。
CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL UNIQUE,
ADDRESS CHAR(50),
SALARY REAL DEFAULT 50000.00
);
  • PRIMARY Key 约束:唯一标识数据库表中的各行/记录。

PRIMARY KEY 约束唯一标识数据库表中的每个记录。在一个表中可以有多个 UNIQUE 列,但只能有一个主键。在设计数据库表时,主键是很重要的。主键是唯一的 ID。

我们使用主键来引用表中的行。可通过把主键设置为其他表的外键,来创建表之间的关系。由于"长期存在编码监督",在 SQLite 中,主键可以是 NULL,这是与其他数据库不同的地方。

主键是表中的一个字段,唯一标识数据库表中的各行/记录。主键必须包含唯一值。主键列不能有 NULL 值。

一个表只能有一个主键,它可以由一个或多个字段组成。当多个字段作为主键,它们被称为复合键

如果一个表在任何字段上定义了一个主键,那么在这些字段上不能有两个记录具有相同的值。

  • CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。

CHECK 约束启用输入一条记录要检查值的条件。如果条件值为 false,则记录违反了约束,且不能输入到表。

CREATE TABLE COMPANY3(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL CHECK(SALARY > 0)
);

删除表

DROP TABLE 语句用来删除表定义及其所有相关数据、索引、触发器、约束和该表的权限规范。

使用此命令时要特别注意,因为一旦一个表被删除,表中所有信息也将永远丢失。

DROP TABLE 语句的基本语法如下。您可以选择指定带有表名的数据库名称,如下所示:

DROP TABLE database_name.table_name;

查询(select)/新建(insert)/更新(update)/删除(delete) 语句

SELECT 语句

用于从 SQLite 数据库表中获取数据,以结果表的形式返回数据。这些结果表也被称为结果集。

SELECT column1, column2, columnN FROM table_name;

Distinct 关键字

SQLite 的 DISTINCT 关键字与 SELECT 语句一起使用,来消除所有重复的记录,并只获取唯一一次记录。

有可能出现一种情况,在一个表中有多个重复的记录。当提取这样的记录时,DISTINCT 关键字就显得特别有意义,它只获取唯一一次记录,而不是获取重复记录。

INSERT INTO 语句

用于向数据库的某个表中添加新的数据行。

INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]
VALUES (value1, value2, value3,...valueN);

UPDATE

查询用于修改表中已有的记录。可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新。

UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];

DELETE

查询用于删除表中已有的记录。可以使用带有 WHERE 子句的 DELETE 查询来删除选定行,否则所有的记录都会被删除。

DELETE FROM table_name
WHERE [condition];

表达式与 运算符

运算符

一个保留字或字符,主要用于 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 运算符搜索指定表中的每一行,确保唯一性(无重复)。
  • 位运算符
运算符 描述 实例
& 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 (A & B) 将得到 12,即为 0000 1100
| 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 (A | B) 将得到 61,即为 0011 1101
~ 二进制补码运算符是一元运算符,具有"翻转"位效应,即0变成1,1变成0。 (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。
<< 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 A << 2 将得到 240,即为 1111 0000
>> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 A >> 2 将得到 15,即为 0000 1111

sqlite> .tables
table1
sqlite> SELECT * FROM table1;
#id text
100|update
101|update
102|update
103|update
104|update
105|text
211|schips sqlite> SELECT * FROM table1 WHERE id > 103;
104|update
105|text
211|schips sqlite>

表达式

一个或多个值、运算符和计算值的SQL函数的组合。SQL 表达式与公式类似,都写在查询语言中。您还可以使用特定的数据集来查询数据库。

  • 布尔表达式:SQLite 的布尔表达式在匹配单个值的基础上获取数据。语法如下:
SELECT column1, column2, columnN
FROM table_name
WHERE SINGLE VALUE MATCHING EXPRESSION;

例如:

sqlite> SELECT * FROM table1 WHERE id > 103;
104|update
105|text
211|schips
  • 数值表达式:这些表达式用来执行查询中的任何数学运算。语法如下:
SELECT numerical_expression as  OPERATION_NAME
[FROM table_name WHERE CONDITION] ;

有几个内置的函数,比如 avg()、sum()、count(),等等,执行被称为对一个表或一个特定的表列的汇总数据计算。

例如:

sqlite> SELECT (15 + 6) AS ADDITION
ADDITION = 21 sqlite> SELECT COUNT(*) AS "RECORDS" FROM table1;
RECORDS = 7
  • 日期表达式:日期表达式返回当前系统日期和时间值,这些表达式将被用于各种数据操作。
sqlite>  SELECT CURRENT_TIMESTAMP;
2020-03-26 01:34:15

Where 子句

子句:无法单独成SQL的句子成分,需要搭配语句进行使用

SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件。

如果满足给定的条件,即为真(true)时,则从表中返回特定的值。您可以使用 WHERE 子句来过滤记录,只获取需要的记录。

WHERE 子句不仅可用在 SELECT 语句中,它也可用在 UPDATE、DELETE 语句中。

Like 子句

LIKE 运算符是用来匹配通配符指定模式的文本值。如果搜索表达式与模式表达式匹配,LIKE 运算符将返回真(true),也就是 1。这些符号可以被组合使用。这里有两个通配符与 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 结尾的任意值
sqlite> SELECT * FROM table1;;
100|update
101|update
102|update
103|update
104|update
105|text
211|schips sqlite> SELECT * FROM table1 WHERE id LIKE '1%';
100|update
101|update
102|update
103|update
104|update
105|text

Glob 子句

GLOB 运算符是用来匹配通配符指定模式的文本值。如果搜索表达式与模式表达式匹配,GLOB 运算符将返回真(true),也就是 1。与 LIKE 运算符不同的是,GLOB 是大小写敏感的,对于下面的通配符,它遵循 UNIX 的语法。这些符号可以被组合使用。

  • 星号 (*):代表零个、一个或多个数字或字符。
  • 问号 (?):代表一个单一的数字或字符。

我们看看一些例子:

语句 描述
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 结尾的任意值
sqlite> SELECT * FROM table1;;
100|update
101|update
102|update
103|update
104|update
105|text
211|schips sqlite> SELECT * FROM table1 WHERE name GLOB '*s*';
211|schips

LIMIT 和OFFSET 子句

LIMIT 子句:用于限制由 SELECT 语句返回的数据数量。

OFFSET 子句:指明在开始返回行之前忽略多少行。

OFFSET 0 和省略 OFFSET 子句是一样的。如果 OFFSET 和 LIMIT 都出现了,那么在计算LIMIT 个行之前先忽略 OFFSET 指定的行数。

使用 LIMIT 和 OFFSET 子句可以只取出查询结果中的一部分数据行:

SELECT select_list
FROM table_expression
[ORDER BY sort_expression1 [ASC | DESC] [, sort_expression2 [ASC | DESC] ...]]
[LIMIT { number | ALL }] [OFFSET number]
sqlite> SELECT * FROM table1;
100|update
101|update
102|update
103|update
104|update
105|text
211|schips sqlite> SELECT * FROM table1 WHERE name GLOB '*u*' LIMIT 2;
100|update
101|update sqlite> SELECT * FROM table1 WHERE name GLOB '*u*' LIMIT 2 OFFSET 2;
102|update
103|update

Order By

ORDER BY 子句是用来基于一个或多个列按升序或降序顺序排列数据。

SELECT column-list
FROM table_name
[WHERE condition]
[ORDER BY column1, column2, .. columnN] [ASC | DESC]; # ASC 升序、DESE 降序

例子:

sqlite> SELECT * FROM table1 ORDER BY ID DESC;

211|schips
105|text
104|update
103|update
102|update
101|update
100|update

Group By

GROUP BY 子句用于与 SELECT 语句一起使用,来对相同的数据进行分组(求总结果)

GROUP BY 子句必须放在 WHERE 子句中的条件之后,必须放在 ORDER BY 子句之前。

 SELECT column-list
FROM table_name
WHERE [ conditions ]
▲GROUP BY column1, column2....columnN
ORDER BY column1, column2....columnN
$ ./sqlite3 example2.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints. sqlite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
); sqlite> INSERT INTO COMPANY VALUES (8, 'Paul', 24, 'Houston', 20000.00 );
sqlite> INSERT INTO COMPANY VALUES (9, 'James', 44, 'Norway', 5000.00 );
sqlite> INSERT INTO COMPANY VALUES (10, 'James', 45, 'Texas', 5000.00 ); sqlite> SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME;
James|10000.0
Paul|20000.0

Having 子句

HAVING 子句允许指定条件来过滤将出现在有GROUP BY的最终结果中的分组结果。统计GROUPT BY结果中满足指定重复次数的结果。

WHERE 子句在所选列上设置条件,而 HAVING 子句则在由 GROUP BY 子句创建的分组上设置条件。

HAVING 子句在 SELECT 查询中的位置:

 SELECT
FROM
WHERE
GROUP BY
▲HAVING
ORDER BY

在一个查询中,HAVING 子句必须放在 GROUP BY 子句之后,必须放在 ORDER BY 子句之前。下面是包含 HAVING 子句的 SELECT 语句的语法:

SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2
sqlite> SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME;
James|19000.0
Paul|20000.0 sqlite> SELECT * FROM COMPANY GROUP BY name HAVING count(name) < 2;
8|Paul|24|Houston|20000.0 sqlite> SELECT * FROM COMPANY GROUP BY name HAVING count(name) > 2;
9|James|44|Norway|5000.0
sqlite>

基于 SQLite 3 的 C 学习:2-高级操作的更多相关文章

  1. SVN 学习笔记-高级操作

    所谓高级操作,只是曲高和寡,其实都不怎么用的.但是关键时候,可能会很有用. 这个高级只是针对基本操作而言.有些操作可能也是比较基本的. 清除锁 有时候我们在操作的时候,可能系统崩溃了,或者SVN非正常 ...

  2. Scala学习——函数高级操作

    scala函数高级操作 一.字符串高级操作 多行字符串和插值 package top.ruandb.scala.Course06 object StringApp { def main(args: A ...

  3. (七)linux 学习 -- 键盘高级操作技巧

    The Linux Command Line 读书笔记 - 部分内容来自 http://billie66.github.io/TLCL/book/chap09.html 文章目录 移动光标 修改文本 ...

  4. php基于SQLite实现的分页功能示例

    php基于SQLite实现的分页功能. 这里操作数据库文件使用的是前面文章<PHP基于PDO实现的SQLite操作类>中的SQLite数据库操作类. 代码: <?php class ...

  5. 基于TensorFlow Serving的深度学习在线预估

    一.前言 随着深度学习在图像.语言.广告点击率预估等各个领域不断发展,很多团队开始探索深度学习技术在业务层面的实践与应用.而在广告CTR预估方面,新模型也是层出不穷: Wide and Deep[1] ...

  6. 数据库MySQL学习笔记高级篇

    数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...

  7. 基于NVIDIA GPUs的深度学习训练新优化

    基于NVIDIA GPUs的深度学习训练新优化 New Optimizations To Accelerate Deep Learning Training on NVIDIA GPUs 不同行业采用 ...

  8. Shell高级编程视频教程-跟着老男孩一步步学习Shell高级编程实战视频教程

    Shell高级编程视频教程-跟着老男孩一步步学习Shell高级编程实战视频教程 教程简介: 本教程共71节,主要介绍了shell的相关知识教程,如shell编程需要的基础知识储备.shell脚本概念介 ...

  9. Python3学习(3)-高级篇

    Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 文件读写 源文件test.txt line1 line2 line3 读取文件内容 f = ope ...

  10. MySQL学习笔记_9_MySQL高级操作(上)

    MySQL高级操作(上) 一.MySQL表复制 create table t2 like t1;               #复制表结构,t2可以学习到t1所有的表结构 insert into t2 ...

随机推荐

  1. 坐标轴调控大揭秘:Matplotlib坐标轴设置全攻略+顺口溜,一文掌握!

    在数据可视化的世界里,Matplotlib是那把魔法棒,让枯燥的数据跃然纸上,而掌控这把魔法棒的核心,就是对坐标轴的精妙操作.今天,就让我们一起揭开Matplotlib坐标轴设置的神秘面纱,配上易记的 ...

  2. Flink Forward #Asia2020 流批一体及数仓资料整理

    阿里云实时计算负责人 - 王峰(莫问)/ FFA_2020-Flink as a Unified Engine - Now and Next-V4 2020年Flink 基于Flink 的流批一体数仓 ...

  3. linux-centos7.6-gpt-uefi安装

    目录 linux-centos7.6-gpt-uefi安装 一.需要 二.环境 三.vm新建虚拟机系统环境 四.开始安装 linux-centos7.6-gpt-uefi安装 一.需要 安装的系统适用 ...

  4. axios的基本

    目录 axios基本使用.html axios+vue.html axios基本使用.html <!DOCTYPE html> <html lang="en"&g ...

  5. 关于Java Chassis 3的契约优先(API First)开发

    本文分享自华为云社区<Java Chassis 3技术解密:契约优先(API First)开发>,作者: liubao68. 契约优先(API First)开发是指应用程序开发过程中,将A ...

  6. iceoryx源码阅读(一)——全局概览

    一.什么是iceoryx iceoryx是一套基于共享内存实现的进程间通信组件. 二.源码结构 iceoryx源码包括若干工程,整理如下表所示: 下图展示了主要项目之间的依赖(FROM:iceoryx ...

  7. 关于小说阅读前端翻页插件推荐turn.js

    http://www.turnjs.com

  8. 【漏洞复现】蓝凌OA sysUiComponent 任意文件上传漏洞

    阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站.服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作.利用此文所提供的信息而造成的直接 ...

  9. Django模型层的QuerySet对象

    def index(request): # 查询数据,返回QuerySet对象books books=Book.objects.filter(id__gte=1) # 打印books, 是一个Quer ...

  10. TS码流解析(三)PES

    我们常说的音视频数据流在TS中被称为Elementary Stream(ES),也称为原始码流(裸流).ES流本身不含有传输所需的所有信息,为了在传输过程中同时携带PTS(Presentation T ...