SQLite 的 PRAGMA 命令是一个特殊的命令,可以用在 SQLite 环境内控制各种环境变量和状态标志。一个 PRAGMA 值可以被读取,也可以根据需求进行设置。
语法:要查询当前的 PRAGMA 值,只需要提供该 pragma 的名字:
PRAGMA pragma_name;
要为 PRAGMA 设置一个新的值,语法如下:
PRAGMA pragma_name = value;
设置模式,可以是名称或等值的整数,但返回的值将始终是一个整数。
auto_vacuum Pragma 获取或设置 auto-vacuum 模式。
语法如下:
PRAGMA [database.]auto_vacuum;
PRAGMA [database.]auto_vacuum = mode;
其中,mode 可以是以下任何一种:
Pragma 值 | 描述 |
---|---|
0 或 NONE | 禁用 Auto-vacuum。这是默认模式,意味着数据库文件尺寸大小不会缩小,除非手动使用 VACUUM 命令。 |
1 或 FULL | 启用 Auto-vacuum,是全自动的。在该模式下,允许数据库文件随着数据从数据库移除而缩小。 |
2 或 INCREMENTAL | 启用 Auto-vacuum,但是必须手动激活。在该模式下,引用数据被维持,免费页面只放在免费列表中。这些页面可在任何时候使用 incremental_vacuum pragma 进行覆盖。 |
sqlite> PRAGMA auto_vacuum;
auto_vacuum
-----------
0
cache_size Pragma 可获取或暂时设置在内存中页面缓存的最大尺寸。
语法如下:
PRAGMA [database.]cache_size;
PRAGMA [database.]cache_size = pages;
pages 值表示在缓存中的页面数。内置页面缓存的默认大小为 2,000 页,最小尺寸为 10 页。
sqlite> PRAGMA cache_size;
cache_size
----------
-2000
case_sensitive_like Pragma 控制内置的 LIKE 表达式的大小写敏感度。默认情况下,该 Pragma 为 false,这意味着,内置的 LIKE 操作符忽略字母的大小写。
语法如下:
PRAGMA case_sensitive_like = [true|false];
目前没有办法查询该 Pragma 的当前状态。
count_changes Pragma 获取或设置数据操作语句的返回值,如 INSERT、UPDATE 和 DELETE。
语法如下:
PRAGMA count_changes;
PRAGMA count_changes = [true|false];
默认情况下,该 Pragma 为 false,这些语句不返回任何东西。如果设置为 true,每个所提到的语句将返回一个单行单列的表,由一个单一的整数值组成,该整数表示操作影响的行。
sqlite> PRAGMA count_changes;
count_changes
-------------
0
sqlite> INSERT INTO user VALUES('zhy', 24);
sqlite> select * from user;
one two
---------- ----------
hello 10
goodbye 20
zhy 24
sqlite> PRAGMA count_changes = true;
sqlite> INSERT INTO user VALUES('Tom', 28);
rows inserted
-------------
1
sqlite> select * from user;
one two
---------- ----------
hello 10
goodbye 20
zhy 24
Tom 28
database_list Pragma 将用于列出了所有的数据库连接。
语法如下:
PRAGMA database_list;
该 Pragma 将返回一个单行三列的表格,每当打开或附加数据库时,会给出数据库中的序列号,它的名称和相关的文件。
sqlite> PRAGMA database_list;
seq name file
---------- ---------- ----------------
0 main C:\sqlite\testDB
encoding Pragma 控制字符串如何编码及存储在数据库文件中。
语法如下:
PRAGMA encoding;
PRAGMA encoding = format;
sqlite> PRAGMA encoding;
encoding
----------
UTF-8
格式值可以是 UTF-8、UTF-16le 或 UTF-16be 之一。
freelist_count Pragma 返回一个整数,表示当前被标记为免费和可用的数据库页数。
语法如下:
PRAGMA [database.]freelist_count;
index_info Pragma 返回关于数据库索引的信息。
语法如下:
PRAGMA [database.]index_info( index_name );
结果集将为每个包含在给出列序列的索引、表格内的列索引、列名称的列显示一行。
sqlite> .index
sqlite_autoindex_company_1 sqlite_autoindex_department_1
sqlite_autoindex_company_2 sqlite_autoindex_tb1_1
sqlite> PRAGMA index_info(sqlite_autoindex_tb1_1);
seqno cid name
---------- ---------- ----------
0 0 f1
index_list Pragma 列出所有与表相关联的索引。
语法如下:
PRAGMA [database.]index_list( table_name );
结果集将为每个给出列序列的索引、索引名称、表示索引是否唯一的标识显示一行。
sqlite> PRAGMA index_list(company);
seq name unique origin partial
---------- -------------------------- ---------- ---------- ----------
0 sqlite_autoindex_company_2 1 u 0
1 sqlite_autoindex_company_1 1 pk 0
journal_mode Pragma 获取或设置控制日志文件如何存储和处理的日志模式。
语法如下::
PRAGMA journal_mode;
PRAGMA journal_mode = mode;
PRAGMA database.journal_mode;
PRAGMA database.journal_mode = mode;
这里支持五种日志模式:
Pragma 值 | 描述 |
---|---|
DELETE | 默认模式。在该模式下,在事务结束时,日志文件将被删除。 |
TRUNCATE | 日志文件被阶段为零字节长度。 |
PERSIST | 日志文件被留在原地,但头部被重写,表明日志不再有效。 |
MEMORY | 日志记录保留在内存中,而不是磁盘上。 |
OFF | 不保留任何日志记录。 |
sqlite> PRAGMA journal_mode;
journal_mode
------------
delete
max_page_count Pragma 为数据库获取或设置允许的最大页数。
语法如下:
PRAGMA [database.]max_page_count;
PRAGMA [database.]max_page_count = max_page;
默认值是 1,073,741,823,这是一个千兆的页面,即如果默认 1 KB 的页面大小,那么数据库中增长起来的一个兆字节。
sqlite> PRAGMA max_page_count;
max_page_count
--------------
1073741823
page_count Pragma 返回当前数据库中的网页数量。
语法如下:
PRAGMA [database.]page_count;
数据库文件的大小应该是 page_count * page_size。
sqlite> PRAGMA page_count;
page_count
----------
72
page_size Pragma 获取或设置数据库页面的大小。
语法如下:
PRAGMA [database.]page_size;
PRAGMA [database.]page_size = bytes;
默认情况下,允许的尺寸是 512、1024、2048、4096、8192、16384、32768 字节。改变现有数据库页面大小的唯一方法就是设置页面大小,然后立即 VACUUM 该数据库。
sqlite> PRAGMA page_size;
page_size
----------
4096
parser_trace Pragma 随着它解析 SQL 命令来控制打印的调试状态,
语法如下:
PRAGMA parser_trace = [true|false];
默认情况下,它被设置为 false,但设置为 true 时则启用,此时 SQL 解析器会随着它解析 SQL 命令来打印出它的状态。
recursive_triggers Pragma 获取或设置递归触发器功能。如果未启用递归触发器,一个触发动作将不会触发另一个触发。
语法如下:
PRAGMA recursive_triggers;
PRAGMA recursive_triggers = [true|false];
sqlite> PRAGMA recursive_triggers;
recursive_triggers
------------------
0
schema_version Pragma 获取或设置存储在数据库头中的的架构版本值。
语法如下:
PRAGMA [database.]schema_version;
PRAGMA [database.]schema_version = number;
这是一个 32 位有符号整数值,用来跟踪架构的变化。每当一个架构改变命令执行(比如 CREATE… 或 DROP…)时,这个值会递增。
sqlite> PRAGMA schema_version;
schema_version
--------------
17
sqlite> CREATE TABLE class(
...> ID INT,
...> name TEXT
...> );
sqlite> PRAGMA schema_version;
schema_version
--------------
18
secure_delete Pragma 用来控制内容是如何从数据库中删除。
语法如下:
PRAGMA secure_delete;
PRAGMA secure_delete = [true|false];
PRAGMA database.secure_delete;
PRAGMA database.secure_delete = [true|false];
安全删除标志的默认值通常是关闭的,但是这是可以通过 SQLITE_SECURE_DELETE 构建选项来改变的。
sqlite> PRAGMA secure_delete;
secure_delete
-------------
0
sql_trace Pragma 用于把 SQL 跟踪结果转储到屏幕上。
语法如下:
PRAGMA sql_trace;
PRAGMA sql_trace = [true|false];
SQLite 必须通过 SQLITE_DEBUG 指令来编译要引用的该 Pragma。
synchronous Pragma 获取或设置当前磁盘的同步模式,该模式控制积极的 SQLite 如何将数据写入物理存储。
语法如下:
PRAGMA [database.]synchronous;
PRAGMA [database.]synchronous = mode;
SQLite 支持下列同步模式:
Pragma 值 | 描述 |
---|---|
0 或 OFF | 不进行同步。 |
1 或 NORMAL | 在关键的磁盘操作的每个序列后同步。 |
2 或 FULL | 在每个关键的磁盘操作后同步。 |
sqlite> PRAGMA synchronous;
synchronous
-----------
2
temp_store Pragma 获取或设置临时数据库文件所使用的存储模式。
语法如下:
PRAGMA temp_store;
PRAGMA temp_store = mode;
SQLite 支持下列存储模式:
Pragma 值 | 描述 |
---|---|
0 或 DEFAULT | 默认使用编译时的模式。通常是 FILE。 |
1 或 FILE | 使用基于文件的存储。 |
2 或 MEMORY | 使用基于内存的存储。 |
sqlite> PRAGMA temp_store;
temp_store
----------
0
temp_store_directory Pragma 获取或设置用于临时数据库文件的位置。
语法如下:
PRAGMA temp_store_directory;
PRAGMA temp_store_directory = 'directory_path';
user_version Pragma 获取或设置存储在数据库头的用户自定义的版本值。
语法如下:
PRAGMA [database.]user_version;
PRAGMA [database.]user_version = number;
这是一个 32 位的有符号整数值,可以由开发人员设置,用于版本跟踪的目的。
sqlite> PRAGMA user_version;
user_version
------------
0
writable_schema Pragma 获取或设置是否能够修改系统表。
语法如下:
PRAGMA writable_schema;
PRAGMA writable_schema = [true|false];
如果设置了该 Pragma,则表以 sqlite_ 开始,可以创建和修改,包括 sqlite_master 表。使用该 Pragma 时要注意,因为它可能导致整个数据库损坏。
sqlite> PRAGMA writable_schema;
writable_schema
---------------
0
约束是在表的数据列上强制执行的规则。这些是用来限制可以插入到表中的数据类型。这确保了数据库中数据的准确性和可靠性。
约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。
以下是在 SQLite 中常用的约束:
默认情况下,列可以保存 NULL 值。如果您不想某列有 NULL 值,那么需要在该列上定义此约束,指定在该列上不允许 NULL 值。
NULL 与没有数据是不一样的,它代表着未知的数据。
例:
sqlite> CREATE TABLE company(
...> ID int PRIMARY KEY NOT NULL,
...> name text NOT NULL,
...> age int NOT NULL,
...> address char(50),
...> salary real
...> );
DEFAULT 约束在 INSERT INTO 语句没有提供一个特定的值时,为列提供一个默认值。
例:设置 salary 列的值默认为50000.00
sqlite> 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
...> );
sqlite> INSERT INTO company(ID, name ,age, address) VALUES(2, 'Jack', 34, 'China
');
sqlite> select * from company;
1|Jack|34|China|50000.0
UNIQUE 约束防止在一个特定的列存在两个记录具有相同的值。
例:设置name 列的值唯一
sqlite> CREATE TABLE company(
...> ID int PRIMARY KEY NOT NULL,
...> name text NOT NULL UNIQUE,
...> age int NOT NULL,
...> address char(50),
...> salary REAL NOT NULL DEFAULT 50000.00
...> );
sqlite> INSERT INTO company(ID, name, age, address) VALUES(1, 'Tom', 24, 'China'
);
sqlite> select * from company;
1|Tom|24|China|50000.0
sqlite> INSERT INTO company(ID, name, age, address) VALUES(2, 'Tom', 54, 'China'
);
Error: UNIQUE constraint failed: company.name
PRIMARY KEY 约束唯一标识数据库表中的每个记录。在一个表中可以有多个 UNIQUE 列,但只能有一个主键。在设计数据库表时,主键是很重要的。主键是唯一的 ID。
我们使用主键来引用表中的行。可通过把主键设置为其他表的外键,来创建表之间的关系。由于"长期存在编码监督",在 SQLite 中,主键可以是 NULL,这是与其他数据库不同的地方。
主键是表中的一个字段,唯一标识数据库表中的各行/记录。主键必须包含唯一值。主键列不能有 NULL 值。
一个表只能有一个主键,它可以由一个或多个字段组成。当多个字段作为主键,它们被称为复合键。
如果一个表在任何字段上定义了一个主键,那么在这些字段上不能有两个记录具有相同的值。
CHECK 约束启用输入一条记录要检查值的条件。如果条件值为 false,则记录违反了约束,且不能输入到表。
例:设置检查 salary 的值不能小于0
sqlite> CREATE TABLE company(
...> ID int PRIMARY KEY NOT NULL,
...> name text NOT NULL UNIQUE,
...> age int NOT NULL,
...> address char(50),
...> salary REAL NOT NULL CHECK(salary > 0) DEFAULT 50000.00
...> );
sqlite> INSERT INTO company VALUES(1, 'Tom', 24, 'China', 0.00);
Error: CHECK constraint failed: company
sqlite> INSERT INTO company VALUES(2, 'Tomas', 34, 'China', 0);
Error: CHECK constraint failed: company
SQLite 支持 ALTER TABLE 的有限子集。在 SQLite 中,ALTER TABLE 命令允许用户重命名表,或向现有表添加一个新的列。重命名列,删除一列,或从一个表中添加或删除约束都是不可能的。
SQLite 的 Join 子句用于结合两个或多个数据库中表的记录。JOIN 是一种通过共同值来结合两个表中字段的手段。
SQL 定义了三种主要类型的连接:
交叉连接(CROSS JOIN)把第一个表的每一行与第二个表的每一行进行匹配。如果两个输入表分别有 x 和 y 行,则结果表有 x*y 行。由于交叉连接(CROSS JOIN)有可能产生非常大的表,使用时必须谨慎,只在适当的时候使用它们。
交叉连接的操作,它们都返回被连接的两个表所有数据行的笛卡尔积,返回到的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。
下面是交叉连接(CROSS JOIN)的语法:
SELECT ... FROM table1 CROSS JOIN table2 ...
例:
sqlite> SELECT emp_ID, name, dept FROM company CROSS JOIN department;
emp_ID name dept
---------- ---------- ----------
1 Allen IT Billing
2 Allen Engineerin
7 Allen Finance
1 David IT Billing
2 David Engineerin
7 David Finance
1 James IT Billing
2 James Engineerin
7 James Finance
1 Kim IT Billing
2 Kim Engineerin
7 Kim Finance
1 Mark IT Billing
2 Mark Engineerin
7 Mark Finance
1 Paul IT Billing
2 Paul Engineerin
7 Paul Finance
1 Teddy IT Billing
2 Teddy Engineerin
7 Teddy Finance
内连接(INNER JOIN)根据连接谓词结合两个表(table1 和 table2)的列值来创建一个新的结果表。查询会把 table1 中的每一行与 table2 中的每一行进行比较,找到所有满足连接谓词的行的匹配对。当满足连接谓词时,A 和 B 行的每个匹配对的列值会合并成一个结果行。
内连接(INNER JOIN)是最常见的连接类型,是默认的连接类型。INNER 关键字是可选的。
下面是内连接(INNER JOIN)的语法:
SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression ...
为了避免冗余,并保持较短的措辞,可以使用 USING 表达式声明内连接(INNER JOIN)条件。这个表达式指定一个或多个列的列表:
SELECT ... FROM table1 JOIN table2 USING ( column1 ,... ) ...
自然连接(NATURAL JOIN)类似于 JOIN…USING,只是它会自动测试存在两个表中的每一列的值之间相等值:
SELECT ... FROM table1 NATURAL JOIN table2...
例:
sqlite> SELECT emp_ID, name, dept FROM company INNER JOIN department ON com
ID =department.emp_ID;
emp_ID name dept
---------- ---------- ----------
1 Paul IT Billing
2 Allen Engineerin
7 James Finance
外连接(OUTER JOIN)是内连接(INNER JOIN)的扩展。虽然 SQL 标准定义了三种类型的外连接:LEFT、RIGHT、FULL,但 SQLite 只支持 左外连接(LEFT OUTER JOIN)。
外连接(OUTER JOIN)声明条件的方法与内连接(INNER JOIN)是相同的,使用 ON、USING 或 NATURAL 关键字来表达。最初的结果表以相同的方式进行计算。一旦主连接计算完成,外连接(OUTER JOIN)将从一个或两个表中任何未连接的行合并进来,外连接的列使用 NULL 值,将它们附加到结果表中。
下面是左外连接(LEFT OUTER JOIN)的语法:
SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...
为了避免冗余,并保持较短的措辞,可以使用 USING 表达式声明外连接(OUTER JOIN)条件。这个表达式指定一个或多个列的列表:
SELECT ... FROM table1 LEFT OUTER JOIN table2 USING ( column1 ,... ) ...
例:
sqlite> SELECT emp_ID, name, dept FROM company LEFT OUTER JOIN department
...> ON company.ID = department.emp_ID;
emp_ID name dept
---------- ---------- ----------
1 Paul IT Billing
2 Allen Engineerin
Teddy
Mark
David
Kim
7 James Finance
SQLite的 UNION 子句/运算符用于合并两个或多个 SELECT 语句的结果,不返回任何重复的行。
为了使用 UNION,每个 SELECT 被选择的列数必须是相同的,相同数目的列表达式,相同的数据类型,并确保它们有相同的顺序,但它们不必具有相同的长度。
UNION 的基本语法如下:
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
UNION
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
这里给定的条件根据需要可以是任何表达式。
例:
sqlite> insert into department values(4, 'Engineering', 3)
...> ;insert into department values(5, 'Finance', 4)
...> ;insert into department values(6, 'Engineering', 5)
...> ;insert into department values(7, 'Finance', 6)
...> ;
sqlite> select * from department;
ID dept emp_ID
---------- ---------- ----------
1 IT Billing 1
2 Engineerin 2
3 Finance 7
4 Engineerin 3
5 Finance 4
6 Engineerin 5
7 Finance 6
UNION ALL 运算符用于结合两个 SELECT 语句的结果,包括重复行。
适用于 UNION 的规则同样适用于 UNION ALL 运算符。
UNION ALL 的基本语法如下:
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
UNION ALL
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
例:
sqlite> SELECT emp_ID, name, dept FROM company INNER JOIN department
...> ON company.ID = department.emp_ID
...> UNION ALL
...> SELECT emp_ID, name, dept FROM company LEFT OUTER JOIN department
...> ON company.ID = department.emp_ID;
emp_ID name dept
---------- ---------- ----------
1 Paul IT Billing
2 Allen Engineerin
7 James Finance
3 Teddy Engineerin
4 Mark Finance
5 David Engineerin
6 Kim Finance
1 Paul IT Billing
2 Allen Engineerin
3 Teddy Engineerin
4 Mark Finance
5 David Engineerin
6 Kim Finance
7 James Finance
SQLite 的 NULL 是用来表示一个缺失值的项。表中的一个 NULL 值是在字段中显示为空白的一个值。
带有 NULL 值的字段是一个不带有值的字段。NULL 值与零值或包含空格的字段是不同的,理解这点是非常重要的。
SQLite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
在这里,NOT NULL 表示列总是接受给定数据类型的显式值。这里有两个列我们没有使用 NOT NULL,这意味着这两个列可以为 NULL。
带有 NULL 值的字段在记录创建的时候可以保留为空。
sqlite> SELECT * FROM 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 45000.0
7 James 24 10000.0
sqlite> SELECT * from company where address IS NOT NULL;
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
sqlite> SELECT * from company where address IS NULL;
ID name age address salary
---------- ---------- ---------- ---------- ----------
6 Kim 22 45000.0
7 James 24 10000.0
可以暂时把表或列重命名为另一个名字,这被称为别名。使用表别名是指在一个特定的 SQLite 语句中重命名表。重命名是临时的改变,在数据库中实际的表的名称不会改变。
列别名用来为某个特定的 SQLite 语句重命名表中的列。
表 别名的基本语法如下:
SELECT column1, column2....
FROM table_name AS alias_name
WHERE [condition];
列 别名的基本语法如下:
SELECT column_name AS alias_name
FROM table_name
WHERE [condition];
例:表别名
sqlite> SELECT C.ID, C.name, D.dept
...> FROM company AS C, department AS D
...> WHERE C.ID = D.emp_ID;
ID name dept
---------- ---------- ----------
1 Paul IT Billing
2 Allen Engineerin
7 James Finance
3 Teddy Engineerin
4 Mark Finance
5 David Engineerin
6 Kim Finance
例:列别名
sqlite> SELECT C.ID AS companyID, C.name AS companyName, C.age, D.dept
...> FROM company AS C, department AS D
...> WHERE C.ID = D.emp_ID;
companyID companyName age dept
---------- ----------- ---------- ----------
1 Paul 32 IT Billing
2 Allen 25 Engineerin
7 James 24 Finance
3 Teddy 23 Engineerin
4 Mark 25 Finance
5 David 27 Engineerin
6 Kim 22 Finance
SQLite 触发器(Trigger)是数据库的回调函数,它会在指定的数据库事件发生时自动执行/调用。
以下是关于 SQLite 的触发器(Trigger)的要点:
创建 触发器(Trigger) 的基本语法如下:
CREATE TRIGGER trigger_name [BEFORE|AFTER] event_name
ON table_name
BEGIN
-- Trigger logic goes here....
END;
在这里,event_name 可以是在所提到的表 table_name 上的 INSERT、DELETE 和 UPDATE 数据库操作。可以在表名后选择指定 FOR EACH ROW。
以下是在 UPDATE 操作上在表的一个或多个指定列上创建触发器(Trigger)的语法:
CREATE TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name
ON table_name
BEGIN
-- Trigger logic goes here....
END;
例:创建一个名为 audit 的新表。每当 company 表中有一个新的记录项时,日志消息将被插入其中
sqlite> CREATE TABLE audit(
...> emp_ID INT NOT NULL,
...> entry_date TEXT NOT NULL
...> );
注意 :emp_ID 是来自 company 表的 ID,entry_date 将保持 company 中记录被创建时的时间戳。
现在让我们在 COMPANY 表上创建一个触发器,如下所示:
sqlite> CREATE TRIGGER audit_log AFTER INSERT
...> ON company
...> BEGIN
...> INSERT INTO audit VALUES(new.ID, datetime('now'));
...> END;
现在,我们将开始在 company 表中插入记录,这将导致在 audit 表中创建一个审计日志记录。因此,让我们在 company 表中创建一个记录,如下所示:
sqlite> INSERT INTO company VALUES(15, 'XiaoMing', 32, 'HangZhou', 20000.00);
同时,将在 AUDIT 表中创建一个记录。这个纪录是触发器的结果,这是我们在 COMPANY 表上的 INSERT 操作上创建的触发器(Trigger)。
sqlite> select * from audit;
emp_ID entry_date
---------- -------------------
15 2018-10-28 04:47:54
类似的,可以根据需要在 UPDATE 和 DELETE 操作上创建触发器(Trigger)。
例:UPDATE
sqlite> CREATE TRIGGER audit_UPDATE AFTER UPDATE
...> ON company
...> BEGIN
...> INSERT INTO audit VALUES(new.ID, datetime('now'));
...> END;
sqlite> UPDATE company SET name = 'One' WHERE ID = 1;
sqlite> select * from company where ID=1;
ID name age address salary
---------- ---------- ---------- ---------- ----------
1 One 32 California 20000.0
sqlite> select * from audit;
emp_ID entry_date
---------- -------------------
15 2018-10-28 04:47:54
1 2018-10-28 05:14:22
可以从 sqlite_master 表中列出所有触发器,如下所示:
sqlite> select * from audit_del;
sqlite> SELECT name FROM sqlite_master
...> WHERE type = 'trigger';
name
--------------
update_trigger
audit_log
audit_UPDATE
del_trigger
如果想要列出特定表上的触发器,则使用 AND 子句连接表名,如下所示:
sqlite> SELECT name FROM sqlite_master
...> WHERE type = 'trigger' AND tbl_name = 'company';
name
--------------
update_trigger
audit_log
audit_UPDATE
del_trigger
下面是 DROP 命令,可用于删除已有的触发器:
sqlite> DROP TRIGGER trigger_name;
sqlite> DROP TRIGGER del_trigger;
sqlite> SELECT name FROM sqlite_master
...> WHERE type = 'trigger' AND tbl_name = 'company';
name
--------------
update_trigger
audit_log
audit_UPDATE
索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。
例如,如果您想在一本讨论某个话题的书中引用所有页面,您首先需要指向索引,索引按字母顺序列出了所有主题,然后指向一个或多个特定的页码。
索引有助于加快 SELECT 查询和 WHERE 子句,但它会减慢使用 UPDATE 和 INSERT 语句时的数据输入。索引可以创建或删除,但不会影响数据。
使用 CREATE INDEX 语句创建索引,它允许命名索引,指定表及要索引的一列或多列,并指示索引是升序排列还是降序排列。
索引也可以是唯一的,与 UNIQUE 约束类似,在列上或列组合上防止重复条目。
CREATE INDEX 的基本语法如下:
CREATE INDEX index_name ON table_name;
单列索引是一个只基于表的一个列上创建的索引。
基本语法如下:
CREATE INDEX index_name
ON table_name (column_name);
使用唯一索引不仅是为了性能,同时也为了数据的完整性。唯一索引不允许任何重复的值插入到表中。
基本语法如下:
CREATE UNIQUE INDEX index_name
ON table_name (column_name);
组合索引是基于一个表的两个或多个列上创建的索引。
基本语法如下:
CREATE INDEX index_name
ON table_name (column1, column2);
是否要创建一个单列索引还是组合索引,要考虑到您在作为查询过滤条件的 WHERE 子句中使用非常频繁的列。
如果值使用到一个列,则选择使用单列索引。如果在作为过滤的 WHERE 子句中有两个或多个列经常使用,则选择使用组合索引。
隐式索引是在创建对象时,由数据库服务器自动创建的索引。索引自动创建为主键约束和唯一约束。
例:在 company 表的 salary 列上创建一个索引,使用 .indices 或 .indexes 命令列出 company 表上所有可用的索引,如下所示:
sqlite> .indices company
sqlite_autoindex_company_1 sqlite_autoindex_company_2
sqlite> CREATE INDEX salary_index ON company (salary);
sqlite> .indices company
salary_index sqlite_autoindex_company_2
sqlite_autoindex_company_1
注意:其中 sqlite_autoindex_COMPANY_1 是创建表时创建的隐式索引。
可以列出数据库范围的所有索引,如下所示:
sqlite> SELECT * FROM sqlite_master WHERE type = 'index';
type name tbl_name rootpage sql
---------- ---------------------- ---------- ---------- ----------
index sqlite_autoindex_tb1_1 tb1 4
index sqlite_autoindex_depar department 9
index sqlite_autoindex_compa company 6
index sqlite_autoindex_compa company 7
index salary_index company 75 CREATE IND
一个索引可以使用 SQLite 的 DROP 命令删除。当删除索引时应特别注意,因为性能可能会下降或提高。
基本语法如下:
DROP INDEX index_name;
sqlite> DROP INDEX salary_index;
sqlite> SELECT * FROM sqlite_master WHERE type = 'index';
type name tbl_name rootpage sql
---------- ---------------------- ---------- ---------- ----------
index sqlite_autoindex_tb1_1 tb1 4
index sqlite_autoindex_depar department 9
index sqlite_autoindex_compa company 6
index sqlite_autoindex_compa company 7
虽然索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。使用索引时,应重新考虑下列准则:
“INDEXED BY index-name” 子句规定必须需要命名的索引来查找前面表中值。
如果索引名 index-name 不存在或不能用于查询,然后 SQLite 语句的准备失败。
“NOT INDEXED” 子句规定当访问前面的表(包括由 UNIQUE 和 PRIMARY KEY 约束创建的隐式索引)时,没有使用索引。
然而,即使指定了 “NOT INDEXED”,INTEGER PRIMARY KEY 仍然可以被用于查找条目。
下面是 INDEXED BY 子句的语法,它可以与 DELETE、UPDATE 或 SELECT 语句一起使用:
SELECT|DELETE|UPDATE column1, column2...
FROM table_name
INDEXED BY (index_name)
WHERE (condition);
例:
sqlite> CREATE INDEX salary_index ON company (salary);
sqlite> SELECT * FROM company INDEXED BY salary_index WHERE salary > 50000;
ID name age address salary
---------- ---------- ---------- ---------- ----------
4 Mark 25 Rich-Mond 65000.0
5 David 27 Texas 85000.0
sqlite> SELECT * FROM company INDEXED BY salary_index_2 WHERE salary > 50000;
Error: no such index: salary_index_2
SQLite 的 ALTER TABLE 命令不通过执行一个完整的转储和数据的重载来修改已有的表。您可以使用 ALTER TABLE 语句重命名表,使用 ALTER TABLE 语句还可以在已有的表中添加额外的列。
在 SQLite 中,除了重命名表和在已有的表中添加列,ALTER TABLE 命令不支持其他操作。
用来重命名已有的表的 ALTER TABLE 的基本语法如下:
ALTER TABLE database_name.table_name RENAME TO new_table_name;
用来在已有的表中添加一个新的列的 ALTER TABLE 的基本语法如下:
ALTER TABLE database_name.table_name ADD COLUMN column_def...;
例:重命名表 tb1 为 tb_1
sqlite> .tables
audit class department tb1
audit_del company images user
sqlite> ALTER TABLE tb1 RENAME TO tb_1;
sqlite> .tables
audit class department tb_1
audit_del company images user
例:为表 tb_1 增加一列
sqlite> .schema tb_1
CREATE TABLE IF NOT EXISTS "tb_1"(
f1 varchar(30) primary key,
f2 text,
f3 real
);
sqlite> ALTER TABLE tb_1 ADD COLUMN name TEXT;
sqlite> .schema tb_1
CREATE TABLE IF NOT EXISTS "tb_1"(
f1 varchar(30) primary key,
f2 text,
f3 real
, name TEXT);
注意,新添加的列是以 NULL 值来填充的。
sqlite> select * from tb_1 ;
f1 f2 f3 name
---------- ---------- ---------- ----------
zhy hello 80.5
在 SQLite 中,并没有 TRUNCATE TABLE 命令,但可以使用 SQLite 的 DELETE 命令从已有的表中删除全部的数据。
DELETE 命令的基本语法如下:
sqlite> DELETE FROM table_name;
但这种方法无法将递增数归零。
如果要将递增数归零,可以使用以下方法:
sqlite> DELETE FROM sqlite_sequence WHERE name = 'table_name';
当 SQLite 数据库中包含自增列时,会自动建立一个名为 sqlite_sequence 的表。这个表包含两个列:name 和 seq。name 记录自增列所在的表,seq 记录当前序号(下一条记录的编号就是当前序号加 1)。如果想把某个自增列的序号归零,只需要修改 sqlite_sequence 表就可以了。
UPDATE sqlite_sequence SET seq = 0 WHERE name = 'table_name';
视图(View)只不过是通过相关的名称存储在数据库中的一个 SQLite 语句。视图实际上是一个以预定义的 SQLite 查询形式存在的表的组合。
视图(View)可以包含一个表的所有行或从一个或多个表选定行。视图可以从一个或多个表创建,这取决于要创建视图的 SQLite 查询。、
视图(View)是一种虚表,允许用户实现以下几点:
SQLite 视图是只读的,因此可能无法在视图上执行 DELETE、INSERT 或 UPDATE 语句。但是可以在视图上创建一个触发器,当尝试 DELETE、INSERT 或 UPDATE 视图时触发,需要做的动作在触发器内容中定义。
SQLite 的视图是使用 CREATE VIEW 语句创建的。SQLite 视图可以从一个单一的表、多个表或其他视图创建。
CREATE VIEW 的基本语法如下:
CREATE [TEMP | TEMPORARY] VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];
可以在 SELECT 语句中包含多个表,这与在正常的 SQL SELECT 查询中的方式非常相似。如果使用了可选的 TEMP 或 TEMPORARY 关键字,则将在临时数据库中创建视图。
例:从 company 表创建视图的实例。视图只从 company 表中选取几列
sqlite> CREATE VIEW company_view AS
...> SELECT ID, name, age
...> FROM company;
现在,可以查询 company_view,与查询实际表的方式类似:
sqlite> SELECT * FROM company_view;
ID name age
---------- ---------- ----------
1 Paul 32
2 Allen 25
3 Teddy 23
4 Mark 25
5 David 27
6 Kim 22
7 James 24
要删除视图,只需使用带有 view_name 的 DROP VIEW 语句。
DROP VIEW 的基本语法如下:
sqlite> DROP VIEW view_name;
例:删除 company_view 视图
sqlite> DROP VIEW company_view;
sqlite> SELECT * FROM company_view;
Error: no such table: company_view
事务(Transaction)是一个对数据库执行工作单元。事务(Transaction)是以逻辑顺序完成的工作单位或序列,可以是由用户手动操作完成,也可以是由某种数据库程序自动完成。
事务(Transaction)是指一个或多个更改数据库的扩展。例如,如果您正在创建一个记录或者更新一个记录或者从表中删除一个记录,那么您正在该表上执行事务。重要的是要控制事务以确保数据的完整性和处理数据库错误。
实际上,您可以把许多的 SQLite 查询联合成一组,把所有这些放在一起作为事务的一部分进行执行。
事务(Transaction)具有以下四个标准属性,通常根据首字母缩写为 ACID:
使用下面的命令来控制事务:
事务控制命令只与 DML 命令 INSERT、UPDATE 和 DELETE 一起使用。他们不能在创建表或删除表时使用,因为这些操作在数据库中是自动提交的。
事务(Transaction)可以使用 BEGIN TRANSACTION 命令或简单的 BEGIN 命令来启动。此类事务通常会持续执行下去,直到遇到下一个 COMMIT 或 ROLLBACK 命令。不过在数据库关闭或发生错误时,事务处理也会回滚。
以下是启动一个事务的简单语法:
BEGIN;
or
BEGIN TRANSACTION;
COMMIT 命令是用于把事务调用的更改保存到数据库中的事务命令。
COMMIT 命令把自上次 COMMIT 或 ROLLBACK 命令以来的所有事务保存到数据库。
COMMIT 命令的语法如下:
COMMIT;
or
END TRANSACTION;
ROLLBACK 命令是用于撤消尚未保存到数据库的事务的事务命令。
ROLLBACK 命令只能用于撤销自上次发出 COMMIT 或 ROLLBACK 命令以来的事务。
ROLLBACK 命令的语法如下:
ROLLBACK;
例:从 company 表中删除 age = 25 的记录,最后使用 ROLLBACK 命令撤消所有的更改
sqlite> BEGIN TRANSACTION;
sqlite> DELETE FROM company WHERE age = 25;
sqlite> SELECT ID, age FROM company;
ID age
---------- ----------
1 32
3 23
5 27
6 22
7 24
sqlite> ROLLBACK;
sqlite> SELECT ID, age FROM company;
ID age
---------- ----------
1 32
2 25
3 23
4 25
5 27
6 22
7 24
例:开始另一个事务,从 company 表中删除 age = 25 的记录,最后使用 COMMIT 命令提交所有的更改
sqlite> BEGIN TRANSACTION;
sqlite> DELETE FROM company WHERE age = 25;
sqlite> COMMIT;
sqlite> SELECT ID, age FROM company;
ID age
---------- ----------
1 32
3 23
5 27
6 22
7 24
子查询或内部查询或嵌套查询是在另一个 SQLite 查询内嵌入在 WHERE 子句中的查询。
使用子查询返回的数据将被用在主查询中作为条件,以进一步限制要检索的数据。
子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,可伴随着使用运算符如 =、<、>、>=、<=、IN、BETWEEN 等。
以下是子查询必须遵循的几个规则:
子查询通常与 SELECT 语句一起使用。基本语法如下:
SELECT column_name [, column_name ]
FROM table1 [, table2 ]
WHERE column_name OPERATOR
(SELECT column_name [, column_name ]
FROM table1 [, table2 ]
[WHERE])
注:OPERATOR—操作符。
例:
sqlite> SELECT * FROM company WHERE ID IN ( SELECT ID
...> FROM company
...> WHERE salary > 45000);
ID name age address salary
---------- ---------- ---------- ---------- ----------
4 Mark 25 Rich-Mond 65000.0
5 David 27 Texas 85000.0
子查询也可以与 INSERT 语句一起使用。INSERT 语句使用子查询返回的数据插入到另一个表中。在子查询中所选择的数据可以用任何字符、日期或数字函数修改。
基本语法如下:
INSERT INTO table_name [ (column1 [, column2 ]) ]
SELECT [ *|column1 [, column2 ]
FROM table1 [, table2 ]
[ WHERE VALUE OPERATOR ]
例:
sqlite> select * from person;
sqlite> INSERT INTO person
...> SELECT ID,name,age FROM company
...> WHERE ID IN (SELECT ID FROM company WHERE age >= 30);
sqlite> select * from person;
ID name age
---------- ---------- ----------
1 Paul 32
例:
sqlite> INSERT INTO person
...> SELECT ID,name,age + 10 FROM company
...> WHERE ID IN (SELECT ID FROM company WHERE age = 22);
sqlite> select * from person;
ID name age
---------- ---------- ----------
1 Paul 32
6 Kim 32
子查询可以与 UPDATE 语句结合使用。当通过 UPDATE 语句使用子查询时,表中单个或多个列被更新。
基本语法如下:
UPDATE table_name
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
(SELECT COLUMN_NAME
FROM TABLE_NAME)
[ WHERE) ]
例:
sqlite> select * from person;
ID name age
---------- ---------- ----------
1 Paul 32
6 Kim 32
sqlite> UPDATE person
...> SET age = age -10
...> WHERE age IN (SELECT age FROM person
...> WHERE age > 30);
sqlite> select * from person;
ID name age
---------- ---------- ----------
1 Paul 22
6 Kim 22
子查询可以与 DELETE 语句结合使用,就像上面提到的其他语句一样。
基本语法如下:
DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
(SELECT COLUMN_NAME
FROM TABLE_NAME)
[ WHERE) ]
例:
sqlite> DELETE FROM person
...> WHERE age IN (SELECT age FROM person
...> WHERE age > 20);
sqlite> select * from person;
sqlite>
SQLite 的 AUTOINCREMENT 是一个关键字,用于表中的字段值自动递增。我们可以在创建表时在特定的列名称上使用 AUTOINCREMENT 关键字实现该字段值的自动增加。
关键字 AUTOINCREMENT 只能用于整型(INTEGER)字段。
AUTOINCREMENT 关键字的基本用法如下:
CREATE TABLE table_name(
column1 INTEGER AUTOINCREMENT,
column2 datatype,
column3 datatype,
.....
columnN datatype,
);
例:
sqlite> INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
...> VALUES ( 'Paul', 32, 'California', 20000.00 );
sqlite> INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
...> VALUES ( 'Allen', 25, 'Texas', 15000.00 );
sqlite> INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
...> VALUES ( 'Mark', 25, 'Rich-Mond', 65000.00 );
sqlite> select * from company;
ID NAME AGE ADDRESS SALARY
---------- ---------- ---------- ---------- ----------
1 Paul 32 California 20000.0
2 Allen 25 Texas 15000.0
3 Mark 25 Rich-Mond 65000.0
SQLite 支持以下五个日期和时间函数:
函数 | 实例 |
---|---|
date(timestring, modifier, modifier, …) | 以 YYYY-MM-DD 格式返回日期。 |
time(timestring, modifier, modifier, …) | 以 HH:MM:SS 格式返回时间。 |
datetime(timestring, modifier, modifier, …) | 以 YYYY-MM-DD HH:MM:SS 格式返回。 |
julianday(timestring, modifier, modifier, …) | 这将返回从格林尼治时间的公元前 4714 年 11 月 24 日正午算起的天数。 |
strftime(format, timestring, modifier, modifier, …) | 这将根据第一个参数指定的格式字符串返回格式化的日期。具体格式见下边讲解。 |
上述五个日期和时间函数把时间字符串作为参数。时间字符串后跟零个或多个 modifier 修饰符。strftime() 函数也可以把格式字符串 format 作为其第一个参数。下面将为您详细讲解不同类型的时间字符串和修饰符。
一个时间字符串可以采用下面任何一种格式:
时间字符串 | 实例 |
---|---|
YYYY-MM-DD | 2010-12-30 |
YYYY-MM-DD HH:MM | 2010-12-30 12:10 |
YYYY-MM-DD HH:MM:SS.SSS | 2010-12-30 12:10:04.100 |
MM-DD-YYYY HH:MM | 30-12-2010 12:10 |
HH:MM | 12:10 |
YYYY-MM-DDTHH:MM | 2010-12-30 12:10 |
HH:MM:SS | 12:10:01 |
YYYYMMDD HHMMSS | 20101230 121001 |
now | 2013-05-07 |
注:可以使用 “T” 作为分隔日期和时间的文字字符。
时间字符串后边可跟着零个或多个的修饰符,这将改变由上述五个函数返回的日期和/或时间。任何上述五大功能返回时间时,修饰符应从左到右使用。
下面列出了可在 SQLite 中使用的修饰符:
SQLite 提供了非常方便的函数 strftime() 来格式化任何日期和时间。可以使用以下的替换来格式化日期和时间:
替换 | 描述 |
---|---|
%d | 一月中的第几天,01-31 |
%f | 带小数部分的秒,SS.SSS |
%H | 小时,00-23 |
%j | 一年中的第几天,001-366 |
%J | 儒略日数,DDDD.DDDD |
%m | 月,00-12 |
%M | 分,00-59 |
%s | 从 1970-01-01 算起的秒数 |
%S | 秒,00-59 |
%w | 一周中的第几天,0-6 (0 is Sunday) |
%W | 一年中的第几周,01-53 |
%Y | 年,YYYY |
%% | % symbol |
例:
sqlite> SELECT date('now');
2018-10-29
sqlite> SELECT time('now');
07:14:27
sqlite> SELECT datetime('now');
2018-10-29 07:17:33
sqlite> SELECT datetime('now', 'localtime');
2018-10-29 15:21:03
sqlite> SELECT time('12.00', 'utc');
04:00:00
sqlite> SELECT time('12.00', 'localtime');
20:00:00
SQLite 有许多内置函数用于处理字符串或数字数据。下面列出了一些有用的 SQLite 内置函数,且所有函数都是大小写不敏感,这意味着您可以使用这些函数的小写形式或大写形式或混合形式。
函数 | 描述 |
---|---|
COUNT | COUNT 聚集函数是用来计算一个数据库表中的行数。 |
MAX | MAX 聚合函数允许我们选择某列的最大值。 |
MIN | MIN 聚合函数允许我们选择某列的最小值。 |
AVG | AVG 聚合函数计算某列的平均值。 |
SUM | SUM 聚合函数允许为一个数值列计算总和。 |
RANDOM | RANDOM 函数返回一个介于 -9223372036854775808 和 +9223372036854775807 之间的伪随机整数。 |
ABS | ABS 函数返回数值参数的绝对值。 |
UPPER | UPPER 函数把字符串转换为大写字母。 |
LOWER | LOWER 函数把字符串转换为小写字母。 |
LENGTH | LENGTH 函数返回字符串的长度。 |
SQLite COUNT 聚集函数是用来计算一个数据库表中的行数。
sqlite> select COUNT(*) FROM company;
COUNT(*)
----------
3
sqlite> select COUNT() FROM company;
COUNT()
----------
3
SQLite MAX 聚合函数允许我们选择某列的最大值。
sqlite> select MAX(age) FROM company;
MAX(age)
----------
32
sqlite> select MAX(ID) FROM company;
MAX(ID)
----------
3
SQLite MIN 聚合函数允许我们选择某列的最小值。
sqlite> select MIN(age) FROM company;
MIN(age)
----------
25
SQLite AVG 聚合函数计算某列的平均值。
sqlite> select AVG(age) FROM company;
AVG(age)
----------------
27.3333333333333
SQLite SUM 聚合函数允许为一个数值列计算总和。
sqlite> select SUM(age) FROM company;
SUM(age)
----------
82
SQLite RANDOM 函数返回一个介于 -9223372036854775808 和 +9223372036854775807 之间的伪随机整数。
sqlite> SELECT RANDOM();
RANDOM()
--------------------
-2190614641119678012
sqlite> SELECT RANDOM() AS Random;
Random
-------------------
-168337340808358512
SQLite ABS 函数返回数值参数的绝对值。
sqlite> select ABS(-1);
ABS(-1)
----------
1
sqlite> select ABS(-1) AS abs;
abs
----------
1
SQLite UPPER 函数把字符串转换为大写字母。
sqlite> SELECT UPPER(name) FROM COMPANY;
UPPER(name)
-----------
PAUL
ALLEN
MARK
sqlite> SELECT UPPER(name) AS upper_name FROM COMPANY;
upper_name
----------
PAUL
ALLEN
MARK
SQLite LOWER 函数把字符串转换为小写字母。
sqlite> SELECT LOWER(name) FROM COMPANY;
LOWER(name)
-----------
paul
allen
mark
sqlite> SELECT LOWER(name) AS lower_name FROM COMPANY;
lower_name
----------
paul
allen
mark
SQLite LENGTH 函数返回字符串的长度。
sqlite> SELECT LENGTH(name) FROM company;
LENGTH(name)
------------
4
5
4
sqlite> SELECT name,LENGTH(name) AS length_of_name FROM company;
NAME length_of_name
---------- --------------
Paul 4
Allen 5
Mark 4