- SQLite 教程
- SQLite - 首页
- SQLite - 概述
- SQLite - 安装
- SQLite - 命令
- SQLite - 语法
- SQLite - 数据类型
- SQLite - 创建数据库 (CREATE Database)
- SQLite - 附加数据库 (ATTACH Database)
- SQLite - 分离数据库 (DETACH Database)
- SQLite - 创建表 (CREATE Table)
- SQLite - 删除表 (DROP Table)
- SQLite - INSERT 查询
- SQLite - SELECT 查询
- SQLite - 运算符
- SQLite - 表达式
- SQLite - WHERE 子句
- SQLite - AND & OR 子句
- SQLite - UPDATE 查询
- SQLite - DELETE 查询
- SQLite - LIKE 子句
- SQLite - GLOB 子句
- SQLite - LIMIT 子句
- SQLite - ORDER By 子句
- SQLite - GROUP By 子句
- SQLite - HAVING 子句
- SQLite - DISTINCT 关键字
- 高级 SQLite
- SQLite - PRAGMA
- SQLite - 约束
- SQLite - 连接 (JOINS)
- SQLite - UNION 子句
- SQLite - NULL 值
- SQLite - 别名语法 (ALIAS Syntax)
- SQLite - 触发器 (Triggers)
- SQLite - 索引 (Indexes)
- SQLite - INDEXED BY 子句
- SQLite - ALTER 命令
- SQLite - TRUNCATE 命令
- SQLite - 视图 (Views)
- SQLite - 事务 (Transactions)
- SQLite - 子查询 (Subqueries)
- SQLite - AUTOINCREMENT
- SQLite - 注入 (Injection)
- SQLite - EXPLAIN
- SQLite - VACUUM
- SQLite - 日期和时间 (Date & Time)
- SQLite - 有用函数
- SQLite 有用资源
- SQLite 快速指南
- SQLite 有用资源
- SQLite - 讨论
SQLite 快速指南
SQLite - 概述
本章帮助您了解什么是 SQLite,它与 SQL 的区别,为什么需要它以及它处理应用程序数据库的方式。
SQLite 是一个软件库,它实现了一个自包含的、无服务器的、零配置的、事务性 SQL 数据库引擎。SQLite 是增长最快的数据库引擎之一,但这指的是流行程度的增长,与它的规模无关。SQLite 的源代码是公共领域的。
什么是 SQLite?
SQLite 是一个进程内库,它实现了一个自包含的、无服务器的、零配置的、事务性 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不同,您不需要在系统中配置它。
SQLite 引擎不像其他数据库那样是一个独立的进程,您可以根据需要静态或动态地将其链接到您的应用程序。SQLite 直接访问其存储文件。
为什么选择 SQLite?
SQLite 不需要单独的服务器进程或系统来运行(无服务器)。
SQLite 是零配置的,这意味着不需要设置或管理。
完整的 SQLite 数据库存储在一个单一的跨平台磁盘文件中。
SQLite 非常小巧轻便,完全配置后不到 400KiB,省略可选功能后不到 250KiB。
SQLite 是自包含的,这意味着没有外部依赖项。
SQLite 事务完全符合 ACID 规范,允许从多个进程或线程安全访问。
SQLite 支持 SQL92 (SQL2) 标准中大多数查询语言功能。
SQLite 使用 ANSI-C 编写,并提供简单易用的 API。
SQLite 可用于 UNIX(Linux、Mac OS-X、Android、iOS)和 Windows(Win32、WinCE、WinRT)。
SQLite 简史
2000 年 - D. Richard Hipp 为无需管理即可运行程序的目的设计了 SQLite。
2000 年 - 8 月,SQLite 1.0 与 GNU 数据库管理器一起发布。
2011 年 - Hipp 宣布向 SQLite 数据库添加 UNQl 接口并开发 UNQLite(面向文档的数据库)。
SQLite 限制
SQLite 中有一些 SQL92 的不支持的功能,列在下面的表格中。
序号 | 功能及描述 |
---|---|
1 | RIGHT OUTER JOIN 仅实现 LEFT OUTER JOIN。 |
2 | FULL OUTER JOIN 仅实现 LEFT OUTER JOIN。 |
3 | ALTER TABLE 支持 ALTER TABLE 命令的 RENAME TABLE 和 ADD COLUMN 变体。不支持 DROP COLUMN、ALTER COLUMN、ADD CONSTRAINT。 |
4 | 触发器支持 支持 FOR EACH ROW 触发器,但不支持 FOR EACH STATEMENT 触发器。 |
5 | 视图 (VIEWs) SQLite 中的视图是只读的。您不能对视图执行 DELETE、INSERT 或 UPDATE 语句。 |
6 | GRANT 和 REVOKE 唯一可以应用的访问权限是底层操作系统的普通文件访问权限。 |
SQLite 命令
与关系数据库交互的标准 SQLite 命令类似于 SQL。它们是 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。这些命令可以根据其操作性质分为几组:
DDL - 数据定义语言
序号 | 命令及描述 |
---|---|
1 | CREATE 在数据库中创建一个新表、表的视图或其他对象。 |
2 | ALTER 修改现有的数据库对象,例如表。 |
3 | DROP 删除数据库中的整个表、表的视图或其他对象。 |
DML - 数据操纵语言
序号 | 命令及描述 |
---|---|
1 | INSERT 创建记录 |
2 | UPDATE 修改记录 |
3 | DELETE 删除记录 |
DQL - 数据查询语言
序号 | 命令及描述 |
---|---|
1 | SELECT 从一个或多个表中检索某些记录 |
SQLite - 安装
SQLite 以其出色的零配置功能而闻名,这意味着不需要复杂的设置或管理。本章将引导您完成在 Windows、Linux 和 Mac OS X 上设置 SQLite 的过程。
在 Windows 上安装 SQLite
**步骤 1** - 前往 SQLite 下载页面,从 Windows 部分下载预编译的二进制文件。
**步骤 2** - 下载 sqlite-shell-win32-*.zip 和 sqlite-dll-win32-*.zip 压缩文件。
**步骤 3** - 创建一个文件夹 C:\>sqlite 并将上述两个压缩文件解压到此文件夹中,这将为您提供 sqlite3.def、sqlite3.dll 和 sqlite3.exe 文件。
**步骤 4** - 将 C:\>sqlite 添加到您的 PATH 环境变量中,最后转到命令提示符并发出 sqlite3 命令,这应该显示以下结果。
C:\>sqlite3 SQLite version 3.7.15.2 2013-01-09 11:53:05 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite>
在 Linux 上安装 SQLite
如今,几乎所有 Linux 操作系统都自带 SQLite。因此,您只需发出以下命令即可检查您的机器上是否已安装 SQLite。
$sqlite3 SQLite version 3.7.15.2 2013-01-09 11:53:05 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite>
如果您没有看到以上结果,则表示您的 Linux 机器上没有安装 SQLite。以下是安装 SQLite 的步骤:
**步骤 1** - 前往 SQLite 下载页面,从源代码部分下载 sqlite-autoconf-*.tar.gz。
**步骤 2** - 运行以下命令:
$tar xvfz sqlite-autoconf-3071502.tar.gz $cd sqlite-autoconf-3071502 $./configure --prefix=/usr/local $make $make install
以上命令将在您的 Linux 机器上完成 SQLite 的安装。您可以按照上面说明的方法进行验证。
在 Mac OS X 上安装 SQLite
尽管最新版本的 Mac OS X 预装了 SQLite,但如果您没有安装,只需按照以下步骤操作:
**步骤 1** - 前往 SQLite 下载页面,从源代码部分下载 sqlite-autoconf-*.tar.gz。
**步骤 2** - 运行以下命令:
$tar xvfz sqlite-autoconf-3071502.tar.gz $cd sqlite-autoconf-3071502 $./configure --prefix=/usr/local $make $make install
上述过程将在您的 Mac OS X 机器上完成 SQLite 的安装。您可以通过发出以下命令来验证:
$sqlite3 SQLite version 3.7.15.2 2013-01-09 11:53:05 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite>
最后,您将拥有 SQLite 命令提示符,您可以在其中为您的练习发出 SQLite 命令。
SQLite - 命令
本章将引导您了解 SQLite 程序员使用的简单且有用的命令。这些命令称为 SQLite 点命令,除了这些命令之外,它们不应该以分号 (;) 结尾。
让我们从在命令提示符下键入简单的 **sqlite3** 命令开始,这将为您提供 SQLite 命令提示符,您可以在其中发出各种 SQLite 命令。
$sqlite3 SQLite version 3.3.6 Enter ".help" for instructions sqlite>
要列出可用的点命令,您可以随时输入“.help”。例如:
sqlite>.help
以上命令将显示各种重要的 SQLite 点命令列表,这些命令列在下表中。
序号 | 命令及描述 |
---|---|
1 | .backup ?DB? FILE 将数据库 (默认为“main”) 备份到 FILE |
2 | .bail ON|OFF 遇到错误后停止。默认为 OFF |
3 | .databases 列出已附加数据库的名称和文件 |
4 | .dump ?TABLE? 以 SQL 文本格式转储数据库。如果指定了 TABLE,则只转储与 LIKE 模式 TABLE 匹配的表 |
5 | .echo ON|OFF 打开或关闭命令回显 |
6 | .exit 退出 SQLite 提示符 |
7 | .explain ON|OFF 打开或关闭适合 EXPLAIN 的输出模式。无参数时,它打开 EXPLAIN |
8 | .header(s) ON|OFF 打开或关闭标题的显示 |
9 | .help 显示此消息 |
10 | .import FILE TABLE 将数据从 FILE 导入 TABLE |
11 | .indices ?TABLE? 显示所有索引的名称。如果指定了 TABLE,则仅显示与 LIKE 模式 TABLE 匹配的表的索引 |
12 | .load FILE ?ENTRY? 加载扩展库 |
13 | .log FILE|off 打开或关闭日志记录。FILE 可以是 stderr/stdout |
14 | .mode MODE 设置输出模式,其中 MODE 为以下之一:
|
15 | .nullvalue STRING 用 STRING 代替 NULL 值 |
16 | .output FILENAME 将输出发送到 FILENAME |
17 | .output stdout 将输出发送到屏幕 |
18 | .print STRING... 打印文字字符串 |
19 | .prompt MAIN CONTINUE 替换标准提示符 |
20 | .quit 退出 SQLite 提示符 |
21 | .read FILENAME 执行 FILENAME 中的 SQL |
22 | .schema ?TABLE? 显示 CREATE 语句。如果指定了 TABLE,则只显示与 LIKE 模式 TABLE 匹配的表的 CREATE 语句 |
23 | .separator STRING 更改输出模式和 .import 使用的分隔符 |
24 | .show 显示各种设置的当前值 |
25 | .stats ON|OFF 启用或禁用统计信息 |
26 | .tables ?PATTERN? 列出与 LIKE 模式匹配的表名 |
27 | .timeout MS 尝试打开被锁定的表,持续时间为 MS 毫秒 |
28 | .width NUM NUM 设置“列”模式下的列宽 |
29 | .timer ON|OFF 启用或禁用 CPU 计时器测量 |
让我们尝试使用 .show 命令查看 SQLite 命令提示符的默认设置。
sqlite>.show echo: off explain: off headers: off mode: column nullvalue: "" output: stdout separator: "|" width: sqlite>
确保 sqlite> 提示符和点命令之间没有空格,否则将无法正常工作。
格式化输出
您可以使用以下一系列点命令来格式化输出。
sqlite>.header on sqlite>.mode column sqlite>.timer on sqlite>
上述设置将产生以下格式的输出。
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 CPU Time: user 0.000000 sys 0.000000
sqlite_master 表
主表保存有关数据库表的关键信息,其名称为 sqlite_master。您可以按如下方式查看其模式:
sqlite>.schema sqlite_master
这将产生以下结果。
CREATE TABLE sqlite_master ( type text, name text, tbl_name text, rootpage integer, sql text );
SQLite - 语法
SQLite 遵循一组独特的规则和指南,称为语法。本章列出了所有基本的 SQLite 语法。
大小写敏感性
需要注意的重要一点是,SQLite **不区分大小写**,但是有一些命令区分大小写,例如 **GLOB** 和 **glob** 在 SQLite 语句中具有不同的含义。
注释
SQLite 注释是您可以添加到 SQLite 代码中的额外说明,以提高其可读性,它们可以出现在任何地方;允许出现空格,包括表达式内部和其它 SQL 语句的中间,但它们不能嵌套。
SQL 注释以两个连续的“-”字符(ASCII 0x2d)开头,一直延伸到下一个换行符(ASCII 0x0a)或输入结束,以先到者为准。
您也可以使用 C 样式注释,它们以“/*”开头,一直延伸到下一个“*/”字符对或输入结束,以先到者为准。C 样式注释可以跨多行。
sqlite> .help -- This is a single line comment
SQLite 语句
所有 SQLite 语句都以 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP 等关键字中的任何一个开头,并且所有语句都以分号 (;) 结尾。
SQLite ANALYZE 语句
ANALYZE; or ANALYZE database_name; or ANALYZE database_name.table_name;
SQLite AND/OR 子句
SELECT column1, column2....columnN FROM table_name WHERE CONDITION-1 {AND|OR} CONDITION-2;
SQLite ALTER TABLE 语句
ALTER TABLE table_name ADD COLUMN column_def...;
SQLite ALTER TABLE 语句(重命名)
ALTER TABLE table_name RENAME TO new_table_name;
SQLite ATTACH DATABASE 语句
ATTACH DATABASE 'DatabaseName' As 'Alias-Name';
SQLite BEGIN TRANSACTION 语句
BEGIN; or BEGIN EXCLUSIVE TRANSACTION;
SQLite BETWEEN 子句
SELECT column1, column2....columnN FROM table_name WHERE column_name BETWEEN val-1 AND val-2;
SQLite COMMIT 语句
COMMIT;
SQLite CREATE INDEX 语句
CREATE INDEX index_name ON table_name ( column_name COLLATE NOCASE );
SQLite CREATE UNIQUE INDEX 语句
CREATE UNIQUE INDEX index_name ON table_name ( column1, column2,...columnN);
SQLite CREATE TABLE 语句
CREATE TABLE table_name( column1 datatype, column2 datatype, column3 datatype, ..... columnN datatype, PRIMARY KEY( one or more columns ) );
SQLite CREATE TRIGGER 语句
CREATE TRIGGER database_name.trigger_name BEFORE INSERT ON table_name FOR EACH ROW BEGIN stmt1; stmt2; .... END;
SQLite CREATE VIEW 语句
CREATE VIEW database_name.view_name AS SELECT statement....;
SQLite CREATE VIRTUAL TABLE 语句
CREATE VIRTUAL TABLE database_name.table_name USING weblog( access.log ); or CREATE VIRTUAL TABLE database_name.table_name USING fts3( );
SQLite COMMIT TRANSACTION 语句
COMMIT;
SQLite COUNT 子句
SELECT COUNT(column_name) FROM table_name WHERE CONDITION;
SQLite DELETE 语句
DELETE FROM table_name WHERE {CONDITION};
SQLite DETACH DATABASE 语句
DETACH DATABASE 'Alias-Name';
SQLite DISTINCT 子句
SELECT DISTINCT column1, column2....columnN FROM table_name;
SQLite DROP INDEX 语句
DROP INDEX database_name.index_name;
SQLite DROP TABLE 语句
DROP TABLE database_name.table_name;
SQLite DROP VIEW 语句
DROP INDEX database_name.view_name;
SQLite DROP TRIGGER 语句
DROP INDEX database_name.trigger_name;
SQLite EXISTS 子句
SELECT column1, column2....columnN FROM table_name WHERE column_name EXISTS (SELECT * FROM table_name );
SQLite EXPLAIN 语句
EXPLAIN INSERT statement...; or EXPLAIN QUERY PLAN SELECT statement...;
SQLite GLOB 子句
SELECT column1, column2....columnN FROM table_name WHERE column_name GLOB { PATTERN };
SQLite GROUP BY 子句
SELECT SUM(column_name) FROM table_name WHERE CONDITION GROUP BY column_name;
SQLite HAVING 子句
SELECT SUM(column_name) FROM table_name WHERE CONDITION GROUP BY column_name HAVING (arithematic function condition);
SQLite INSERT INTO 语句
INSERT INTO table_name( column1, column2....columnN) VALUES ( value1, value2....valueN);
SQLite IN 子句
SELECT column1, column2....columnN FROM table_name WHERE column_name IN (val-1, val-2,...val-N);
SQLite Like 子句
SELECT column1, column2....columnN FROM table_name WHERE column_name LIKE { PATTERN };
SQLite NOT IN 子句
SELECT column1, column2....columnN FROM table_name WHERE column_name NOT IN (val-1, val-2,...val-N);
SQLite ORDER BY 子句
SELECT column1, column2....columnN FROM table_name WHERE CONDITION ORDER BY column_name {ASC|DESC};
SQLite PRAGMA 语句
PRAGMA pragma_name; For example: PRAGMA page_size; PRAGMA cache_size = 1024; PRAGMA table_info(table_name);
SQLite RELEASE SAVEPOINT 语句
RELEASE savepoint_name;
SQLite REINDEX 语句
REINDEX collation_name; REINDEX database_name.index_name; REINDEX database_name.table_name;
SQLite ROLLBACK 语句
ROLLBACK; or ROLLBACK TO SAVEPOINT savepoint_name;
SQLite SAVEPOINT 语句
SAVEPOINT savepoint_name;
SQLite SELECT 语句
SELECT column1, column2....columnN FROM table_name;
SQLite UPDATE 语句
UPDATE table_name SET column1 = value1, column2 = value2....columnN=valueN [ WHERE CONDITION ];
SQLite VACUUM 语句
VACUUM;
SQLite WHERE 子句
SELECT column1, column2....columnN FROM table_name WHERE CONDITION;
SQLite - 数据类型
SQLite 数据类型是一个属性,它指定任何对象的数 据类型。SQLite 中的每个列、变量和表达式都具有相关的数据类型。
创建表时会使用这些数据类型。SQLite 使用更通用的动态类型系统。在 SQLite 中,值的数 据类型与其自身相关联,而不是与其容器相关联。
SQLite 存储类
存储在 SQLite 数据库中的每个值都具有以下存储类之一:
序号 | 存储类和说明 |
---|---|
1 | NULL 该值为 NULL 值。 |
2 | INTEGER 该值为带符号整数,存储在 1、2、3、4、6 或 8 字节中,具体取决于值的量级。 |
3 | REAL 该值为浮点值,存储为 8 字节 IEEE 浮点数。 |
4 | TEXT 该值为文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。 |
5 | BLOB 该值为数据块,按输入时的原样存储。 |
SQLite 存储类略微比数据类型更通用。例如,INTEGER 存储类包含 6 种不同长度的不同整数数据类型。
SQLite 亲和类型
SQLite 支持列上的**类型亲和性**概念。任何列仍然可以存储任何类型的数据,但是列的首选存储类称为其**亲和性**。SQLite3 数据库中的每个表列都分配有以下类型亲和性之一:
序号 | 亲和性和说明 |
---|---|
1 | TEXT TEXT |
2 | NUMERIC 此列可以包含使用所有五种存储类的值。 |
3 | INTEGER INTEGER |
4 | REAL 其行为与具有 NUMERIC 亲和性的列相同,但 CAST 表达式中除外。 |
5 | REAL 其行为类似于具有 NUMERIC 亲和性的列,但它会将整数值强制转换为浮点表示形式。 |
NONE
亲和性为 NONE 的列不偏向任何存储类,并且不会尝试将数据从一种存储类强制转换为另一种存储类。
SQLite 亲和性和类型名称 | 下表列出了创建 SQLite3 表时可以使用的各种数据类型名称及其对应的应用亲和性。 |
---|---|
|
INTEGER |
|
TEXT |
|
REAL |
|
REAL |
|
NUMERIC |
DATE
DATETIME
布尔数据类型
SQLite 没有单独的布尔存储类。布尔值存储为整数 0(false)和 1(true)。
序号 | 日期和时间数据类型 |
---|---|
1 | TEXT SQLite 没有单独的存储类来存储日期和/或时间,但是 SQLite 能够将日期和时间存储为 TEXT、REAL 或 INTEGER 值。 |
2 | REAL 存储类和日期格式 |
3 | INTEGER TEXT |
类似“YYYY-MM-DD HH:MM:SS.SSS”的日期格式
SQLite - 创建数据库 (CREATE Database)
REAL
公元前 4714 年 11 月 24 日中午以来的天数
INTEGER
$sqlite3 DatabaseName.db
自 1970-01-01 00:00:00 UTC 以来的秒数
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
在 SQLite 中,使用sqlite3命令创建新的 SQLite 数据库。创建数据库不需要任何特殊权限。
$sqlite3 testDB.db SQLite version 3.7.15.2 2013-01-09 11:53:05 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite>
语法
以下是用于创建数据库的 sqlite3 命令的基本语法:
sqlite>.databases seq name file --- --------------- ---------------------- 0 main /home/sqlite/testDB.db
数据库名称在 RDBMS 中始终应该是唯一的。
sqlite>.quit $
示例
如果要创建一个新的数据库 <testDB.db>,则 SQLITE3 语句如下:
$sqlite3 testDB.db .dump > testDB.sql
上述命令将在当前目录中创建一个名为testDB.db的文件。SQLite 引擎将使用此文件作为数据库。您可能已经注意到,在创建数据库时,sqlite3 命令在成功创建数据库文件后将提供一个sqlite>提示符。
$sqlite3 testDB.db < testDB.sql
创建数据库后,您可以使用以下 SQLite .databases 命令在数据库列表中验证它。
SQLite - 附加数据库 (ATTACH Database)
您可以使用 SQLite .quit 命令退出 sqlite 提示符,如下所示:
公元前 4714 年 11 月 24 日中午以来的天数
.dump 命令
ATTACH DATABASE 'DatabaseName' As 'Alias-Name';
您可以使用.dump点命令将完整数据库导出到文本文件,方法是在命令提示符下使用以下 SQLite 命令。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
上述命令会将testDB.db数据库的全部内容转换为 SQLite 语句,并将其转储到 ASCII 文本文件testDB.sql中。您可以简单地按如下方式从生成的 testDB.sql 中执行恢复:
sqlite> ATTACH DATABASE 'testDB.db' as 'TEST';
目前您的数据库是空的,因此您可以在数据库中添加一些表和数据后再尝试上述两个过程。现在,让我们继续下一章。
sqlite> .database seq name file --- --------------- ---------------------- 0 main /home/sqlite/testDB.db 2 test /home/sqlite/testDB.db
假设您有多个数据库可用,并且您希望一次使用其中的一个。SQLite ATTACH DATABASE 语句用于选择特定数据库,此命令之后,所有 SQLite 语句都将在附加的数据库下执行。
sqlite> ATTACH DATABASE 'testDB.db' as 'TEMP'; Error: database TEMP is already in use sqlite> ATTACH DATABASE 'testDB.db' as 'main'; Error: database TEMP is already in use
SQLite - 分离数据库 (DETACH Database)
以下是 SQLite ATTACH DATABASE 语句的基本语法。
如果数据库是内存数据库或临时数据库,则数据库将被销毁,其内容将丢失。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 SQLite DETACH DATABASE '别名' 语句的基本语法。
DETACH DATABASE 'Alias-Name';
这里,'别名' 是您在使用 ATTACH 语句附加数据库时使用的相同别名。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
假设您有一个数据库,您在上一章中创建了它,并使用 'test' 和 'currentDB' 附加了它,我们可以使用.database命令查看。
sqlite>.databases seq name file --- --------------- ---------------------- 0 main /home/sqlite/testDB.db 2 test /home/sqlite/testDB.db 3 currentDB /home/sqlite/testDB.db
让我们尝试使用以下命令从 testDB.db 中分离 'currentDB'。
sqlite> DETACH DATABASE 'currentDB';
现在,如果您检查当前附件,您会发现 testDB.db 仍然与 'test' 和 'main' 连接。
sqlite>.databases seq name file --- --------------- ---------------------- 0 main /home/sqlite/testDB.db 2 test /home/sqlite/testDB.db
SQLite - 创建表 (CREATE Table)
SQLite 的CREATE TABLE语句用于在任何给定的数据库中创建一个新表。创建基本表包括命名表和定义其列以及每列的数据类型。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 CREATE TABLE 语句的基本语法。
CREATE TABLE database_name.table_name( column1 datatype PRIMARY KEY(one or more columns), column2 datatype, column3 datatype, ..... columnN datatype );
CREATE TABLE 是告诉数据库系统创建一个新表的关键字。表的唯一名称或标识符位于 CREATE TABLE 语句之后。可以选择性地,您可以指定database_name以及table_name。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
以下是一个示例,它创建一个 COMPANY 表,其中 ID 是主键,NOT 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 );
让我们再创建一个表,我们将在后续章节的练习中使用它。
sqlite> CREATE TABLE DEPARTMENT( ID INT PRIMARY KEY NOT NULL, DEPT CHAR(50) NOT NULL, EMP_ID INT NOT NULL );
您可以使用 SQLite 命令.tables命令验证您的表是否已成功创建,该命令将用于列出附加数据库中的所有表。
sqlite>.tables COMPANY DEPARTMENT
在这里,您可以看到 COMPANY 表两次,因为它显示了主数据库的 COMPANY 表和为您的 testDB.db 创建的 'test' 别名的 test.COMPANY 表。您可以使用以下 SQLite.schema命令获取有关表的完整信息。
sqlite>.schema COMPANY CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
SQLite - 删除表 (DROP Table)
SQLite 的DROP TABLE语句用于删除表定义以及与该表关联的所有数据、索引、触发器、约束和权限规范。
使用此命令时必须小心,因为一旦表被删除,表中所有可用信息也将永远丢失。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 DROP TABLE 语句的基本语法。您可以选择性地指定数据库名称以及表名,如下所示:
DROP TABLE database_name.table_name;
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
让我们首先验证 COMPANY 表,然后将其从数据库中删除。
sqlite>.tables COMPANY test.COMPANY
这意味着 COMPANY 表存在于数据库中,因此让我们将其删除,如下所示:
sqlite>DROP TABLE COMPANY; sqlite>
现在,如果您尝试使用 .TABLES 命令,则将不再找到 COMPANY 表。
sqlite>.tables sqlite>
它什么也没有显示,这意味着数据库中的表已成功删除。
SQLite - INSERT 查询
SQLite 的INSERT INTO语句用于向数据库中的表中添加新的数据行。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 INSERT INTO 语句的两种基本语法。
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);
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
假设您已经在您的 testDB.db 中创建了 COMPANY 表,如下所示:
sqlite> 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 );
所有上述语句都将在 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 语句将数据填充到表中,前提是另一个表具有一组字段,这些字段是填充第一个表所需的。以下是语法:
INSERT INTO first_table_name [(column1, column2, ... columnN)] SELECT column1, column2, ...columnN FROM second_table_name [WHERE condition];
目前,您可以跳过上述语句。首先,让我们学习将在后续章节中介绍的 SELECT 和 WHERE 子句。
SQLite - SELECT 查询
SQLite 的SELECT语句用于从 SQLite 数据库表中提取数据,该数据以结果表的形式返回数据。这些结果表也称为结果集。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 SQLite SELECT 语句的基本语法。
SELECT column1, column2, columnN FROM table_name;
这里,column1、column2...是表的字段,您要提取其值。如果要提取字段中所有可用的字段,则可以使用以下语法:
SELECT * FROM table_name;
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的 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 语句提取和显示所有这些记录的示例。这里,前三个命令已用于设置格式正确的输出。
sqlite>.header on sqlite>.mode column 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 South-Hall 45000.0 7 James 24 Houston 10000.0
如果只想提取 COMPANY 表的选定字段,则使用以下查询:
sqlite> SELECT ID, NAME, SALARY FROM COMPANY;
上述查询将产生以下结果。
ID NAME SALARY ---------- ---------- ---------- 1 Paul 20000.0 2 Allen 15000.0 3 Teddy 20000.0 4 Mark 65000.0 5 David 85000.0 6 Kim 45000.0 7 James 10000.0
设置输出列宽
有时,在.mode column的情况下,您会遇到与输出被截断相关的问题,这是因为要显示的列的默认宽度造成的。您可以做的是,可以使用.width num, num....命令设置列的可显示列宽,如下所示:
sqlite>.width 10, 20, 10 sqlite>SELECT * FROM COMPANY;
上述.width命令将第一列宽度设置为 10,第二列宽度设置为 20,第三列宽度设置为 10。最后,上述 SELECT 语句将给出以下结果。
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
模式信息
由于所有点命令都可在 SQLite 提示符下使用,因此在使用 SQLite 编程时,您将使用以下 SELECT 语句和sqlite_master表列出数据库中创建的所有表。
sqlite> SELECT tbl_name FROM sqlite_master WHERE type = 'table';
假设您的 testDB.db 中只有 COMPANY 表,这将产生以下结果。
tbl_name ---------- COMPANY
您可以列出有关 COMPANY 表的完整信息,如下所示:
sqlite> SELECT sql FROM sqlite_master WHERE type = 'table' AND tbl_name = 'COMPANY';
假设您的 testDB.db 中只有 COMPANY 表,这将产生以下结果。
CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL )
SQLite - 运算符
什么是 SQLite 中的操作符?
操作符是一个保留字或字符,主要用于 SQLite 语句的 WHERE 子句中执行操作,例如比较和算术运算。
操作符用于在 SQLite 语句中指定条件,并用作语句中多个条件的连接词。
- 算术运算符
- 比较运算符
- 逻辑运算符
- 位运算符
SQLite 算术运算符
假设变量a持有 10,变量b持有 20,则 SQLite 算术运算符将按如下方式使用:
运算符 | 描述 | 您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。 |
---|---|---|
+ (加法) | 将运算符两侧的值相加 | a + b 将得到 30 |
- (减法) | 从左操作数中减去右操作数 | a - b 将得到 -10 |
* (乘法) | 将运算符两侧的值相乘 | a * b 将得到 200 |
/ (除法) | 将左操作数除以右操作数 | b / a 将得到 2 |
% (取模) | 将左操作数除以右操作数并返回余数 | b % a 将得到 0 |
SQLite 比较运算符
假设变量a持有 10,变量b持有 20,则 SQLite 比较运算符将按如下方式使用
运算符 | 描述 | 您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。 |
---|---|---|
== | 检查两个操作数的值是否相等,如果相等,则条件变为真。 | (a == b) 为假。 |
= | 检查两个操作数的值是否相等,如果相等,则条件变为真。 | (a = b) 为假。 |
!= | 检查两个操作数的值是否相等,如果不相等,则条件变为真。 | (a != b) 为真。 |
<> | 检查两个操作数的值是否相等,如果不相等,则条件变为真。 | (a <> b) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是,则条件变为真。 | (a > b) 为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是,则条件变为真。 | (a < b) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件变为真。 | (a >= b) 为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件变为真。 | (a <= b) 为真。 |
!< | 检查左操作数的值是否不小于右操作数的值,如果是,则条件变为真。 | (a !< b) 为假。 |
!> | 检查左操作数的值是否不大于右操作数的值,如果是,则条件变为真。 | (a !> b) 为真。 |
SQLite 逻辑运算符
以下是 SQLite 中所有可用逻辑运算符的列表。
序号 | 运算符和说明 |
---|---|
1 | AND AND 运算符允许 SQL 语句的 WHERE 子句中存在多个条件。 |
2 | BETWEEN BETWEEN 运算符用于搜索在给定最小值和最大值的一组值内的值。 |
3 | EXISTS EXISTS 运算符用于搜索指定表中满足某些条件的行是否存在。 |
4 | IN IN 运算符用于将值与已指定的文字值列表进行比较。 |
5 | NOT IN IN 运算符的反义词,用于将值与已指定的文字值列表进行比较。 |
6 | LIKE LIKE 运算符用于使用通配符运算符将值与类似的值进行比较。 |
7 | GLOB GLOB 运算符用于使用通配符运算符将值与类似的值进行比较。此外,与 LIKE 不同,GLOB 区分大小写。 |
8 | NOT NOT 运算符反转与其一起使用的逻辑运算符的含义。例如 NOT EXISTS、NOT BETWEEN、NOT IN 等。这是否定运算符。 |
9 | OR OR 运算符用于在 SQL 语句的 WHERE 子句中组合多个条件。 |
10 | IS NULL NULL 运算符用于将值与 NULL 值进行比较。 |
11 | IS IS 运算符的工作方式与 = 相同 |
12 | IS NOT IS 运算符的工作方式与 != 相同 |
13 | || 将两个不同的字符串相加并创建一个新的字符串。 |
14 | UNIQUE UNIQUE 运算符搜索指定表中的每一行以查找唯一性(无重复项)。 |
SQLite 位运算符
位运算符对位进行运算并执行逐位运算。以下是&和|的真值表。
p | q | p & q | p | q |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 |
1 | 0 | 0 | 1 |
假设A = 60;和B = 13,则以二进制格式,它们将如下所示:
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
~A = 1100 0011
SQLite语言支持的位运算符列在下面的表格中。假设变量A的值为60,变量B的值为13,则:
运算符 | 描述 | 您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。 |
---|---|---|
& | 二进制与运算符:如果一个位同时存在于两个操作数中,则将其复制到结果中。 | (A & B) 将得到 12,其二进制表示为 0000 1100 |
| | 二进制或运算符:如果一个位存在于任一操作数中,则将其复制到结果中。 | (A | B) 将得到 61,其二进制表示为 0011 1101 |
~ | 二进制非运算符:这是一元运算符,其作用是“翻转”位。 | (~A) 将得到 -61,由于是带符号二进制数,因此其二进制补码形式为 1100 0011 |
<< | 二进制左移运算符:左操作数的值向左移动由右操作数指定的位数。 | A << 2 将得到 240,其二进制表示为 1111 0000 |
>> | 二进制右移运算符:左操作数的值向右移动由右操作数指定的位数。 | A >> 2 将得到 15,其二进制表示为 0000 1111 |
SQLite - 表达式
表达式是由一个或多个值、运算符和SQL函数组合而成,最终计算出一个值。
SQL表达式就像公式一样,它们是用查询语言编写的。你也可以用它来查询数据库中的特定数据集。
公元前 4714 年 11 月 24 日中午以来的天数
考虑SELECT语句的基本语法如下:
SELECT column1, column2, columnN FROM table_name WHERE [CONDITION | EXPRESSION];
以下是不同类型的SQLite表达式。
SQLite - 布尔表达式
SQLite布尔表达式根据匹配单个值来获取数据。语法如下:
SELECT column1, column2, columnN FROM table_name WHERE SINGLE VALUE MATCHTING EXPRESSION;
考虑具有以下记录的 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
以下是一个简单的例子,展示了SQLite布尔表达式的用法:
sqlite> SELECT * FROM COMPANY WHERE SALARY = 10000; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 James 24 Houston 10000.0
SQLite - 数值表达式
这些表达式用于在任何查询中执行任何数学运算。语法如下:
SELECT numerical_expression as OPERATION_NAME [FROM table_name WHERE CONDITION] ;
这里,numerical_expression 用于数学表达式或任何公式。以下是一个简单的例子,展示了SQLite数值表达式的用法。
sqlite> SELECT (15 + 6) AS ADDITION ADDITION = 21
有一些内置函数,例如avg()、sum()、count()等,用于对表或特定表列执行所谓的聚合数据计算。
sqlite> SELECT COUNT(*) AS "RECORDS" FROM COMPANY; RECORDS = 7
SQLite - 日期表达式
日期表达式返回当前系统日期和时间值。这些表达式用于各种数据操作。
sqlite> SELECT CURRENT_TIMESTAMP; CURRENT_TIMESTAMP = 2013-03-17 10:43:35
SQLite - WHERE 子句
SQLite 的WHERE子句用于在从一个或多个表中获取数据时指定条件。
如果给定的条件满足,即为真,则它将返回表中的特定值。你必须使用WHERE子句来过滤记录,只获取必要的记录。
WHERE子句不仅用于SELECT语句,也用于UPDATE、DELETE语句等,这些将在后续章节中介绍。
公元前 4714 年 11 月 24 日中午以来的天数
以下是带有WHERE子句的SQLite SELECT语句的基本语法。
SELECT column1, column2, columnN FROM table_name WHERE [condition]
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
你可以使用比较运算符或逻辑运算符,例如>、<、=、LIKE、NOT等来指定条件。考虑具有以下记录的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
以下是一个简单的例子,展示了SQLite逻辑运算符的用法。以下SELECT语句列出了所有年龄大于或等于25并且工资大于或等于65000.00的记录。
sqlite> SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
以下SELECT语句列出了所有年龄大于或等于25或者工资大于或等于65000.00的记录。
sqlite> SELECT * FROM COMPANY WHERE AGE >= 25 OR SALARY >= 65000; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
以下SELECT语句列出了所有年龄不为NULL的记录,这意味着所有记录,因为没有记录的年龄等于NULL。
sqlite> SELECT * FROM COMPANY WHERE AGE 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 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
以下SELECT语句列出了所有名称以“Ki”开头的记录,不管“Ki”之后是什么。
sqlite> SELECT * FROM COMPANY WHERE NAME LIKE 'Ki%'; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 6 Kim 22 South-Hall 45000.0
以下SELECT语句列出了所有名称以“Ki”开头的记录,不管“Ki”之后是什么。
sqlite> SELECT * FROM COMPANY WHERE NAME GLOB 'Ki*'; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 6 Kim 22 South-Hall 45000.0
以下SELECT语句列出了年龄为25或27的所有记录。
sqlite> SELECT * FROM COMPANY WHERE AGE IN ( 25, 27 ); ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
以下SELECT语句列出了年龄既不是25也不是27的所有记录。
sqlite> SELECT * FROM COMPANY WHERE AGE NOT IN ( 25, 27 ); ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 3 Teddy 23 Norway 20000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
以下SELECT语句列出了年龄在25到27之间的所有记录。
sqlite> SELECT * FROM COMPANY WHERE AGE BETWEEN 25 AND 27; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
以下SELECT语句使用了SQL子查询,子查询查找SALARY > 65000的AGE字段的所有记录,然后WHERE子句与EXISTS运算符一起使用,列出外部查询中的AGE存在于子查询返回的结果中的所有记录:
sqlite> SELECT AGE FROM COMPANY WHERE EXISTS (SELECT AGE FROM COMPANY WHERE SALARY > 65000); AGE ---------- 32 25 23 25 27 22 24
以下SELECT语句使用了SQL子查询,子查询查找SALARY > 65000的AGE字段的所有记录,然后WHERE子句与>运算符一起使用,列出外部查询中的AGE大于子查询返回的结果中的年龄的所有记录。
sqlite> SELECT * FROM COMPANY WHERE AGE > (SELECT AGE FROM COMPANY WHERE SALARY > 65000); ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0
SQLite - AND & OR 运算符
SQLite 的AND & OR 运算符用于组合多个条件,以缩小SQLite语句中选择的数据范围。这两个运算符被称为连接运算符。
这些运算符提供了一种方法,可以在同一个SQLite语句中使用不同的运算符进行多个比较。
AND 运算符
AND运算符允许在SQLite语句的WHERE子句中存在多个条件。使用AND运算符时,只有当所有条件都为真时,整个条件才被认为是真。例如,[condition1] AND [condition2] 只有当condition1和condition2都为真时才为真。
公元前 4714 年 11 月 24 日中午以来的天数
以下是带有WHERE子句的AND运算符的基本语法。
SELECT column1, column2, columnN FROM table_name WHERE [condition1] AND [condition2]...AND [conditionN];
你可以使用AND运算符组合N个条件。对于SQLite语句要执行的操作,无论是事务还是查询,所有由AND分隔的条件都必须为TRUE。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的 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语句列出了所有年龄大于或等于25并且工资大于或等于65000.00的记录。
sqlite> SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
OR 运算符
OR运算符也用于在SQLite语句的WHERE子句中组合多个条件。使用OR运算符时,只要至少有一个条件为真,整个条件就被认为是真。例如,[condition1] OR [condition2] 如果condition1或condition2为真,则为真。
公元前 4714 年 11 月 24 日中午以来的天数
以下是带有WHERE子句的OR运算符的基本语法。
SELECT column1, column2, columnN FROM table_name WHERE [condition1] OR [condition2]...OR [conditionN]
你可以使用OR运算符组合N个条件。对于SQLite语句要执行的操作,无论是事务还是查询,只有任何一个由OR分隔的条件必须为TRUE。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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语句列出了所有年龄大于或等于25或者工资大于或等于65000.00的记录。
sqlite> SELECT * FROM COMPANY WHERE AGE >= 25 OR SALARY >= 65000; ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
SQLite - UPDATE 查询
SQLite 的UPDATE查询用于修改表中现有的记录。你可以将WHERE子句与UPDATE查询一起使用以更新选定的行,否则将更新所有行。
公元前 4714 年 11 月 24 日中午以来的天数
以下是带有WHERE子句的UPDATE查询的基本语法。
UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];
你可以使用AND或OR运算符组合N个条件。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的 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
以下是一个例子,它将更新ID为6的客户的地址。
sqlite> UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;
现在,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 Texas 45000.0 7 James 24 Houston 10000.0
如果你想修改COMPANY表中所有ADDRESS和SALARY列的值,则不需要使用WHERE子句,UPDATE查询将如下所示:
sqlite> UPDATE COMPANY SET ADDRESS = 'Texas', SALARY = 20000.00;
现在,COMPANY表将具有以下记录:
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 Texas 20000.0 2 Allen 25 Texas 20000.0 3 Teddy 23 Texas 20000.0 4 Mark 25 Texas 20000.0 5 David 27 Texas 20000.0 6 Kim 22 Texas 20000.0 7 James 24 Texas 20000.0
SQLite - DELETE 查询
SQLite 的DELETE查询用于从表中删除现有记录。你可以将WHERE子句与DELETE查询一起使用以删除选定的行,否则将删除所有记录。
公元前 4714 年 11 月 24 日中午以来的天数
以下是带有WHERE子句的DELETE查询的基本语法。
DELETE FROM table_name WHERE [condition];
你可以使用AND或OR运算符组合N个条件。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
以下是一个例子,它将删除ID为7的客户。
sqlite> DELETE FROM COMPANY WHERE ID = 7;
现在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
如果你想从COMPANY表中删除所有记录,则不需要在DELETE查询中使用WHERE子句,它将如下所示:
sqlite> DELETE FROM COMPANY;
现在,COMPANY表没有任何记录,因为所有记录都已被DELETE语句删除。
SQLite - LIKE 子句
SQLite 的LIKE运算符用于使用通配符将文本值与模式匹配。如果搜索表达式可以与模式表达式匹配,则LIKE运算符将返回true,即1。与LIKE运算符一起使用的通配符有两个:
- 百分号 (%)
- 下划线 (_)
百分号代表零个、一个或多个数字或字符。下划线代表单个数字或字符。这些符号可以组合使用。
公元前 4714 年 11 月 24 日中午以来的天数
以下是%和_的基本语法。
SELECT FROM table_name WHERE column LIKE 'XXXX%' or SELECT FROM table_name WHERE column LIKE '%XXXX%' or SELECT FROM table_name WHERE column LIKE 'XXXX_' or SELECT FROM table_name WHERE column LIKE '_XXXX' or SELECT FROM table_name WHERE column LIKE '_XXXX_'
你可以使用AND或OR运算符组合N个条件。这里,XXXX可以是任何数值或字符串值。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
下表列出了几个示例,这些示例显示了WHERE部分具有使用'%'和'_'运算符的不同LIKE子句。
序号 | 语句 & 说明 |
---|---|
1 | WHERE SALARY LIKE '200%' 查找以200开头的任何值 |
2 | WHERE SALARY LIKE '%200%' 查找任何位置包含200的任何值 |
3 | WHERE SALARY LIKE '_00%' 查找在第二位和第三位有00的任何值 |
4 | WHERE SALARY LIKE '2_%_%' 查找以2开头且至少有3个字符的任何值 |
5 | WHERE SALARY LIKE '%2' 查找以2结尾的任何值 |
6 | WHERE SALARY LIKE '_2%3' 查找第二位有2且以3结尾的任何值 |
7 | WHERE SALARY LIKE '2___3' 查找五位数中以2开头并以3结尾的任何值 |
让我们来看一个真实的例子,考虑具有以下记录的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
以下是一个例子,它将显示COMPANY表中AGE以2开头的所有记录。
sqlite> SELECT * FROM COMPANY WHERE AGE LIKE '2%';
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 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
以下是一个例子,它将显示COMPANY表中ADDRESS包含连字符(-)的所有记录。
sqlite> SELECT * FROM COMPANY WHERE ADDRESS LIKE '%-%';
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 Mark 25 Rich-Mond 65000.0 6 Kim 22 South-Hall 45000.0
SQLite - GLOB 子句
SQLite 的GLOB运算符用于仅使用通配符将文本值与模式匹配。如果搜索表达式可以与模式表达式匹配,则GLOB运算符将返回true,即1。与LIKE运算符不同,GLOB区分大小写,并且遵循UNIX的语法来指定以下通配符。
- 星号 (*)
- 问号 (?)
星号 (*) 代表零个或多个数字或字符。问号 (?) 代表单个数字或字符。
公元前 4714 年 11 月 24 日中午以来的天数
以下是* 和? 的基本语法。
SELECT FROM table_name WHERE column GLOB 'XXXX*' or SELECT FROM table_name WHERE column GLOB '*XXXX*' or SELECT FROM table_name WHERE column GLOB 'XXXX?' or SELECT FROM table_name WHERE column GLOB '?XXXX' or SELECT FROM table_name WHERE column GLOB '?XXXX?' or SELECT FROM table_name WHERE column GLOB '????'
你可以使用AND或OR运算符组合N个条件。这里,XXXX可以是任何数值或字符串值。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
下表列出了一些示例,这些示例显示了 WHERE 部分具有使用 '*' 和 '?' 运算符的不同 LIKE 子句。
序号 | 语句 & 说明 |
---|---|
1 | WHERE SALARY GLOB '200*' 查找以200开头的任何值 |
2 | WHERE SALARY GLOB '*200*' 查找任何位置包含200的任何值 |
3 | WHERE SALARY GLOB '?00*' 查找在第二位和第三位有00的任何值 |
4 | WHERE SALARY GLOB '2??' 查找以2开头且至少有3个字符的任何值 |
5 | WHERE SALARY GLOB '*2' 查找以2结尾的任何值 |
6 | WHERE SALARY GLOB '?2*3' 查找任何在第二位是 2 且以 3 结尾的值 |
7 | WHERE SALARY GLOB '2???3' 查找任何以 2 开头并以 3 结尾的五位数 |
让我们来看一个真实的例子,考虑一个包含以下记录的 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
以下是一个示例,它将显示 COMPANY 表中 AGE 以 2 开头的所有记录。
sqlite> SELECT * FROM COMPANY WHERE AGE GLOB '2*';
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 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
以下是一个示例,它将显示 COMPANY 表中 ADDRESS 包含连字符 (-) 的所有记录:
sqlite> SELECT * FROM COMPANY WHERE ADDRESS GLOB '*-*';
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 Mark 25 Rich-Mond 65000.0 6 Kim 22 South-Hall 45000.0
SQLite - LIMIT 子句
SQLite 的LIMIT 子句用于限制 SELECT 语句返回的数据量。
公元前 4714 年 11 月 24 日中午以来的天数
以下是包含 LIMIT 子句的 SELECT 语句的基本语法。
SELECT column1, column2, columnN FROM table_name LIMIT [no of rows]
以下是 LIMIT 子句与 OFFSET 子句一起使用时的语法。
SELECT column1, column2, columnN FROM table_name LIMIT [no of rows] OFFSET [row num]
SQLite 引擎将从给定 OFFSET 的下一行开始返回行,如下面的最后一个示例所示。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的 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
以下是一个示例,它根据您想要从表中提取的行数来限制表中的行。
sqlite> SELECT * FROM COMPANY LIMIT 6;
这将产生以下结果。
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
但是,在某些情况下,您可能需要从特定偏移量处提取一组记录。这是一个示例,它从第 3 个位置开始提取 3 条记录。
sqlite> SELECT * FROM COMPANY LIMIT 3 OFFSET 2;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
SQLite - ORDER BY 子句
SQLite 的ORDER BY 子句用于根据一个或多个列对数据进行升序或降序排序。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 ORDER BY 子句的基本语法。
SELECT column-list FROM table_name [WHERE condition] [ORDER BY column1, column2, .. columnN] [ASC | DESC];
您可以在 ORDER BY 子句中使用多个列。确保您用于排序的任何列都应在列列表中可用。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
以下是一个示例,它将结果按 SALARY 降序排序。
sqlite> SELECT * FROM COMPANY ORDER BY SALARY ASC;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 7 James 24 Houston 10000.0 2 Allen 25 Texas 15000.0 1 Paul 32 California 20000.0 3 Teddy 23 Norway 20000.0 6 Kim 22 South-Hall 45000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
以下是一个示例,它将结果按 NAME 和 SALARY 降序排序。
sqlite> SELECT * FROM COMPANY ORDER BY NAME, SALARY ASC;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000.0 5 David 27 Texas 85000.0 7 James 24 Houston 10000.0 6 Kim 22 South-Hall 45000.0 4 Mark 25 Rich-Mond 65000.0 1 Paul 32 California 20000.0 3 Teddy 23 Norway 20000.0
以下是一个示例,它将结果按 NAME 降序排序。
sqlite> SELECT * FROM COMPANY ORDER BY NAME DESC;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 3 Teddy 23 Norway 20000.0 1 Paul 32 California 20000.0 4 Mark 25 Rich-Mond 65000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 5 David 27 Texas 85000.0 2 Allen 25 Texas 15000.0
SQLite - GROUP BY 子句
SQLite 的GROUP BY 子句与 SELECT 语句一起使用,用于将相同的数据排列成组。
GROUP BY 子句位于 SELECT 语句中的 WHERE 子句之后,ORDER BY 子句之前。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 GROUP BY 子句的基本语法。GROUP BY 子句必须遵循 WHERE 子句中的条件,如果使用 ORDER BY 子句,则必须位于其之前。
SELECT column-list FROM table_name WHERE [ conditions ] GROUP BY column1, column2....columnN ORDER BY column1, column2....columnN
您可以在 GROUP BY 子句中使用多个列。确保您用于分组的任何列都应在列列表中可用。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
如果您想知道每个客户的工资总额,那么 GROUP BY 查询如下:
sqlite> SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME;
这将产生以下结果:
NAME SUM(SALARY) ---------- ----------- Allen 15000.0 David 85000.0 James 10000.0 Kim 45000.0 Mark 65000.0 Paul 20000.0 Teddy 20000.0
现在,让我们使用以下 INSERT 语句在 COMPANY 表中创建三个更多记录。
INSERT INTO COMPANY VALUES (8, 'Paul', 24, 'Houston', 20000.00 ); INSERT INTO COMPANY VALUES (9, 'James', 44, 'Norway', 5000.00 ); INSERT INTO COMPANY VALUES (10, 'James', 45, 'Texas', 5000.00 );
现在,我们的表包含以下具有重复名称的记录。
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 8 Paul 24 Houston 20000.0 9 James 44 Norway 5000.0 10 James 45 Texas 5000.0
再次,让我们使用相同的语句,使用 NAME 列对所有记录进行分组,如下所示:
sqlite> SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME;
这将产生以下结果。
NAME SUM(SALARY) ---------- ----------- Allen 15000 David 85000 James 20000 Kim 45000 Mark 65000 Paul 40000 Teddy 20000
让我们结合使用 ORDER BY 子句和 GROUP BY 子句,如下所示:
sqlite> SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME DESC;
这将产生以下结果。
NAME SUM(SALARY) ---------- ----------- Teddy 20000 Paul 40000 Mark 65000 Kim 45000 James 20000 David 85000 Allen 15000
SQLite - HAVING 子句
HAVING 子句使您可以指定条件,以筛选最终结果中显示的组结果。
WHERE 子句对选定的列设置条件,而 HAVING 子句对 GROUP BY 子句创建的组设置条件。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 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
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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 8 Paul 24 Houston 20000.0 9 James 44 Norway 5000.0 10 James 45 Texas 5000.0
以下是一个示例,它将显示名称计数少于 2 的记录。
sqlite > SELECT * FROM COMPANY GROUP BY name HAVING count(name) < 2;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000 5 David 27 Texas 85000 6 Kim 22 South-Hall 45000 4 Mark 25 Rich-Mond 65000 3 Teddy 23 Norway 20000
以下是一个示例,它将显示名称计数大于 2 的记录。
sqlite > SELECT * FROM COMPANY GROUP BY name HAVING count(name) > 2;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 10 James 45 Texas 5000
SQLite - DISTINCT 关键字
SQLite 的DISTINCT 关键字与 SELECT 语句一起使用,用于消除所有重复记录并仅获取唯一记录。
您可能遇到表中有多个重复记录的情况。在提取此类记录时,提取唯一记录比提取重复记录更有意义。
公元前 4714 年 11 月 24 日中午以来的天数
以下是用于消除重复记录的 DISTINCT 关键字的基本语法。
SELECT DISTINCT column1, column2,.....columnN FROM table_name WHERE [condition]
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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 8 Paul 24 Houston 20000.0 9 James 44 Norway 5000.0 10 James 45 Texas 5000.0
首先,让我们看看以下 SELECT 查询如何返回重复的工资记录。
sqlite> SELECT name FROM COMPANY;
这将产生以下结果。
NAME ---------- Paul Allen Teddy Mark David Kim James Paul James James
现在,让我们在上面的 SELECT 查询中使用DISTINCT 关键字,并查看结果。
sqlite> SELECT DISTINCT name FROM COMPANY;
这将产生以下结果,其中没有重复条目。
NAME ---------- Paul Allen Teddy Mark David Kim James
SQLite - PRAGMA
SQLite 的PRAGMA 命令是一个特殊命令,用于控制 SQLite 环境中的各种环境变量和状态标志。可以读取 PRAGMA 值,也可以根据需要设置 PRAGMA 值。
公元前 4714 年 11 月 24 日中午以来的天数
要查询当前的 PRAGMA 值,只需提供 pragma 的名称。
PRAGMA pragma_name;
要为 PRAGMA 设置新值,请使用以下语法。
PRAGMA pragma_name = value;
设置模式可以是名称或整数等效项,但返回值始终为整数。
auto_vacuum Pragma
auto_vacuum pragma 获取或设置自动 vacuum 模式。以下是简单的语法。
PRAGMA [database.]auto_vacuum; PRAGMA [database.]auto_vacuum = mode;
其中mode 可以是以下任何一个:
序号 | Pragma 值和说明 |
---|---|
1 | 0 或 NONE 禁用自动 vacuum。这是默认模式,这意味着数据库文件的大小永远不会缩小,除非使用 VACUUM 命令手动 vacuum。 |
2 | 1 或 FULL 启用自动 vacuum 且完全自动,允许数据库文件在数据从数据库中删除时缩小。 |
3 | 2 或 INCREMENTAL 启用自动 vacuum,但必须手动激活。在此模式下,将维护参考数据,但空闲页面将简单地放在空闲列表中。这些页面可以使用incremental_vacuum pragma随时恢复。 |
cache_size Pragma
cache_size pragma 可以获取或临时设置内存中页面缓存的最大大小。以下是简单的语法。
PRAGMA [database.]cache_size; PRAGMA [database.]cache_size = pages;
pages 值表示缓存中的页面数。内置页面缓存的默认大小为 2000 个页面,最小大小为 10 个页面。
case_sensitive_like Pragma
case_sensitive_like pragma 控制内置 LIKE 表达式的区分大小写。默认情况下,此 pragma 为 false,这意味着内置 LIKE 运算符会忽略字母大小写。以下是简单的语法。
PRAGMA case_sensitive_like = [true|false];
无法查询此 pragma 的当前状态。
count_changes Pragma
count_changes pragma 获取或设置数据操作语句(如 INSERT、UPDATE 和 DELETE)的返回值。以下是简单的语法。
PRAGMA count_changes; PRAGMA count_changes = [true|false];
默认情况下,此 pragma 为 false,这些语句不返回任何内容。如果设置为 true,则每个提到的语句都将返回一个单列、单行表,其中包含一个整数数值,表示操作影响的行数。
database_list Pragma
database_list pragma 用于列出所有附加的数据库。以下是简单的语法。
PRAGMA database_list;
此 pragma 将返回一个三列表,每行一个打开或附加的数据库,给出数据库序列号、其名称和关联的文件。
encoding Pragma
encoding pragma 控制字符串如何在数据库文件中编码和存储。以下是简单的语法。
PRAGMA encoding; PRAGMA encoding = format;
format 值可以是UTF-8、UTF-16le 或UTF-16be 之一。
freelist_count Pragma
freelist_count pragma 返回一个整数,指示当前有多少数据库页面被标记为空闲且可用。以下是简单的语法。
PRAGMA [database.]freelist_count;
format 值可以是UTF-8、UTF-16le 或UTF-16be 之一。
index_info Pragma
index_info pragma 返回有关数据库索引的信息。以下是简单的语法。
PRAGMA [database.]index_info( index_name );
结果集将为索引中包含的每一列包含一行,给出列序列、表内的列索引和列名。
index_list Pragma
index_list pragma 列出与表关联的所有索引。以下是简单的语法。
PRAGMA [database.]index_list( table_name );
结果集将为每个索引包含一行,给出索引序列、索引名称和指示索引是否唯一的标志。
journal_mode Pragma
journal_mode pragma 获取或设置日志模式,该模式控制日志文件的存储和处理方式。以下是简单的语法。
PRAGMA journal_mode; PRAGMA journal_mode = mode; PRAGMA database.journal_mode; PRAGMA database.journal_mode = mode;
下表列出了五种受支持的日志模式。
序号 | Pragma 值和说明 |
---|---|
1 | DELETE 这是默认模式。在此模式下,事务结束时,将删除日志文件。 |
2 | TRUNCATE 日志文件将被截断为零字节长度。 |
3 | PERSIST 日志文件保留在原处,但标头将被覆盖以指示日志不再有效。 |
4 | MEMORY 日志记录保存在内存中,而不是磁盘上。 |
5 | OFF 不保留日志记录。 |
max_page_count Pragma
max_page_count pragma 获取或设置数据库允许的最大页面数。以下是简单的语法。
PRAGMA [database.]max_page_count; PRAGMA [database.]max_page_count = max_page;
默认值为 1,073,741,823,即十亿页,这意味着如果默认页面大小为 1 KB,则允许数据库增长到一太字节。
page_count Pragma
page_count pragma 返回数据库中当前的页面数。以下是简单的语法:
PRAGMA [database.]page_count;
数据库文件的大小应为 page_count * page_size。
page_size Pragma
page_size pragma 获取或设置数据库页面的大小。以下是简单的语法。
PRAGMA [database.]page_size; PRAGMA [database.]page_size = bytes;
默认情况下,允许的大小为 512、1024、2048、4096、8192、16384 和 32768 字节。更改现有数据库页面大小的唯一方法是设置页面大小,然后立即 VACUUM 数据库。
parser_trace Pragma
parser_trace pragma 控制在解析 SQL 命令时打印调试状态。以下是简单的语法。
PRAGMA parser_trace = [true|false];
默认情况下,它设置为 false,但如果通过将其设置为 true 来启用它,则 SQL 解析器将在解析 SQL 命令时打印其状态。
recursive_triggers Pragma
recursive_triggers pragma 获取或设置递归触发器功能。如果未启用递归触发器,则触发器操作不会触发另一个触发器。以下是简单的语法。
PRAGMA recursive_triggers; PRAGMA recursive_triggers = [true|false];
schema_version Pragma
schema_version pragma 获取或设置存储在数据库标头中的模式版本值。以下是简单的语法。
PRAGMA [database.]schema_version; PRAGMA [database.]schema_version = number;
这是一个 32 位有符号整数,用于跟踪模式更改。每当执行更改模式的命令(例如,CREATE... 或 DROP...)时,此值都会递增。
secure_delete Pragma
secure_delete pragma 用于控制如何从数据库中删除内容。以下是简单的语法。
PRAGMA secure_delete; PRAGMA secure_delete = [true|false]; PRAGMA database.secure_delete; PRAGMA database.secure_delete = [true|false];
安全删除标志的默认值通常为关闭,但这可以通过 SQLITE_SECURE_DELETE 构建选项更改。
sql_trace Pragma
sql_trace pragma 用于将 SQL 跟踪结果转储到屏幕上。以下是简单的语法。
PRAGMA sql_trace; PRAGMA sql_trace = [true|false];
SQLite 必须使用 SQLITE_DEBUG 指令编译才能包含此 pragma。
synchronous Pragma
同步 pragma 获取或设置当前磁盘同步模式,该模式控制 SQLite 将数据写入物理存储的积极程度。以下是简单的语法。
PRAGMA [database.]synchronous; PRAGMA [database.]synchronous = mode;
SQLite 支持下表列出的同步模式。
序号 | Pragma 值和说明 |
---|---|
1 | 0 或 OFF 完全不同步 |
2 | 1 或 NORMAL 在每次关键磁盘操作序列后同步 |
3 | 2 或 FULL 在每次关键磁盘操作后同步 |
temp_store Pragma
temp_store pragma 获取或设置临时数据库文件使用的存储模式。以下是简单的语法。
PRAGMA temp_store; PRAGMA temp_store = mode;
SQLite 支持以下存储模式。
序号 | Pragma 值和说明 |
---|---|
1 | 0 或 DEFAULT 使用编译时默认值。通常为 FILE。 |
2 | 1 或 FILE 使用基于文件的存储。 |
3 | 2 或 MEMORY 使用基于内存的存储。 |
temp_store_directory Pragma
temp_store_directory pragma 获取或设置临时数据库文件使用的位置。以下是简单的语法。
PRAGMA temp_store_directory; PRAGMA temp_store_directory = 'directory_path';
user_version Pragma
user_version pragma 获取或设置存储在数据库头中的用户定义版本值。以下是简单的语法。
PRAGMA [database.]user_version; PRAGMA [database.]user_version = number;
这是一个 32 位有符号整数,开发人员可以将其设置为版本跟踪目的。
writable_schema Pragma
writable_schema pragma 获取或设置修改系统表的能力。以下是简单的语法。
PRAGMA writable_schema; PRAGMA writable_schema = [true|false];
如果设置了此 pragma,则可以创建和修改以 sqlite_ 开头的表,包括 sqlite_master 表。使用 pragma 时要小心,因为它可能导致数据库完全损坏。
SQLite - 约束
约束是对表中数据列强制执行的规则。这些规则用于限制可以进入表的數據类型。这确保了数据库中数据的准确性和可靠性。
约束可以是列级或表级。列级约束仅应用于一列,而表级约束应用于整个表。
以下是 SQLite 中常用的约束。
NOT NULL 约束 - 确保列不能具有 NULL 值。
DEFAULT 约束 - 在未指定值时为列提供默认值。
UNIQUE 约束 - 确保列中的所有值都不同。
PRIMARY KEY - 唯一标识数据库表中的每一行/记录。
CHECK 约束 - 确保列中的所有值都满足某些条件。
NOT NULL 约束
默认情况下,列可以包含 NULL 值。如果您不希望列具有 NULL 值,则需要在此列上定义此约束,指定该列现在不允许 NULL。
NULL 与没有数据不同,而是表示未知数据。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
例如,以下 SQLite 语句创建一个名为 COMPANY 的新表并添加五列,其中三列 ID、NAME 和 AGE 指定不接受 NULL。
CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
DEFAULT 约束
DEFAULT 约束在 INSERT INTO 语句未提供特定值时为列提供默认值。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
例如,以下 SQLite 语句创建一个名为 COMPANY 的新表并添加五列。这里,SALARY 列默认设置为 5000.00,因此,如果 INSERT INTO 语句未为此列提供值,则此列将默认设置为 5000.00。
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 约束
UNIQUE 约束可以防止两条记录在特定列中具有相同的值。例如,在 COMPANY 表中,您可能希望防止两个人拥有相同的年龄。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
例如,以下 SQLite 语句创建一个名为 COMPANY 的新表并添加五列。这里,AGE 列设置为 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 值。
一个表只能有一个主键,它可以由单个或多个字段组成。当多个字段用作主键时,它们称为组合键。
如果表在任何字段上定义了主键,则您不能有两条记录具有该字段的相同值。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
您已经在上面的各种示例中看到我们创建了以 ID 作为主键的 COMPANY 表。
CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
CHECK 约束
CHECK 约束启用一个条件来检查输入记录的值。如果条件计算结果为假,则记录违反约束,不会输入到表中。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
例如,以下 SQLite 创建一个名为 COMPANY 的新表并添加五列。这里,我们在 SALARY 列添加一个 CHECK,这样您就不能有任何为零的 SALARY。
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) );
删除约束
SQLite 支持 ALTER TABLE 的有限子集。SQLite 中的 ALTER TABLE 命令允许用户重命名表或向现有表添加新列。无法重命名列、删除列或向表添加或删除约束。
SQLite - 连接 (JOINS)
SQLite 的连接子句用于组合数据库中两个或多个表中的记录。连接是一种通过使用每个表共有的值来组合两个表中的字段的方法。
SQL 定义了三种主要的连接类型 -
- 交叉连接 (CROSS JOIN)
- 内连接 (INNER JOIN)
- 外连接 (OUTER JOIN)
在我们继续之前,让我们考虑两个表 COMPANY 和 DEPARTMENT。我们已经看到用于填充 COMPANY 表的 INSERT 语句。所以让我们假设 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
另一个表是 DEPARTMENT,其定义如下 -
CREATE TABLE DEPARTMENT( ID INT PRIMARY KEY NOT NULL, DEPT CHAR(50) NOT NULL, EMP_ID INT NOT NULL );
以下是用于填充 DEPARTMENT 表的 INSERT 语句列表 -
INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID) VALUES (1, 'IT Billing', 1 ); INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID) VALUES (2, 'Engineering', 2 ); INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID) VALUES (3, 'Finance', 7 );
最后,DEPARTMENT 表中可用的记录列表如下 -
ID DEPT EMP_ID ---------- ---------- ---------- 1 IT Billing 1 2 Engineering 2 3 Finance 7
交叉连接 (CROSS JOIN)
CROSS JOIN 将第一个表的每一行与第二个表的每一行匹配。如果输入表分别具有 x 和 y 行,则结果表将具有 x*y 行。由于 CROSS JOIN 有可能生成非常大的表,因此必须小心谨慎,仅在适当的时候使用它们。
以下是 CROSS JOIN 的语法 -
SELECT ... FROM table1 CROSS JOIN table2 ...
基于上面的表,您可以编写 CROSS JOIN 如下 -
sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY CROSS JOIN DEPARTMENT;
上面的查询将产生以下结果 -
EMP_ID NAME DEPT ---------- ---------- ---------- 1 Paul IT Billing 2 Paul Engineering 7 Paul Finance 1 Allen IT Billing 2 Allen Engineering 7 Allen Finance 1 Teddy IT Billing 2 Teddy Engineering 7 Teddy Finance 1 Mark IT Billing 2 Mark Engineering 7 Mark Finance 1 David IT Billing 2 David Engineering 7 David Finance 1 Kim IT Billing 2 Kim Engineering 7 Kim Finance 1 James IT Billing 2 James Engineering 7 James Finance
内连接 (INNER JOIN)
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...
基于上面的表,您可以编写 INNER JOIN 如下 -
sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
上面的查询将产生以下结果 -
EMP_ID NAME DEPT ---------- ---------- ---------- 1 Paul IT Billing 2 Allen Engineering 7 James Finance
外连接 (OUTER JOIN)
OUTER JOIN 是 INNER JOIN 的扩展。尽管 SQL 标准定义了三种类型的 OUTER JOIN:LEFT、RIGHT 和 FULL,但 SQLite 只支持LEFT OUTER JOIN。
OUTER JOIN 具有与 INNER JOIN 相同的条件,使用 ON、USING 或 NATURAL 关键字表示。初始结果表以相同的方式计算。一旦计算出主 JOIN,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 Engineering Teddy Mark David Kim 7 James Finance
SQLite - UNION 子句
SQLite 的UNION子句/运算符用于组合两个或多个 SELECT 语句的结果,而不返回任何重复的行。
要使用 UNION,每个 SELECT 必须具有相同数量的列、相同数量的列表达式、相同的数据类型,并且顺序相同,但它们不必具有相同的长度。
公元前 4714 年 11 月 24 日中午以来的天数
以下是UNION的基本语法。
SELECT column1 [, column2 ] FROM table1 [, table2 ] [WHERE condition] UNION SELECT column1 [, column2 ] FROM table1 [, table2 ] [WHERE condition]
这里给定的条件可以是基于您需求的任何给定表达式。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑以下两个表,(a) COMPANY 表如下 -
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 South-Hall 45000.0 7 James 24 Houston 10000.0
(b) 另一个表是 DEPARTMENT 表如下 -
ID DEPT EMP_ID ---------- -------------------- ---------- 1 IT Billing 1 2 Engineering 2 3 Finance 7 4 Engineering 3 5 Finance 4 6 Engineering 5 7 Finance 6
现在让我们使用 SELECT 语句以及 UNION 子句将这两个表连接起来,如下所示 -
sqlite> 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;
这将产生以下结果。
EMP_ID NAME DEPT ---------- -------------------- ---------- 1 Paul IT Billing 2 Allen Engineering 3 Teddy Engineering 4 Mark Finance 5 David Engineering 6 Kim Finance 7 James Finance
UNION ALL 子句
UNION ALL 运算符用于组合两个 SELECT 语句的结果,包括重复的行。
应用于 UNION 的相同规则也适用于 UNION ALL 运算符。
公元前 4714 年 11 月 24 日中午以来的天数
以下是UNION ALL的基本语法。
SELECT column1 [, column2 ] FROM table1 [, table2 ] [WHERE condition] UNION ALL SELECT column1 [, column2 ] FROM table1 [, table2 ] [WHERE condition]
这里给定的条件可以是基于您需求的任何给定表达式。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
现在,让我们在 SELECT 语句中连接上述两个表,如下所示 -
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 Engineering 3 Teddy Engineering 4 Mark Finance 5 David Engineering 6 Kim Finance 7 James Finance 1 Paul IT Billing 2 Allen Engineering 3 Teddy Engineering 4 Mark Finance 5 David Engineering 6 Kim Finance 7 James Finance
SQLite - NULL 值
SQLite 的NULL用于表示缺失值。表中的 NULL 值是指字段中看起来为空的值。
具有 NULL 值的字段是没有值的字段。务必理解,NULL 值不同于零值或包含空格的字段。
公元前 4714 年 11 月 24 日中午以来的天数
以下是创建表时使用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 值的字段是在记录创建期间留空的值。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
NULL 值在选择数据时可能会导致问题,因为当将未知值与任何其他值进行比较时,结果始终是未知的,并且不包含在最终结果中。考虑以下表格,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
让我们使用 UPDATE 语句将一些可为空的值设置为 NULL,如下所示:
sqlite> UPDATE COMPANY SET ADDRESS = NULL, SALARY = NULL where ID IN(6,7);
现在,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 7 James 24
接下来,让我们看看IS NOT NULL运算符的用法,以列出 SALARY 不为 NULL 的所有记录。
sqlite> SELECT ID, NAME, AGE, ADDRESS, SALARY FROM COMPANY WHERE SALARY IS NOT NULL;
上面的 SQLite 语句将产生以下结果:
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
以下是IS NULL运算符的用法,它将列出 SALARY 为 NULL 的所有记录。
sqlite> SELECT ID, NAME, AGE, ADDRESS, SALARY FROM COMPANY WHERE SALARY IS NULL;
上面的 SQLite 语句将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 6 Kim 22 7 James 24
SQLite - 别名语法 (ALIAS Syntax)
您可以通过给表或列另一个名称来临时重命名它们,这称为别名 (ALIAS)。使用表别名意味着在一个特定的 SQLite 语句中重命名一个表。重命名是一个临时更改,实际的表名不会在数据库中更改。
列别名用于为了特定 SQLite 查询的目的而重命名表的列。
公元前 4714 年 11 月 24 日中午以来的天数
以下是表 (table)别名的基本语法。
SELECT column1, column2.... FROM table_name AS alias_name WHERE [condition];
以下是列 (column)别名的基本语法。
SELECT column_name AS alias_name FROM table_name WHERE [condition];
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑以下两个表,(a) COMPANY 表如下所示:
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 South-Hall 45000.0 7 James 24 Houston 10000.0
(b) 另一个表是 DEPARTMENT 表如下 -
ID DEPT EMP_ID ---------- -------------------- ---------- 1 IT Billing 1 2 Engineering 2 3 Finance 7 4 Engineering 3 5 Finance 4 6 Engineering 5 7 Finance 6
现在,以下是表别名 (TABLE ALIAS)的用法,我们使用 C 和 D 分别作为 COMPANY 和 DEPARTMENT 表的别名:
sqlite> SELECT C.ID, C.NAME, C.AGE, D.DEPT FROM COMPANY AS C, DEPARTMENT AS D WHERE C.ID = D.EMP_ID;
上面的 SQLite 语句将产生以下结果:
ID NAME AGE DEPT ---------- ---------- ---------- ---------- 1 Paul 32 IT Billing 2 Allen 25 Engineering 3 Teddy 23 Engineering 4 Mark 25 Finance 5 David 27 Engineering 6 Kim 22 Finance 7 James 24 Finance
考虑一个列别名 (COLUMN ALIAS)用法的示例,其中 COMPANY_ID 是 ID 列的别名,COMPANY_NAME 是 name 列的别名。
sqlite> SELECT C.ID AS COMPANY_ID, C.NAME AS COMPANY_NAME, C.AGE, D.DEPT FROM COMPANY AS C, DEPARTMENT AS D WHERE C.ID = D.EMP_ID;
上面的 SQLite 语句将产生以下结果:
COMPANY_ID COMPANY_NAME AGE DEPT ---------- ------------ ---------- ---------- 1 Paul 32 IT Billing 2 Allen 25 Engineering 3 Teddy 23 Engineering 4 Mark 25 Finance 5 David 27 Engineering 6 Kim 22 Finance 7 James 24 Finance
SQLite - 触发器 (Triggers)
SQLite触发器 (Triggers)是数据库回调函数,当指定的数据库事件发生时会自动执行/调用。以下是关于 SQLite 触发器的重要几点:
可以指定 SQLite 触发器在特定数据库表的 DELETE、INSERT 或 UPDATE 发生时,或者在表的指定列之一或多个列上发生 UPDATE 时触发。
目前,SQLite 只支持 FOR EACH ROW 触发器,不支持 FOR EACH STATEMENT 触发器。因此,显式指定 FOR EACH ROW 是可选的。
WHEN 子句和触发器操作都可以访问正在插入、删除或更新的行中的元素,使用 NEW.column-name 和 OLD.column-name 形式的引用,其中 column-name 是触发器关联的表的列的名称。
如果提供了 WHEN 子句,则只有在 WHEN 子句为 true 的行上才会执行指定的 SQL 语句。如果没有提供 WHEN 子句,则会对所有行执行 SQL 语句。
BEFORE 或 AFTER 关键字确定相对于关联行的插入、修改或删除操作何时执行触发器操作。
触发器在与其关联的表被删除时会自动删除。
要修改的表必须存在于与附加触发器的表或视图相同的数据库中,并且必须只使用tablename,而不是database.tablename。
可以在触发器程序中使用特殊的 SQL 函数 RAISE() 来引发异常。
公元前 4714 年 11 月 24 日中午以来的天数
以下是创建触发器的基本语法。
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 操作创建触发器的语法。
CREATE TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name ON table_name BEGIN -- Trigger logic goes here.... END;
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
让我们考虑一个案例,我们想为 COMPANY 表中插入的每条记录保留审计跟踪,我们新建如下(如果您已经拥有它,请删除 COMPANY 表)。
sqlite> CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
为了保留审计跟踪,我们将创建一个名为 AUDIT 的新表,每当在 COMPANY 表中为新记录创建条目时,日志消息将被插入到其中。
sqlite> CREATE TABLE AUDIT( EMP_ID INT NOT NULL, ENTRY_DATE TEXT NOT NULL );
这里,ID 是 AUDIT 记录 ID,EMP_ID 是将来自 COMPANY 表的 ID,DATE 将保留在 COMPANY 表中创建记录的时间戳。现在让我们在 COMPANY 表上创建触发器,如下所示:
sqlite> CREATE TRIGGER audit_log AFTER INSERT ON COMPANY BEGIN INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now')); END;
现在,我们将开始实际工作,让我们开始在 COMPANY 表中插入记录,这应该会导致在 AUDIT 表中创建一个审计日志记录。在 COMPANY 表中创建一个记录,如下所示:
sqlite> INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00 );
这将在 COMPANY 表中创建一个记录,如下所示:
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0
同时,将在 AUDIT 表中创建一个记录。此记录是我们在 COMPANY 表的 INSERT 操作上创建的触发器的结果。类似地,您可以根据您的需求在 UPDATE 和 DELETE 操作上创建触发器。
EMP_ID ENTRY_DATE ---------- ------------------- 1 2013-04-05 06:26:00
列出触发器
您可以从sqlite_master表中列出所有触发器,如下所示:
sqlite> SELECT name FROM sqlite_master WHERE type = 'trigger';
上面的 SQLite 语句将只列出以下一个条目:
name ---------- audit_log
如果您想列出特定表上的触发器,请使用包含表名的 AND 子句,如下所示:
sqlite> SELECT name FROM sqlite_master WHERE type = 'trigger' AND tbl_name = 'COMPANY';
上面的 SQLite 语句也将只列出以下一个条目:
name ---------- audit_log
删除触发器
以下是 DROP 命令,可用于删除现有触发器。
sqlite> DROP TRIGGER trigger_name;
SQLite - 索引 (Indexes)
索引是数据库搜索引擎可用于加快数据检索速度的特殊查找表。简单地说,索引是指向表中数据的指针。数据库中的索引与书后面的索引非常相似。
例如,如果您想参考书中讨论某个主题的所有页面,您首先参考索引,该索引按字母顺序列出所有主题,然后参考一个或多个特定页码。
索引有助于加快 SELECT 查询和 WHERE 子句的速度,但会减慢数据输入(使用 UPDATE 和 INSERT 语句)的速度。创建或删除索引不会影响数据。
创建索引涉及 CREATE INDEX 语句,该语句允许您命名索引,指定表以及要索引的列或列,并指示索引是升序还是降序。
索引也可以是唯一的,类似于 UNIQUE 约束,因为它可以防止在存在索引的列或列组合中插入重复项。
CREATE INDEX 命令
以下是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 列创建一个索引:
sqlite> CREATE INDEX salary_index ON COMPANY (salary);
现在,让我们使用.indices命令列出 COMPANY 表中所有可用的索引,如下所示:
sqlite> .indices COMPANY
这将产生以下结果,其中sqlite_autoindex_COMPANY_1是在创建表本身时创建的隐式索引。
salary_index sqlite_autoindex_COMPANY_1
您可以列出数据库范围内的所有索引,如下所示:
sqlite> SELECT * FROM sqlite_master WHERE type = 'index';
DROP INDEX 命令
可以使用 SQLite DROP 命令删除索引。删除索引时应谨慎,因为性能可能会变慢或变快。
以下是基本语法:
DROP INDEX index_name;
您可以使用以下语句删除之前创建的索引。
sqlite> DROP INDEX salary_index;
何时应避免使用索引?
尽管索引旨在增强数据库的性能,但在某些情况下应避免使用它们。以下准则指示何时应重新考虑使用索引。
不应在以下情况下使用索引:
- 小型表。
- 经常进行大量批量更新或插入操作的表。
- 包含大量 NULL 值的列。
- 经常被操作的列。
SQLite - INDEXED BY 子句
"INDEXED BY index-name" 子句指定必须使用命名的索引才能查找前面的表上的值。
如果 index-name 不存在或不能用于查询,则 SQLite 语句的准备将失败。
"NOT INDEXED" 子句指定在访问前面的表时不应使用任何索引,包括由 UNIQUE 和 PRIMARY KEY 约束创建的隐式索引。
但是,即使指定了 "NOT INDEXED",仍然可以使用 INTEGER PRIMARY KEY 来查找条目。
公元前 4714 年 11 月 24 日中午以来的天数
以下是 INDEXED BY 子句的语法,它可以与 DELETE、UPDATE 或 SELECT 语句一起使用。
SELECT|DELETE|UPDATE column1, column2... INDEXED BY (index_name) table_name WHERE (CONDITION);
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑表COMPANY,我们将创建一个索引并使用它执行INDEXED BY操作。
sqlite> CREATE INDEX salary_index ON COMPANY(salary); sqlite>
现在,从COMPANY表中选择数据,您可以按如下方式使用INDEXED BY子句:
sqlite> SELECT * FROM COMPANY INDEXED BY salary_index WHERE salary > 5000;
这将产生以下结果。
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 7 James 24 Houston 10000.0 2 Allen 25 Texas 15000.0 1 Paul 32 California 20000.0 3 Teddy 23 Norway 20000.0 6 Kim 22 South-Hall 45000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
SQLite - ALTER TABLE命令
SQLite 的ALTER TABLE命令修改现有表,无需执行数据的完整转储和重新加载。您可以使用ALTER TABLE语句重命名表,并可以使用ALTER TABLE语句在现有表中添加其他列。
除了重命名表和在现有表中添加列之外,SQLite中的ALTER TABLE命令不支持其他操作。
公元前 4714 年 11 月 24 日中午以来的天数
以下是用于重命名现有表的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...;
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
现在,让我们尝试使用ALTER TABLE语句重命名此表,如下所示:
sqlite> ALTER TABLE COMPANY RENAME TO OLD_COMPANY;
上述SQLite语句将COMPANY表重命名为OLD_COMPANY。现在,让我们尝试在OLD_COMPANY表中添加一个新列,如下所示:
sqlite> ALTER TABLE OLD_COMPANY ADD COLUMN SEX char(1);
COMPANY表现在已更改,SELECT语句将输出以下内容。
ID NAME AGE ADDRESS SALARY SEX ---------- ---------- ---------- ---------- ---------- --- 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
需要注意的是,新添加的列填充了NULL值。
SQLite - TRUNCATE TABLE命令
不幸的是,SQLite中没有TRUNCATE TABLE命令,但是您可以使用SQLite的DELETE命令删除现有表中的所有数据,尽管建议使用DROP TABLE命令删除整个表并再次重新创建它。
公元前 4714 年 11 月 24 日中午以来的天数
以下是DELETE命令的基本语法。
sqlite> DELETE FROM table_name;
以下是DROP TABLE的基本语法。
sqlite> DROP TABLE table_name;
如果您使用DELETE TABLE命令删除所有记录,建议使用VACUUM命令清除未使用的空间。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
以下是截断上述表的示例:
SQLite> DELETE FROM COMPANY; SQLite> VACUUM;
现在,COMPANY表已完全截断,SELECT语句将没有任何输出。
SQLite - 视图 (Views)
视图只不过是存储在数据库中并具有关联名称的SQLite语句。它实际上是以预定义的SQLite查询形式组成的表。
视图可以包含表的全部行或一个或多个表中的选定行。视图可以从一个或多个表创建,这取决于用于创建视图的编写的SQLite查询。
作为虚拟表的视图允许用户:
以用户或用户类别认为自然或直观的方式构造数据。
限制对数据的访问,以便用户只能查看有限的数据,而不是完整的表。
汇总来自各个表的数据,可用于生成报表。
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];
您可以像在普通的SQL SELECT查询中使用它们一样,在SELECT语句中包含多个表。如果存在可选的TEMP或TEMPORARY关键字,则视图将创建在临时数据库中。
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
以下是如何从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 - 事务 (Transactions)
事务是对数据库执行的工作单元。事务是按逻辑顺序完成的工作单元或序列,无论是用户手动完成,还是某种数据库程序自动完成。
事务是将一个或多个更改传播到数据库。例如,如果您正在创建、更新或删除表中的记录,那么您正在对表执行事务。控制事务以确保数据完整性和处理数据库错误非常重要。
实际上,您会将许多SQLite查询组合成一个组,并将它们一起作为事务的一部分执行。
事务的属性
事务具有以下四个标准属性,通常用首字母缩写词ACID表示。
原子性 - 确保工作单元中的所有操作都成功完成;否则,事务将在失败点中止,之前的操作将回滚到其先前状态。
一致性 - 确保数据库在成功提交的事务后正确更改状态。
隔离性 - 使事务能够彼此独立且透明地运行。
持久性 - 确保已提交事务的结果或效果在系统故障的情况下仍然存在。
事务控制
以下是用于控制事务的命令
BEGIN TRANSACTION - 开始事务。
COMMIT - 保存更改,或者您可以使用END TRANSACTION命令。
ROLLBACK - 回滚更改。
事务控制命令仅与DML命令INSERT、UPDATE和DELETE一起使用。在创建或删除表时不能使用它们,因为这些操作会自动提交到数据库。
BEGIN TRANSACTION命令
可以使用BEGIN TRANSACTION或简单的BEGIN命令启动事务。此类事务通常持续到遇到下一个COMMIT或ROLLBACK命令为止。但是,如果数据库关闭或发生错误,事务也将回滚。以下是启动事务的简单语法。
BEGIN; or BEGIN TRANSACTION;
COMMIT命令
COMMIT命令是用于将事务调用的更改保存到数据库的事务命令。
COMMIT命令自上次COMMIT或ROLLBACK命令以来将所有事务保存到数据库。
以下是COMMIT命令的语法。
COMMIT; or END TRANSACTION;
ROLLBACK命令
ROLLBACK命令是用于撤消尚未保存到数据库的事务的事务命令。
ROLLBACK命令只能用于撤消自发出上次COMMIT或ROLLBACK命令以来的事务。
以下是ROLLBACK命令的语法。
ROLLBACK;
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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
现在,让我们启动一个事务并删除表中age = 25的记录。然后,使用ROLLBACK命令撤消所有更改。
sqlite> BEGIN; sqlite> DELETE FROM COMPANY WHERE AGE = 25; sqlite> ROLLBACK;
现在,如果您检查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
让我们启动另一个事务并删除表中age = 25的记录,最后我们使用COMMIT命令提交所有更改。
sqlite> BEGIN; sqlite> DELETE FROM COMPANY WHERE AGE = 25; sqlite> COMMIT;
如果您现在检查COMPANY表,它仍然具有以下记录:
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 3 Teddy 23 Norway 20000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
SQLite - 子查询 (Subqueries)
子查询或内部查询或嵌套查询是在另一个SQLite查询中的查询,并嵌入在WHERE子句中。
子查询用于返回将在主查询中用作条件的数据,以进一步限制要检索的数据。
子查询可以与SELECT、INSERT、UPDATE和DELETE语句以及=、<、>、>=、<=、IN、BETWEEN等运算符一起使用。
子查询必须遵循一些规则:
子查询必须用括号括起来。
除非子查询的多个列用于比较其选择的列,否则子查询的SELECT子句中只能有一列。
虽然主查询可以使用ORDER BY,但在子查询中不能使用ORDER BY。GROUP BY可用于执行与子查询中的ORDER BY相同的功能。
返回多行的子查询只能与多值运算符一起使用,例如IN运算符。
BETWEEN运算符不能与子查询一起使用;但是,BETWEEN可以在子查询中使用。
带有SELECT语句的子查询
子查询最常与SELECT语句一起使用。基本语法如下:
SELECT column_name [, column_name ] FROM table1 [, table2 ] WHERE column_name OPERATOR (SELECT column_name [, column_name ] FROM table1 [, table2 ] [WHERE])
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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语句的子查询。
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语句使用子查询返回的数据插入到另一个表中。子查询中的选择数据可以使用任何字符、日期或数字函数进行修改。
以下是基本语法:
INSERT INTO table_name [ (column1 [, column2 ]) ] SELECT [ *|column1 [, column2 ] FROM table1 [, table2 ] [ WHERE VALUE OPERATOR ]
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑一个与COMPANY表具有相似结构的COMPANY_BKP表,可以使用相同的CREATE TABLE语句创建,使用COMPANY_BKP作为表名。要将完整的COMPANY表复制到COMPANY_BKP,语法如下:
sqlite> INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY) ;
带有UPDATE语句的子查询
子查询可以与UPDATE语句一起使用。使用子查询与UPDATE语句时,可以更新表中的单个或多个列。
以下是基本语法:
UPDATE table SET column_name = new_value [ WHERE OPERATOR [ VALUE ] (SELECT COLUMN_NAME FROM TABLE_NAME) [ WHERE) ]
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
假设我们有可用的COMPANY_BKP表,它是COMPANY表的备份。
以下示例更新COMPANY表中所有年龄大于或等于27的客户的SALARY,乘以0.50。
sqlite> UPDATE COMPANY SET SALARY = SALARY * 0.50 WHERE AGE IN (SELECT AGE FROM COMPANY_BKP WHERE AGE >= 27 );
这将影响两行,最后COMPANY表将具有以下记录:
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 10000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 42500.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
带有DELETE语句的子查询
子查询可以与DELETE语句一起使用,就像上面提到的任何其他语句一样。
以下是基本语法:
DELETE FROM TABLE_NAME [ WHERE OPERATOR [ VALUE ] (SELECT COLUMN_NAME FROM TABLE_NAME) [ WHERE) ]
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
假设我们有可用的COMPANY_BKP表,它是COMPANY表的备份。
以下示例删除COMPANY表中所有年龄大于或等于27的客户的记录。
sqlite> DELETE FROM COMPANY WHERE AGE IN (SELECT AGE FROM COMPANY_BKP WHERE AGE > 27 );
这将影响两行,最后COMPANY表将具有以下记录:
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 42500.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
SQLite - AUTOINCREMENT
SQLite 的AUTOINCREMENT是一个关键字,用于自动递增表中字段的值。我们可以使用AUTOINCREMENT关键字在创建具有特定列名的表时自动递增字段值。
AUTOINCREMENT关键字只能与INTEGER字段一起使用。
公元前 4714 年 11 月 24 日中午以来的天数
AUTOINCREMENT关键字的基本用法如下:
CREATE TABLE table_name( column1 INTEGER AUTOINCREMENT, column2 datatype, column3 datatype, ..... columnN datatype, );
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑如下创建的COMPANY表:
sqlite> CREATE TABLE COMPANY( ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
现在,将以下记录插入COMPANY表:
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ( 'Paul', 32, 'California', 20000.00 ); INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ('Allen', 25, 'Texas', 15000.00 ); INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ('Teddy', 23, 'Norway', 20000.00 ); INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ( 'Mark', 25, 'Rich-Mond ', 65000.00 ); INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ( 'David', 27, 'Texas', 85000.00 ); INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ( 'Kim', 22, 'South-Hall', 45000.00 ); INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ( 'James', 24, 'Houston', 10000.00 );
这将向COMPANY表中插入7个元组,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
SQLite - 注入 (Injection)
如果您通过网页获取用户输入并将其插入SQLite数据库,则您可能已让自己容易受到称为SQL注入的安全问题的影响。在本章中,您将学习如何帮助防止这种情况的发生,并帮助您保护脚本和SQLite语句。
注入通常发生在您向用户索取输入(例如他们的姓名)时,他们给您的不是姓名,而是一个您会在不知情的情况下在数据库上运行的SQLite语句。
永远不要信任用户提供的数据,只有在验证后才能处理此数据;通常,这是通过模式匹配完成的。在以下示例中,用户名被限制为字母数字字符加上下划线,长度在8到20个字符之间——根据需要修改这些规则。
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){ $db = new SQLiteDatabase('filename'); $result = @$db->query("SELECT * FROM users WHERE username = $matches[0]"); } else { echo "username not accepted"; }
为了演示这个问题,请考虑以下摘录:
$name = "Qadir'; DELETE FROM users;"; @$db->query("SELECT * FROM users WHERE username = '{$name}'");
函数调用应该从用户表中检索一条记录,其中name列与用户指定的名称匹配。在正常情况下,$name 只包含字母数字字符和空格,例如字符串ilia。但是,在这种情况下,通过将一个全新的查询附加到$name,对数据库的调用变成了灾难:注入的DELETE查询删除了users表中的所有记录。
有些数据库接口不允许查询堆叠或在单个函数调用中执行多个查询。如果尝试堆叠查询,则调用会失败,但SQLite和PostgreSQL会愉快地执行堆叠查询,在一个字符串中执行所有提供的查询,从而造成严重的安全问题。
防止SQL注入
您可以在PERL和PHP等脚本语言中巧妙地处理所有转义字符。PHP编程语言提供函数sqlite_escape_string() 来转义对SQLite来说是特殊字符的输入字符。
if (get_magic_quotes_gpc()) { $name = sqlite_escape_string($name); } $result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");
虽然编码使得插入数据安全,但它会使包含二进制数据的列中简单的文本比较和LIKE子句不可用。
注意 − addslashes() 不应该用于为SQLite查询引用字符串;这会在检索数据时导致奇怪的结果。
SQLite - EXPLAIN
SQLite语句可以以关键字“EXPLAIN”或短语“EXPLAIN QUERY PLAN”开头,用于描述表的详细信息。
任何一种修改都会导致SQLite语句的行为像一个查询,并返回有关在省略EXPLAIN关键字或短语的情况下SQLite语句将如何操作的信息。
EXPLAIN和EXPLAIN QUERY PLAN的输出仅用于交互式分析和故障排除。
输出格式的细节可能会在SQLite的各个版本之间发生变化。
应用程序不应使用EXPLAIN或EXPLAIN QUERY PLAN,因为它们的精确行为是可变的,并且只有部分文档。
公元前 4714 年 11 月 24 日中午以来的天数
EXPLAIN语法如下:
EXPLAIN [SQLite Query]
EXPLAIN QUERY PLAN语法如下:
EXPLAIN QUERY PLAN [SQLite Query]
您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。
考虑具有以下记录的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语句检查以下子查询:
sqlite> EXPLAIN SELECT * FROM COMPANY WHERE Salary >= 20000;
这将产生以下结果。
addr opcode p1 p2 p3 ---------- ---------- ---------- ---------- ---------- 0 Goto 0 19 1 Integer 0 0 2 OpenRead 0 8 3 SetNumColu 0 5 4 Rewind 0 17 5 Column 0 4 6 RealAffini 0 0 7 Integer 20000 0 8 Lt 357 16 collseq(BI 9 Rowid 0 0 10 Column 0 1 11 Column 0 2 12 Column 0 3 13 Column 0 4 14 RealAffini 0 0 15 Callback 5 0 16 Next 0 5 17 Close 0 0 18 Halt 0 0 19 Transactio 0 0 20 VerifyCook 0 38 21 Goto 0 1 22 Noop 0 0
现在,让我们使用SELECT语句检查以下Explain Query Plan:
SQLite> EXPLAIN QUERY PLAN SELECT * FROM COMPANY WHERE Salary >= 20000; order from detail ---------- ---------- ------------- 0 0 TABLE COMPANY
SQLite - VACUUM
VACUUM命令通过将其内容复制到临时数据库文件并从副本重新加载原始数据库文件来清理主数据库。这消除了空闲页面,使表数据连续对齐,并以其他方式清理数据库文件结构。
VACUUM命令可能会更改没有显式INTEGER PRIMARY KEY的表中条目的ROWID。VACUUM命令仅适用于主数据库。无法VACUUM附加的数据库文件。
如果存在活动事务,VACUUM命令将失败。对于内存数据库,VACUUM命令是一个空操作。由于VACUUM命令从头开始重建数据库文件,因此VACUUM也可以用于修改许多数据库特定的配置参数。
手动VACUUM
以下是从命令提示符发出整个数据库的VACUUM命令的简单语法:
$sqlite3 database_name "VACUUM;"
您也可以从SQLite提示符运行VACUUM,如下所示:
sqlite> VACUUM;
您还可以对特定表运行VACUUM,如下所示:
sqlite> VACUUM table_name;
自动VACUUM
SQLite自动VACUUM的作用与VACUUM不同,它只将空闲页面移动到数据库的末尾,从而减小数据库的大小。这样做可能会严重碎片化数据库,而VACUUM确保碎片整理。因此,自动VACUUM只保持数据库较小。
您可以通过在SQLite提示符下运行以下pragma来启用/禁用SQLite自动真空:
sqlite> PRAGMA auto_vacuum = NONE; -- 0 means disable auto vacuum sqlite> PRAGMA auto_vacuum = FULL; -- 1 means enable full auto vacuum sqlite> PRAGMA auto_vacuum = INCREMENTAL; -- 2 means enable incremental vacuum
您可以从命令提示符运行以下命令来检查自动真空设置:
$sqlite3 database_name "PRAGMA auto_vacuum;"
SQLite - 日期和时间 (Date & Time)
SQLite支持以下五种日期和时间函数:
序号 | 函数 | 您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。 |
---|---|---|
1 | date(timestring, modifiers...) | 这将返回此格式的日期:YYYY-MM-DD |
2 | time(timestring, modifiers...) | 这将返回时间为HH:MM:SS |
3 | datetime(timestring, modifiers...) | 这将返回YYYY-MM-DD HH:MM:SS |
4 | julianday(timestring, modifiers...) | 这将返回公元前4714年11月24日中午以来的天数。 |
5 | strftime(timestring, modifiers...) | 这将根据指定为第一个参数的格式字符串返回日期,格式如下所示。 |
以上五个日期和时间函数都将时间字符串作为参数。时间字符串后面可以跟零个或多个修饰符。strftime()函数也以格式字符串作为其第一个参数。下一节将详细介绍不同类型的时间字符串和修饰符。
时间字符串
时间字符串可以采用以下任何格式:
序号 | 时间字符串 | 您可以选择以任何这些格式存储日期和时间,并使用内置的日期和时间函数在格式之间自由转换。 |
---|---|---|
1 | YYYY-MM-DD | 2010-12-30 |
2 | YYYY-MM-DD HH:MM | 2010-12-30 12:10 |
3 | YYYY-MM-DD HH:MM:SS.SSS | 2010-12-30 12:10:04.100 |
4 | MM-DD-YYYY HH:MM | 30-12-2010 12:10 |
5 | HH:MM | 12:10 |
6 | YYYY-MM-DDTHH:MM | 2010-12-30 12:10 |
7 | HH:MM:SS | 12:10:01 |
8 | YYYYMMDD HHMMSS | 20101230 121001 |
9 | now | 2013-05-07 |
您可以使用“T”作为分隔日期和时间的文字字符。
修饰符
时间字符串后面可以跟零个或多个修饰符,这些修饰符将更改上述五个函数返回的日期和/或时间。修饰符从左到右应用。
SQLite中提供以下修饰符:
- NNN天
- NNN小时
- NNN分钟
- NNN.NNNN秒
- NNN个月
- NNN年
- 月初
- 年初
- 一日之初
- 星期几N
- unixepoch
- localtime
- utc
格式化程序
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是星期日) |
%W | 一年中的星期数,01-53 |
%Y | 年份,YYYY |
%% | %符号 |
示例
现在让我们尝试使用SQLite提示符使用各种示例。以下命令计算当前日期。
sqlite> SELECT date('now'); 2013-05-07
以下命令计算当前月份的最后一天。
sqlite> SELECT date('now','start of month','+1 month','-1 day'); 2013-05-31
以下命令计算给定UNIX时间戳1092941466的日期和时间。
sqlite> SELECT datetime(1092941466, 'unixepoch'); 2004-08-19 18:51:06
以下命令计算给定UNIX时间戳1092941466的日期和时间,并补偿您的本地时区。
sqlite> SELECT datetime(1092941466, 'unixepoch', 'localtime'); 2004-08-19 13:51:06
以下命令计算当前UNIX时间戳。
sqlite> SELECT strftime('%s','now'); 1393348134
以下命令计算自美国《独立宣言》签署以来的天数。
sqlite> SELECT julianday('now') - julianday('1776-07-04'); 86798.7094695023
以下命令计算自2004年特定时刻以来的秒数。
sqlite> SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56'); 295001572
以下命令计算当前年份10月份第一个星期二的日期。
sqlite> SELECT date('now','start of year','+9 months','weekday 2'); 2013-10-01
以下命令计算自UNIX纪元以来的秒数(类似于strftime('%s','now'),但包含小数部分)。
sqlite> SELECT (julianday('now') - 2440587.5)*86400.0; 1367926077.12598
要在格式化日期时在UTC和本地时间值之间转换,请使用utc或localtime修饰符,如下所示:
sqlite> SELECT time('12:00', 'localtime'); 05:00:00
sqlite> SELECT time('12:00', 'utc'); 19:00:00
SQLite - 有用函数
SQLite有许多内置函数可以对字符串或数字数据进行处理。以下是几个有用的SQLite内置函数的列表,所有这些函数都不区分大小写,这意味着您可以使用这些函数的小写形式、大写形式或混合形式。有关更多详细信息,您可以查看SQLite的官方文档。
序号 | 函数和描述 |
---|---|
1 | SQLite COUNT函数 SQLite COUNT聚合函数用于计算数据库表中的行数。 |
2 | SQLite MAX函数 SQLite MAX聚合函数允许我们为某个列选择最高(最大)值。 |
3 | SQLite MIN函数 SQLite MIN聚合函数允许我们为某个列选择最低(最小)值。 |
4 | SQLite AVG函数 SQLite AVG聚合函数选择某个表列的平均值。 |
5 | SQLite SUM函数 SQLite SUM聚合函数允许选择数字列的总和。 |
6 | SQLite RANDOM函数 SQLite RANDOM函数返回-9223372036854775808和+9223372036854775807之间的伪随机整数。 |
7 | SQLite ABS函数 SQLite ABS函数返回数字参数的绝对值。 |
8 | SQLite UPPER函数 SQLite UPPER函数将字符串转换为大写字母。 |
9 | SQLite LOWER函数 SQLite LOWER函数将字符串转换为小写字母。 |
10 | SQLite LENGTH函数 SQLite LENGTH函数返回字符串的长度。 |
11 | SQLite sqlite_version函数 SQLite sqlite_version函数返回SQLite库的版本。 |
在我们开始对上述函数进行示例之前,请考虑包含以下记录的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
SQLite COUNT函数
SQLite COUNT聚合函数用于计算数据库表中的行数。以下是一个示例:
sqlite> SELECT count(*) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
count(*) ---------- 7
SQLite MAX函数
SQLite MAX聚合函数允许我们为某个列选择最高(最大)值。以下是一个示例:
sqlite> SELECT max(salary) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
max(salary) ----------- 85000.0
SQLite MIN函数
SQLite MIN聚合函数允许我们为某个列选择最低(最小)值。以下是一个示例:
sqlite> SELECT min(salary) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
min(salary) ----------- 10000.0
SQLite AVG函数
SQLite AVG聚合函数选择某个表列的平均值。以下是一个示例:
sqlite> SELECT avg(salary) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
avg(salary) ---------------- 37142.8571428572
SQLite SUM函数
SQLite SUM聚合函数允许选择数字列的总和。以下是一个示例:
sqlite> SELECT sum(salary) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
sum(salary) ----------- 260000.0
SQLite RANDOM函数
SQLite RANDOM函数返回-9223372036854775808和+9223372036854775807之间的伪随机整数。以下是一个示例:
sqlite> SELECT random() AS Random;
上述SQLite SQL语句将产生以下结果。
Random ------------------- 5876796417670984050
SQLite ABS函数
SQLite ABS函数返回数字参数的绝对值。以下是一个示例:
sqlite> SELECT abs(5), abs(-15), abs(NULL), abs(0), abs("ABC");
上述SQLite SQL语句将产生以下结果。
abs(5) abs(-15) abs(NULL) abs(0) abs("ABC") ---------- ---------- ---------- ---------- ---------- 5 15 0 0.0
SQLite UPPER函数
SQLite UPPER函数将字符串转换为大写字母。以下是一个示例:
sqlite> SELECT upper(name) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
upper(name) ----------- PAUL ALLEN TEDDY MARK DAVID KIM JAMES
SQLite LOWER函数
SQLite LOWER函数将字符串转换为小写字母。以下是一个示例:
sqlite> SELECT lower(name) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
lower(name) ----------- paul allen teddy mark david kim james
SQLite LENGTH函数
SQLite LENGTH函数返回字符串的长度。以下是一个示例:
sqlite> SELECT name, length(name) FROM COMPANY;
上述SQLite SQL语句将产生以下结果。
NAME length(name) ---------- ------------ Paul 4 Allen 5 Teddy 5 Mark 4 David 5 Kim 3 James 5
SQLite sqlite_version函数
SQLite sqlite_version函数返回SQLite库的版本。以下是一个示例:
sqlite> SELECT sqlite_version() AS 'SQLite Version';
上述SQLite SQL语句将产生以下结果。
SQLite Version -------------- 3.6.20
SQLite - C/C++
在本章中,您将学习如何在C/C++程序中使用SQLite。
安装
在开始在C/C++程序中使用SQLite之前,您需要确保机器上已设置SQLite库。您可以查看SQLite安装章节以了解安装过程。
C/C++接口API
以下是重要的C/C++ SQLite接口例程,这些例程足以满足您从C/C++程序使用SQLite数据库的要求。如果您正在寻找更复杂的应用程序,那么您可以查看SQLite官方文档。
序号 | API和描述 |
---|---|
1 | sqlite3_open(const char *filename, sqlite3 **ppDb) 此例程打开到SQLite数据库文件的连接,并返回一个数据库连接对象,供其他SQLite例程使用。 如果filename参数为NULL或':memory:',sqlite3_open()将在RAM中创建一个仅在会话期间持续存在的内存数据库。 如果文件名不为NULL,sqlite3_open()将尝试使用其值打开数据库文件。如果不存在该名称的文件,sqlite3_open()将使用该名称打开一个新的数据库文件。 |
2 | sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg) 此例程提供了一种快速简便的方法来执行由sql参数提供的SQL命令,该参数可以包含多个SQL命令。 这里,第一个参数sqlite3是一个打开的数据库对象,sqlite_callback是一个回调函数,data是其第一个参数,errmsg将被返回以捕获例程引发的任何错误。 SQLite3_exec()例程解析并执行sql参数中给出的每个命令,直到到达字符串结尾或遇到错误。 |
3 | sqlite3_close(sqlite3*) 此例程关闭先前通过调用sqlite3_open()打开的数据库连接。所有与连接关联的预处理语句都应在关闭连接之前完成。 如果仍有未完成的查询,sqlite3_close()将返回SQLITE_BUSY,并显示错误消息“由于未完成的语句而无法关闭”。 |
连接到数据库
以下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)); return(0); } else { fprintf(stderr, "Opened database successfully\n"); } sqlite3_close(db); }
现在,让我们编译并运行上述程序,在当前目录中创建我们的数据库test.db。您可以根据需要更改路径。
$gcc test.c -l sqlite3 $./a.out Opened database successfully
如果您要使用C++源代码,则可以按如下方式编译代码:
$g++ test.c -l sqlite3
在这里,我们将程序与sqlite3库链接,以便为C程序提供必要的函数。这将在您的目录中创建一个数据库文件test.db,您将得到以下结果。
-rwxr-xr-x. 1 root root 7383 May 8 02:06 a.out -rw-r--r--. 1 root root 323 May 8 02:05 test.c -rw-r--r--. 1 root root 0 May 8 02:06 test.db
创建表
以下C代码段将用于在先前创建的数据库中创建表:
#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)); return(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; }
编译并执行上述程序后,它将在您的test.db中创建COMPANY表,文件的最终列表如下:
-rwxr-xr-x. 1 root root 9567 May 8 02:31 a.out -rw-r--r--. 1 root root 1207 May 8 02:31 test.c -rw-r--r--. 1 root root 3072 May 8 02:31 test.db
INSERT操作
以下C代码段显示了如何在上面示例中创建的COMPANY表中创建记录:
#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)); return(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; }
编译并执行上述程序后,它将在COMPANY表中创建给定的记录,并将显示以下两行:
Opened database successfully Records created successfully
SELECT操作
在继续实际的提取记录示例之前,让我们详细了解一下我们在示例中使用的回调函数。此回调提供了一种从SELECT语句中获取结果的方法。它具有以下声明:
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 */ );
如果在sqlite_exec()例程中将上述回调作为第三个参数提供,则SQLite将为SQL参数中执行的每个SELECT语句中处理的每条记录调用此回调函数。
以下C代码段显示了如何从上面示例中创建的COMPANY表中提取和显示记录:
#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)); return(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; }
编译并执行上述程序后,将产生以下结果。
Opened database successfully Callback function called: ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 20000.0 Callback function called: ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 Callback function called: ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 Callback function called: ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
UPDATE操作
以下C代码段显示了如何使用UPDATE语句更新任何记录,然后从COMPANY表中提取和显示更新后的记录。
#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)); return(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; }
编译并执行上述程序后,将产生以下结果。
Opened database successfully Callback function called: ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 25000.0 Callback function called: ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 Callback function called: ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 Callback function called: ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
DELETE操作
以下C代码段显示了如何使用DELETE语句删除任何记录,然后从COMPANY表中提取和显示剩余的记录。
#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)); return(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; }
编译并执行上述程序后,将产生以下结果。
Opened database successfully Callback function called: ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 20000.0 Callback function called: ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 Callback function called: ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
SQLite - Java
本章将学习如何在Java程序中使用SQLite。
安装
在开始在Java程序中使用SQLite之前,您需要确保已在计算机上安装SQLite JDBC驱动程序和Java。您可以查看Java教程,了解如何在您的计算机上安装Java。现在,让我们检查如何设置SQLite JDBC驱动程序。
从sqlite-jdbc存储库下载最新版本的sqlite-jdbc-(VERSION).jar。
将下载的jar文件sqlite-jdbc-(VERSION).jar添加到您的类路径中,或者您可以将其与-classpath选项一起使用,如下例所示。
以下部分假设您对Java JDBC概念略知一二。如果您不了解,建议您花半小时时间学习JDBC教程,以便更好地理解以下内容。
连接到数据库
以下Java程序显示了如何连接到现有数据库。如果数据库不存在,则将创建它,最后返回一个数据库对象。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Opened database successfully"); } }
现在,让我们编译并运行上述程序,在当前目录中创建我们的数据库test.db。您可以根据需要更改路径。我们假设当前版本的JDBC驱动程序sqlite-jdbc-3.7.2.jar位于当前路径中。
$javac SQLiteJDBC.java $java -classpath ".:sqlite-jdbc-3.7.2.jar" SQLiteJDBC Open database successfully
如果您要使用Windows机器,则可以按如下方式编译和运行代码:
$javac SQLiteJDBC.java $java -classpath ".;sqlite-jdbc-3.7.2.jar" SQLiteJDBC Opened database successfully
创建表
以下Java程序将用于在先前创建的数据库中创建表。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "CREATE TABLE COMPANY " + "(ID INT PRIMARY KEY NOT NULL," + " NAME TEXT NOT NULL, " + " AGE INT NOT NULL, " + " ADDRESS CHAR(50), " + " SALARY REAL)"; stmt.executeUpdate(sql); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Table created successfully"); } }
编译并执行上述程序后,它将在您的test.db中创建COMPANY表,文件的最终列表如下:
-rw-r--r--. 1 root root 3201128 Jan 22 19:04 sqlite-jdbc-3.7.2.jar -rw-r--r--. 1 root root 1506 May 8 05:43 SQLiteJDBC.class -rw-r--r--. 1 root root 832 May 8 05:42 SQLiteJDBC.java -rw-r--r--. 1 root root 3072 May 8 05:43 test.db
INSERT操作
以下Java程序显示了如何在上面示例中创建的COMPANY表中创建记录。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (1, 'Paul', 32, 'California', 20000.00 );"; stmt.executeUpdate(sql); sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (2, 'Allen', 25, 'Texas', 15000.00 );"; stmt.executeUpdate(sql); sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );"; stmt.executeUpdate(sql); sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );"; stmt.executeUpdate(sql); stmt.close(); c.commit(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Records created successfully"); } }
编译并执行上述程序后,它将在COMPANY表中创建给定的记录,并将显示以下两行:
Opened database successfully Records created successfully
SELECT操作
以下Java程序显示了如何从上面示例中创建的COMPANY表中提取和显示记录。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" ); while ( rs.next() ) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println( "ID = " + id ); System.out.println( "NAME = " + name ); System.out.println( "AGE = " + age ); System.out.println( "ADDRESS = " + address ); System.out.println( "SALARY = " + salary ); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Operation done successfully"); } }
编译并执行上述程序后,将产生以下结果。
Opened database successfully ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 20000.0 ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
UPDATE操作
以下Java代码显示了如何使用UPDATE语句更新任何记录,然后从COMPANY表中提取和显示更新后的记录。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1;"; stmt.executeUpdate(sql); c.commit(); ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" ); while ( rs.next() ) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println( "ID = " + id ); System.out.println( "NAME = " + name ); System.out.println( "AGE = " + age ); System.out.println( "ADDRESS = " + address ); System.out.println( "SALARY = " + salary ); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Operation done successfully"); } }
编译并执行上述程序后,将产生以下结果。
Opened database successfully ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 25000.0 ID = 2 NAME = Allen AGE = 25 ADDRESS = Texas SALARY = 15000.0 ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
DELETE操作
以下Java代码显示了如何使用DELETE语句删除任何记录,然后从我们的COMPANY表中提取和显示剩余的记录。
import java.sql.*; public class SQLiteJDBC { public static void main( String args[] ) { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully"); stmt = c.createStatement(); String sql = "DELETE from COMPANY where ID=2;"; stmt.executeUpdate(sql); c.commit(); ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" ); while ( rs.next() ) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println( "ID = " + id ); System.out.println( "NAME = " + name ); System.out.println( "AGE = " + age ); System.out.println( "ADDRESS = " + address ); System.out.println( "SALARY = " + salary ); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch ( Exception e ) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); System.exit(0); } System.out.println("Operation done successfully"); } }
编译并执行上述程序后,将产生以下结果。
Opened database successfully ID = 1 NAME = Paul AGE = 32 ADDRESS = California SALARY = 25000.0 ID = 3 NAME = Teddy AGE = 23 ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark AGE = 25 ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
SQLite - PHP
本章将学习如何在PHP程序中使用SQLite。
安装
从PHP 5.3.0开始,SQLite3扩展默认启用。可以使用--without-sqlite3在编译时禁用它。
Windows用户必须启用php_sqlite3.dll才能使用此扩展。从PHP 5.3.0开始,此DLL包含在Windows版本的PHP中。
有关详细的安装说明,请查看我们的PHP教程及其官方网站。
PHP接口API
以下是重要的PHP例程,可以满足您从PHP程序使用SQLite数据库的要求。如果您正在寻找更复杂的应用程序,则可以查看PHP官方文档。
序号 | API和描述 |
---|---|
1 | public void SQLite3::open ( filename, flags, encryption_key ) 打开SQLite 3数据库。如果构建包含加密,则它将尝试使用密钥。 如果将filename指定为':memory:',则SQLite3::open()将在RAM中创建一个内存数据库,该数据库仅在会话期间存在。 如果文件名是实际的设备文件名,则SQLite3::open()尝试使用其值打开数据库文件。如果不存在该名称的文件,则将创建一个同名的新数据库文件。 可选标志用于确定如何打开SQLite数据库。默认情况下,open使用SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE。 |
2 | public bool SQLite3::exec ( string $query ) 此例程提供了一种快速简便的方法来执行sql参数提供的SQL命令,该参数可以包含多个SQL命令。此例程用于对给定数据库执行无结果查询。 |
3 | public SQLite3Result SQLite3::query ( string $query ) 此例程执行SQL查询,如果查询返回结果,则返回一个SQLite3Result对象。 |
4 | public int SQLite3::lastErrorCode ( void ) 此例程返回最近一次失败的SQLite请求的数字结果代码。 |
5 | public string SQLite3::lastErrorMsg ( void ) 此例程返回描述最近一次失败的SQLite请求的英文文本。 |
6 | public int SQLite3::changes ( void ) 此例程返回由最近的SQL语句更新、插入或删除的数据库行的数量。 |
7 | public bool SQLite3::close ( void ) 此例程关闭先前通过调用SQLite3::open()打开的数据库连接。 |
8 | public string SQLite3::escapeString ( string $value ) 此例程返回已正确转义以安全包含在SQL语句中的字符串。 |
连接到数据库
以下PHP代码显示了如何连接到现有数据库。如果数据库不存在,则将创建它,最后返回一个数据库对象。
<?php class MyDB extends SQLite3 { function __construct() { $this->open('test.db'); } } $db = new MyDB(); if(!$db) { echo $db->lastErrorMsg(); } else { echo "Opened database successfully\n"; } ?>
现在,让我们运行上述程序,在当前目录中创建我们的数据库test.db。您可以根据需要更改路径。如果数据库成功创建,则将显示以下消息:
Open database successfully
创建表
以下PHP程序将用于在先前创建的数据库中创建表。
<?php class MyDB extends SQLite3 { function __construct() { $this->open('test.db'); } } $db = new MyDB(); if(!$db) { echo $db->lastErrorMsg(); } else { echo "Opened database successfully\n"; } $sql =<<<EOF CREATE TABLE COMPANY (ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL); EOF; $ret = $db->exec($sql); if(!$ret){ echo $db->lastErrorMsg(); } else { echo "Table created successfully\n"; } $db->close(); ?>
执行上述程序后,它将在您的test.db中创建COMPANY表,并将显示以下消息:
Opened database successfully Table created successfully
INSERT操作
以下PHP程序显示了如何在上面示例中创建的COMPANY表中创建记录。
<?php class MyDB extends SQLite3 { function __construct() { $this->open('test.db'); } } $db = new MyDB(); if(!$db){ echo $db->lastErrorMsg(); } else { echo "Opened database successfully\n"; } $sql =<<<EOF 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 ); EOF; $ret = $db->exec($sql); if(!$ret) { echo $db->lastErrorMsg(); } else { echo "Records created successfully\n"; } $db->close(); ?>
执行上述程序后,它将在COMPANY表中创建给定的记录,并将显示以下两行。
Opened database successfully Records created successfully
SELECT操作
以下PHP程序显示了如何从上面示例中创建的COMPANY表中提取和显示记录:
<?php class MyDB extends SQLite3 { function __construct() { $this->open('test.db'); } } $db = new MyDB(); if(!$db) { echo $db->lastErrorMsg(); } else { echo "Opened database successfully\n"; } $sql =<<<EOF SELECT * from COMPANY; EOF; $ret = $db->query($sql); while($row = $ret->fetchArray(SQLITE3_ASSOC) ) { echo "ID = ". $row['ID'] . "\n"; echo "NAME = ". $row['NAME'] ."\n"; echo "ADDRESS = ". $row['ADDRESS'] ."\n"; echo "SALARY = ".$row['SALARY'] ."\n\n"; } echo "Operation done successfully\n"; $db->close(); ?>
执行上述程序后,将产生以下结果。
Opened database successfully ID = 1 NAME = Paul ADDRESS = California SALARY = 20000 ID = 2 NAME = Allen ADDRESS = Texas SALARY = 15000 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000 Operation done successfully
UPDATE操作
以下PHP代码显示了如何使用UPDATE语句更新任何记录,然后从COMPANY表中提取和显示更新后的记录。
<?php class MyDB extends SQLite3 { function __construct() { $this->open('test.db'); } } $db = new MyDB(); if(!$db) { echo $db->lastErrorMsg(); } else { echo "Opened database successfully\n"; } $sql =<<<EOF UPDATE COMPANY set SALARY = 25000.00 where ID=1; EOF; $ret = $db->exec($sql); if(!$ret) { echo $db->lastErrorMsg(); } else { echo $db->changes(), " Record updated successfully\n"; } $sql =<<<EOF SELECT * from COMPANY; EOF; $ret = $db->query($sql); while($row = $ret->fetchArray(SQLITE3_ASSOC) ) { echo "ID = ". $row['ID'] . "\n"; echo "NAME = ". $row['NAME'] ."\n"; echo "ADDRESS = ". $row['ADDRESS'] ."\n"; echo "SALARY = ".$row['SALARY'] ."\n\n"; } echo "Operation done successfully\n"; $db->close(); ?>
执行上述程序后,将产生以下结果。
Opened database successfully 1 Record updated successfully ID = 1 NAME = Paul ADDRESS = California SALARY = 25000 ID = 2 NAME = Allen ADDRESS = Texas SALARY = 15000 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000 Operation done successfully
DELETE操作
以下PHP代码显示了如何使用DELETE语句删除任何记录,然后从COMPANY表中提取和显示剩余的记录。
<?php class MyDB extends SQLite3 { function __construct() { $this->open('test.db'); } } $db = new MyDB(); if(!$db) { echo $db->lastErrorMsg(); } else { echo "Opened database successfully\n"; } $sql =<<<EOF DELETE from COMPANY where ID = 2; EOF; $ret = $db->exec($sql); if(!$ret){ echo $db->lastErrorMsg(); } else { echo $db->changes(), " Record deleted successfully\n"; } $sql =<<<EOF SELECT * from COMPANY; EOF; $ret = $db->query($sql); while($row = $ret->fetchArray(SQLITE3_ASSOC) ) { echo "ID = ". $row['ID'] . "\n"; echo "NAME = ". $row['NAME'] ."\n"; echo "ADDRESS = ". $row['ADDRESS'] ."\n"; echo "SALARY = ".$row['SALARY'] ."\n\n"; } echo "Operation done successfully\n"; $db->close(); ?>
执行上述程序后,将产生以下结果。
Opened database successfully 1 Record deleted successfully ID = 1 NAME = Paul ADDRESS = California SALARY = 25000 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000 Operation done successfully
SQLite - Perl
本章将学习如何在Perl程序中使用SQLite。
安装
可以使用Perl DBI模块将SQLite3与Perl集成,该模块是Perl编程语言的数据库访问模块。它定义了一组方法、变量和约定,这些方法、变量和约定提供标准的数据库接口。
以下是在Linux/UNIX机器上安装DBI模块的简单步骤:
$ wget http://search.cpan.org/CPAN/authors/id/T/TI/TIMB/DBI-1.625.tar.gz $ tar xvfz DBI-1.625.tar.gz $ cd DBI-1.625 $ perl Makefile.PL $ make $ make install
如果需要为DBI安装SQLite驱动程序,则可以按如下方式安装:
$ wget http://search.cpan.org/CPAN/authors/id/M/MS/MSERGEANT/DBD-SQLite-1.11.tar.gz $ tar xvfz DBD-SQLite-1.11.tar.gz $ cd DBD-SQLite-1.11 $ perl Makefile.PL $ make $ make install
DBI接口API
以下是重要的DBI例程,可以满足您从Perl程序使用SQLite数据库的要求。如果您正在寻找更复杂的应用程序,则可以查看Perl DBI官方文档。
序号 | API和描述 |
---|---|
1 | DBI->connect($data_source, "", "", \%attr) 建立到请求的$data_source的数据库连接或会话。如果连接成功,则返回数据库句柄对象。 数据源具有以下形式:DBI:SQLite:dbname = 'test.db',其中SQLite是SQLite驱动程序名称,test.db是SQLite数据库文件的名称。如果文件名指定为':memory:',它将在RAM中创建一个内存数据库,该数据库仅在会话期间存在。 如果文件名是实际的设备文件名,则它尝试使用其值打开数据库文件。如果不存在该名称的文件,则将创建一个同名的新数据库文件。 您可以将第二个和第三个参数保留为空字符串,最后一个参数用于传递各种属性,如下例所示。 |
2 | $dbh->do($sql) 此例程准备并执行单个SQL语句。返回受影响的行数或错误时的未定义值。返回值-1表示行数未知、不适用或不可用。这里,$dbh是由DBI->connect()调用返回的句柄。 |
3 |
$dbh->prepare($sql) 此例程准备由数据库引擎稍后执行的语句,并返回对语句句柄对象的引用。 |
4 |
$sth->execute() 此例程执行执行已准备语句所需的任何处理。如果发生错误,则返回未定义值。成功的执行始终返回true,而不管受影响的行数是多少。这里,$sth是由$dbh->prepare($sql)调用返回的语句句柄。 |
5 |
$sth->fetchrow_array() 此例程提取下一行数据,并将其作为包含字段值的列表返回。空字段在列表中返回为未定义值。 |
6 |
$DBI::err 这等效于$h->err,其中$h是任何句柄类型,例如$dbh、$sth或$drh。这将返回上次调用的驱动程序方法的本机数据库引擎错误代码。 |
7 |
$DBI::errstr 这等效于$h->errstr,其中$h是任何句柄类型,例如$dbh、$sth或$drh。这将返回上次调用的DBI方法的本机数据库引擎错误消息。 |
8 |
$dbh->disconnect() 此例程关闭先前通过调用 DBI->connect() 打开的数据库连接。 |
连接到数据库
下面的 Perl 代码演示如何连接到现有数据库。如果数据库不存在,则会创建它,最后返回一个数据库对象。
#!/usr/bin/perl use DBI; use strict; my $driver = "SQLite"; my $database = "test.db"; my $dsn = "DBI:$driver:dbname=$database"; my $userid = ""; my $password = ""; my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr; print "Opened database successfully\n";
现在,让我们运行上面的程序在当前目录中创建我们的数据库 test.db。您可以根据需要更改路径。将上面的代码保存在 sqlite.pl 文件中,并按如下所示执行它。如果数据库成功创建,则会显示以下消息:
$ chmod +x sqlite.pl $ ./sqlite.pl Open database successfully
创建表
下面的 Perl 程序用于在先前创建的数据库中创建表。
#!/usr/bin/perl use DBI; use strict; my $driver = "SQLite"; my $database = "test.db"; my $dsn = "DBI:$driver:dbname=$database"; my $userid = ""; my $password = ""; my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr; print "Opened database successfully\n"; my $stmt = qq(CREATE TABLE COMPANY (ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL);); my $rv = $dbh->do($stmt); if($rv < 0) { print $DBI::errstr; } else { print "Table created successfully\n"; } $dbh->disconnect();
执行上述程序后,它将在您的 test.db 中创建 COMPANY 表,并将显示以下消息:
Opened database successfully Table created successfully
注意 - 如果在任何操作中看到以下错误:
DBD::SQLite::st execute failed: not an error(21) at dbdimp.c line 398
在这种情况下,打开 DBD-SQLite 安装中提供的dbdimp.c 文件,找到sqlite3_prepare() 函数,将其第三个参数从0更改为-1。最后,使用make安装 DBD::SQLite,并执行make install以解决问题。
INSERT操作
下面的 Perl 程序演示如何在上面示例中创建的 COMPANY 表中创建记录。
#!/usr/bin/perl use DBI; use strict; my $driver = "SQLite"; my $database = "test.db"; my $dsn = "DBI:$driver:dbname=$database"; my $userid = ""; my $password = ""; my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr; print "Opened database successfully\n"; my $stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00 )); my $rv = $dbh->do($stmt) or die $DBI::errstr; $stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (2, 'Allen', 25, 'Texas', 15000.00 )); $rv = $dbh->do($stmt) or die $DBI::errstr; $stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )); $rv = $dbh->do($stmt) or die $DBI::errstr; $stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );); $rv = $dbh->do($stmt) or die $DBI::errstr; print "Records created successfully\n"; $dbh->disconnect();
执行上述程序后,它将在 COMPANY 表中创建给定的记录,并将显示以下两行:
Opened database successfully Records created successfully
SELECT操作
下面的 Perl 程序演示如何从上面示例中创建的 COMPANY 表中提取和显示记录。
#!/usr/bin/perl use DBI; use strict; my $driver = "SQLite"; my $database = "test.db"; my $dsn = "DBI:$driver:dbname=$database"; my $userid = ""; my $password = ""; my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr; print "Opened database successfully\n"; my $stmt = qq(SELECT id, name, address, salary from COMPANY;); my $sth = $dbh->prepare( $stmt ); my $rv = $sth->execute() or die $DBI::errstr; if($rv < 0) { print $DBI::errstr; } while(my @row = $sth->fetchrow_array()) { print "ID = ". $row[0] . "\n"; print "NAME = ". $row[1] ."\n"; print "ADDRESS = ". $row[2] ."\n"; print "SALARY = ". $row[3] ."\n\n"; } print "Operation done successfully\n"; $dbh->disconnect();
执行上述程序后,将产生以下结果。
Opened database successfully ID = 1 NAME = Paul ADDRESS = California SALARY = 20000 ID = 2 NAME = Allen ADDRESS = Texas SALARY = 15000 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000 Operation done successfully
UPDATE操作
下面的 Perl 代码演示如何使用 UPDATE 语句更新任何记录,然后从 COMPANY 表中提取和显示更新后的记录。
#!/usr/bin/perl use DBI; use strict; my $driver = "SQLite"; my $database = "test.db"; my $dsn = "DBI:$driver:dbname=$database"; my $userid = ""; my $password = ""; my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr; print "Opened database successfully\n"; my $stmt = qq(UPDATE COMPANY set SALARY = 25000.00 where ID=1;); my $rv = $dbh->do($stmt) or die $DBI::errstr; if( $rv < 0 ) { print $DBI::errstr; } else { print "Total number of rows updated : $rv\n"; } $stmt = qq(SELECT id, name, address, salary from COMPANY;); my $sth = $dbh->prepare( $stmt ); $rv = $sth->execute() or die $DBI::errstr; if($rv < 0) { print $DBI::errstr; } while(my @row = $sth->fetchrow_array()) { print "ID = ". $row[0] . "\n"; print "NAME = ". $row[1] ."\n"; print "ADDRESS = ". $row[2] ."\n"; print "SALARY = ". $row[3] ."\n\n"; } print "Operation done successfully\n"; $dbh->disconnect();
执行上述程序后,将产生以下结果。
Opened database successfully Total number of rows updated : 1 ID = 1 NAME = Paul ADDRESS = California SALARY = 25000 ID = 2 NAME = Allen ADDRESS = Texas SALARY = 15000 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000 Operation done successfully
DELETE操作
下面的 Perl 代码演示如何使用 DELETE 语句删除任何记录,然后从 COMPANY 表中提取和显示剩余的记录:
#!/usr/bin/perl use DBI; use strict; my $driver = "SQLite"; my $database = "test.db"; my $dsn = "DBI:$driver:dbname=$database"; my $userid = ""; my $password = ""; my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 }) or die $DBI::errstr; print "Opened database successfully\n"; my $stmt = qq(DELETE from COMPANY where ID = 2;); my $rv = $dbh->do($stmt) or die $DBI::errstr; if( $rv < 0 ) { print $DBI::errstr; } else { print "Total number of rows deleted : $rv\n"; } $stmt = qq(SELECT id, name, address, salary from COMPANY;); my $sth = $dbh->prepare( $stmt ); $rv = $sth->execute() or die $DBI::errstr; if($rv < 0) { print $DBI::errstr; } while(my @row = $sth->fetchrow_array()) { print "ID = ". $row[0] . "\n"; print "NAME = ". $row[1] ."\n"; print "ADDRESS = ". $row[2] ."\n"; print "SALARY = ". $row[3] ."\n\n"; } print "Operation done successfully\n"; $dbh->disconnect();
执行上述程序后,将产生以下结果。
Opened database successfully Total number of rows deleted : 1 ID = 1 NAME = Paul ADDRESS = California SALARY = 25000 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000 Operation done successfully
SQLite - Python
本章将学习如何在 Python 程序中使用 SQLite。
安装
SQLite3 可以使用 sqlite3 模块与 Python 集成,该模块由 Gerhard Haring 编写。它提供了一个符合 PEP 249 中描述的 DB-API 2.0 规范的 SQL 接口。您无需单独安装此模块,因为它默认随 Python 2.5.x 及更高版本一起提供。
要使用 sqlite3 模块,必须首先创建一个表示数据库的连接对象,然后可以选择创建一个游标对象,这将有助于执行所有 SQL 语句。
Python sqlite3 模块 API
以下是重要的 sqlite3 模块例程,足以满足您从 Python 程序中使用 SQLite 数据库的需求。如果您正在寻找更复杂的应用程序,则可以查看 Python sqlite3 模块的官方文档。
序号 | API和描述 |
---|---|
1 | sqlite3.connect(database [,timeout ,其他可选参数]) 此 API 打开到 SQLite 数据库文件的连接。您可以使用“:memory:”打开到驻留在 RAM 中而不是磁盘上的数据库的数据库连接。如果成功打开数据库,则返回一个连接对象。 当多个连接访问数据库时,如果其中一个进程修改了数据库,则 SQLite 数据库将被锁定,直到该事务提交为止。timeout 参数指定连接应该等待锁消失多长时间,然后再引发异常。timeout 参数的默认值为 5.0(五秒)。 如果给定的数据库名称不存在,则此调用将创建数据库。如果要创建数据库在当前目录之外的其他位置,则也可以指定带有所需路径的文件名。 |
2 | connection.cursor([cursorClass]) 此例程创建一个游标,它将在使用 Python 进行数据库编程的过程中使用。此方法接受单个可选参数 cursorClass。如果提供,则必须是扩展 sqlite3.Cursor 的自定义游标类。 |
3 | cursor.execute(sql [, 可选参数]) 此例程执行 SQL 语句。SQL 语句可以是参数化的(即占位符而不是 SQL 字面量)。sqlite3 模块支持两种占位符:问号和命名占位符(命名样式)。 例如 - cursor.execute("insert into people values (?, ?)", (who, age)) |
4 | connection.execute(sql [, 可选参数]) 此例程是游标对象提供的上述 execute 方法的快捷方式,它通过调用 cursor 方法创建一个中间游标对象,然后使用给定的参数调用游标的 execute 方法。 |
5 | cursor.executemany(sql, seq_of_parameters) 此例程针对在序列 sql 中找到的所有参数序列或映射执行 SQL 命令。 |
6 | connection.executemany(sql[, parameters]) 此例程是一个快捷方式,它通过调用 cursor 方法创建一个中间游标对象,然后使用给定的参数调用 cursor.s executemany 方法。 |
7 | cursor.executescript(sql_script) 此例程以脚本形式执行多个 SQL 语句。它首先发出 COMMIT 语句,然后执行它作为参数获得的 SQL 脚本。所有 SQL 语句都应该用分号 (;) 分隔。 |
8 | connection.executescript(sql_script) 此例程是一个快捷方式,它通过调用 cursor 方法创建一个中间游标对象,然后使用给定的参数调用游标的 executescript 方法。 |
9 | connection.total_changes() 此例程返回自打开数据库连接以来已修改、插入或删除的数据库行的总数。 |
10 | connection.commit() 此方法提交当前事务。如果您不调用此方法,则自上次调用 commit() 以来所做的任何操作都无法从其他数据库连接中看到。 |
11 | connection.rollback() 此方法回滚自上次调用 commit() 以来对数据库所做的任何更改。 |
12 | connection.close() 此方法关闭数据库连接。请注意,这不会自动调用 commit()。如果您在首先调用 commit() 之前关闭数据库连接,则您的更改将会丢失! |
13 | cursor.fetchone() 此方法提取查询结果集的下一行,返回单个序列,或者当没有更多数据可用时返回 None。 |
14 | cursor.fetchmany([size = cursor.arraysize]) 此例程提取查询结果的下一组行,返回一个列表。当没有更多行可用时,将返回一个空列表。该方法尝试提取 size 参数指示的尽可能多的行。 |
15 | cursor.fetchall() 此例程提取查询结果的所有(剩余)行,返回一个列表。当没有行可用时,将返回一个空列表。 |
连接到数据库
下面的 Python 代码演示如何连接到现有数据库。如果数据库不存在,则会创建它,最后返回一个数据库对象。
#!/usr/bin/python import sqlite3 conn = sqlite3.connect('test.db') print "Opened database successfully";
在这里,您还可以将数据库名称提供为特殊名称:memory: 以在 RAM 中创建数据库。现在,让我们运行上面的程序在当前目录中创建我们的数据库test.db。您可以根据需要更改路径。将上面的代码保存在 sqlite.py 文件中,并按如下所示执行它。如果数据库成功创建,则会显示以下消息。
$chmod +x sqlite.py $./sqlite.py Open database successfully
创建表
下面的 Python 程序将用于在先前创建的数据库中创建表。
#!/usr/bin/python import sqlite3 conn = sqlite3.connect('test.db') print "Opened database successfully"; conn.execute('''CREATE TABLE COMPANY (ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL);''') print "Table created successfully"; conn.close()
执行上述程序后,它将在您的test.db中创建COMPANY表,并将显示以下消息:
Opened database successfully Table created successfully
INSERT操作
下面的 Python 程序演示如何在上面示例中创建的 COMPANY 表中创建记录。
#!/usr/bin/python import sqlite3 conn = sqlite3.connect('test.db') print "Opened database successfully"; conn.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ VALUES (1, 'Paul', 32, 'California', 20000.00 )"); conn.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ VALUES (2, 'Allen', 25, 'Texas', 15000.00 )"); conn.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )"); conn.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )"); conn.commit() print "Records created successfully"; conn.close()
执行上述程序后,它将在 COMPANY 表中创建给定的记录,并将显示以下两行:
Opened database successfully Records created successfully
SELECT操作
下面的 Python 程序演示如何从上面示例中创建的 COMPANY 表中提取和显示记录。
#!/usr/bin/python import sqlite3 conn = sqlite3.connect('test.db') print "Opened database successfully"; cursor = conn.execute("SELECT id, name, address, salary from COMPANY") for row in cursor: print "ID = ", row[0] print "NAME = ", row[1] print "ADDRESS = ", row[2] print "SALARY = ", row[3], "\n" print "Operation done successfully"; conn.close()
执行上述程序后,将产生以下结果。
Opened database successfully ID = 1 NAME = Paul ADDRESS = California SALARY = 20000.0 ID = 2 NAME = Allen ADDRESS = Texas SALARY = 15000.0 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
UPDATE操作
下面的 Python 代码演示如何使用 UPDATE 语句更新任何记录,然后从 COMPANY 表中提取和显示更新后的记录。
#!/usr/bin/python import sqlite3 conn = sqlite3.connect('test.db') print "Opened database successfully"; conn.execute("UPDATE COMPANY set SALARY = 25000.00 where ID = 1") conn.commit() print "Total number of rows updated :", conn.total_changes cursor = conn.execute("SELECT id, name, address, salary from COMPANY") for row in cursor: print "ID = ", row[0] print "NAME = ", row[1] print "ADDRESS = ", row[2] print "SALARY = ", row[3], "\n" print "Operation done successfully"; conn.close()
执行上述程序后,将产生以下结果。
Opened database successfully Total number of rows updated : 1 ID = 1 NAME = Paul ADDRESS = California SALARY = 25000.0 ID = 2 NAME = Allen ADDRESS = Texas SALARY = 15000.0 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully
DELETE操作
下面的 Python 代码演示如何使用 DELETE 语句删除任何记录,然后从 COMPANY 表中提取和显示剩余的记录。
#!/usr/bin/python import sqlite3 conn = sqlite3.connect('test.db') print "Opened database successfully"; conn.execute("DELETE from COMPANY where ID = 2;") conn.commit() print "Total number of rows deleted :", conn.total_changes cursor = conn.execute("SELECT id, name, address, salary from COMPANY") for row in cursor: print "ID = ", row[0] print "NAME = ", row[1] print "ADDRESS = ", row[2] print "SALARY = ", row[3], "\n" print "Operation done successfully"; conn.close()
执行上述程序后,将产生以下结果。
Opened database successfully Total number of rows deleted : 1 ID = 1 NAME = Paul ADDRESS = California SALARY = 20000.0 ID = 3 NAME = Teddy ADDRESS = Norway SALARY = 20000.0 ID = 4 NAME = Mark ADDRESS = Rich-Mond SALARY = 65000.0 Operation done successfully