SQLite 的命令行 Shell(三十一)

返回:SQLite---系列文章目录

上一篇:SQLite FTS5 扩展(三十)

下一篇:SQLite---系列文章目录

1. 入门

SQLite 项目提供了一个名为 sqlite3 (或 Windows 上的sqlite3.exe )的简单命令行程序 允许用户手动输入和执行 SQL 针对 SQLite 数据库或 ZIP 存档的语句。本文档简要介绍了 介绍如何使用 SQLite3 程序。

通过键入"sqlite3"来启动 sqlite3 程序 命令提示符,可选跟随 按保存 SQLite 数据库的文件的名称 (或 [ZIP 存档](#ZIP 存档))。如果命名 文件不存在,则具有给定名称的新数据库文件将是 自动创建。如果未在 命令行,则在以下情况下创建临时数据库并自动删除 "SQLITE3"程序退出。

启动时,sqlite3 程序将显示一个简短的横幅 消息,然后提示您输入 SQL。键入 SQL 语句(已终止 通过分号),按"Enter",SQL将被执行。

例如,创建名为"ex1"的新 SQLite 数据库 使用名为"tbl1"的单个表,可以执行以下操作:

bash 复制代码
$ sqlite3 ex1
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
sqlite> create table tbl1(one text, two int);
sqlite> insert into tbl1 values('hello!',10);
sqlite> insert into tbl1 values('goodbye', 20);
sqlite> select * from tbl1;
hello!|10
goodbye|20
sqlite>

通过键入系统来终止 sqlite3 程序 文件结束字符(通常为 Control-D)。使用中断 字符(通常为 Control-C)停止长时间运行的 SQL 语句。

请确保在每个 SQL 命令的末尾键入分号! sqlite3 程序查找一个分号,以了解您的 SQL 命令何时是 完成。如果你省略分号,sqlite3 会给你一个 继续提示并等待您输入更多文本 完成 SQL 命令。此功能允许您 输入跨多行的 SQL 命令。例如:

bash 复制代码
sqlite> CREATE TABLE tbl2 (
   ...>   f1 varchar(30) primary key,
   ...>   f2 text,
   ...>   f3 real
   ...> );
sqlite>

2. 双击 Windows 上的启动

Windows用户可以双击sqlite3.exe图标以引起 命令行 shell 弹出运行 SQLite 的终端窗口。然而 因为双击在没有命令行参数的情况下启动sqlite3.exe, 没有指定数据库文件,因此 SQLite 将使用临时 会话退出时删除的数据库。 要使用永久磁盘文件作为数据库,请输入".open"命令 终端窗口启动后:

bash 复制代码
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open ex1.db
sqlite>

上面的示例导致打开名为"ex1.db"的数据库文件 并使用。如果"ex1.db"文件以前不存在,则创建该文件。 您可能希望 使用完整路径名可确保文件位于 认为它在。使用正斜杠作为目录分隔符。 换句话说,使用"c:/work/ex1.db",而不是"c:\work\ex1.db"。

或者,您可以使用默认的临时数据库创建新数据库 存储,然后使用".save"命令将该数据库保存到磁盘文件中:

bash 复制代码
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> ... many SQL commands omitted ...
sqlite> .save ex1.db
sqlite>

使用".save"命令时要小心,因为它会覆盖任何 具有相同名称的预先存在的数据库文件,但未提示 确认。与".open"命令一样,您可能希望使用 带有正斜杠目录分隔符的完整路径名,以避免歧义。

3. sqlite3 的特殊命令(dot-commands)

大多数时候,sqlite3 只是读取输入行并传递它们 到SQLite库执行。 但是以点 (".") 开头的输入行 被 SQLite3 程序本身拦截和解释。 这些"点命令"通常用于更改输出格式 的查询,或执行某些预打包的查询语句。 最初只有几个点命令,但多年来 已经积累了许多新功能,因此今天有 60 多个。

有关可用 dot 命令的列表,您可以输入".help" 没有参数。或输入".help TOPIC"以获取有关 TOPIC 的详细信息。 可用的 dot-commands 列表如下:

bash 复制代码
sqlite> .help
.archive ...             Manage SQL archives
.auth ON|OFF             Show authorizer callbacks
.backup ?DB? FILE        Backup DB (default "main") to FILE
.bail on|off             Stop after hitting an error.  Default OFF
.cd DIRECTORY            Change the working directory to DIRECTORY
.changes on|off          Show number of rows changed by SQL
.check GLOB              Fail if output since .testcase does not match
.clone NEWDB             Clone data into NEWDB from the existing database
.connection [close] [#]  Open or close an auxiliary database connection
.crnl on|off             Translate \n to \r\n.  Default ON
.databases               List names and files of attached databases
.dbconfig ?op? ?val?     List or change sqlite3_db_config() options
.dbinfo ?DB?             Show status information about the database
.dump ?OBJECTS?          Render database content as SQL
.echo on|off             Turn command echo on or off
.eqp on|off|full|...     Enable or disable automatic EXPLAIN QUERY PLAN
.excel                   Display the output of next command in spreadsheet
.exit ?CODE?             Exit this program with return-code CODE
.expert                  EXPERIMENTAL. Suggest indexes for queries
.explain ?on|off|auto?   Change the EXPLAIN formatting mode.  Default: auto
.filectrl CMD ...        Run various sqlite3_file_control() operations
.fullschema ?--indent?   Show schema and the content of sqlite_stat tables
.headers on|off          Turn display of headers on or off
.help ?-all? ?PATTERN?   Show help text for PATTERN
.import FILE TABLE       Import data from FILE into TABLE
.indexes ?TABLE?         Show names of indexes
.limit ?LIMIT? ?VAL?     Display or change the value of an SQLITE_LIMIT
.lint OPTIONS            Report potential schema issues.
.load FILE ?ENTRY?       Load an extension library
.log FILE|on|off         Turn logging on or off.  FILE can be stderr/stdout
.mode MODE ?OPTIONS?     Set output mode
.nonce STRING            Suspend safe mode for one command if nonce matches
.nullvalue STRING        Use STRING in place of NULL values
.once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE
.open ?OPTIONS? ?FILE?   Close existing database and reopen FILE
.output ?FILE?           Send output to FILE or stdout if FILE is omitted
.parameter CMD ...       Manage SQL parameter bindings
.print STRING...         Print literal STRING
.progress N              Invoke progress handler after every N opcodes
.prompt MAIN CONTINUE    Replace the standard prompts
.quit                    Stop interpreting input stream, exit if primary.
.read FILE               Read input from FILE or command output
.recover                 Recover as much data as possible from corrupt db.
.restore ?DB? FILE       Restore content of DB (default "main") from FILE
.save ?OPTIONS? FILE     Write database to FILE (an alias for .backup ...)
.scanstats on|off|est    Turn sqlite3_stmt_scanstatus() metrics on or off
.schema ?PATTERN?        Show the CREATE statements matching PATTERN
.separator COL ?ROW?     Change the column and row separators
.session ?NAME? CMD ...  Create or control sessions
.sha3sum ...             Compute a SHA3 hash of database content
.shell CMD ARGS...       Run CMD ARGS... in a system shell
.show                    Show the current values for various settings
.stats ?ARG?             Show stats or turn stats on or off
.system CMD ARGS...      Run CMD ARGS... in a system shell
.tables ?TABLE?          List names of tables matching LIKE pattern TABLE
.timeout MS              Try opening locked tables for MS milliseconds
.timer on|off            Turn SQL timer on or off
.trace ?OPTIONS?         Output each SQL statement as it is run
.version                 Show source, library and compiler versions
.vfsinfo ?AUX?           Information about the top-level VFS
.vfslist                 List all available VFSes
.vfsname ?AUX?           Print the name of the VFS stack
.width NUM1 NUM2 ...     Set minimum column widths for columnar output
sqlite>

4. "点命令"、SQL 等规则

4.1. 线条结构

CLI 的输入被解析为一个序列,包括:

  • SQL 语句;
  • 点命令;或
  • CLI 注释

SQL 语句是自由格式的,可以分布在多行上, 在任何地方嵌入空格或 SQL 注释。 它们以输入行末尾的";"字符结尾, 或"/"字符或单词"go"本身在一行上。 当不在输入行的末尾时,";"字符 用于单独的 SQL 语句。 出于终止目的,将忽略尾随空格。

dot-command 具有更严格的结构:

  • 它必须以左边距的"."开头 前面没有空格。
  • 它必须完全包含在单个输入行中。
  • 它不能发生在普通 SQL 的中间 陈述。换句话说,它不能发生在 继续提示。
  • dot-commands 没有注释语法。

CLI 还接受全行注释 以"#"字符开头,并延伸到行尾。 "#"之前不能有空格。

4.2. 点命令参数

传递给 dot-commands 的参数是从命令尾部解析的, 根据这些规则:

  1. 尾随换行符和任何其他尾随空格将被丢弃;
  2. 点命令名称或任何参数后面的空格 输入端边界被丢弃;
  3. 参数输入以任何非空格字符开头;
  4. 参数输入以字符结尾,该字符 因此,取决于其主要角色:
    • 对于前导单引号 ('),单引号充当 作为结束分隔符;
    • 对于前导双引号 ("),未转义的双引号 充当结束分隔符;
    • 对于任何其他前导字符,结束分隔符为 任何空格;和
    • 命令尾端充当任何参数的结束分隔符;
  5. 在双引号参数输入中,反斜杠转义双引号 是论点的一部分,而不是其终止引用;
  6. 在双引号参数中,传统的 C 字符串文本,反斜杠 转义序列转换完成;和
  7. 参数输入分隔符(边界引号或空格) 被丢弃以生成传递的参数。

4.3. 点命令执行

dot-commands 由sqlite3.exe命令行程序解释,而不是由 SQLite本身。因此,没有一个 dot-command 可以用作参数 到 SQLite 接口,例如 sqlite3_prepare()sqlite3_exec()。

5. 更改输出格式

sqlite3 程序能够显示查询结果 在 14 种不同的输出格式中:

  • ASCII的
  • CSV的
  • [HTML全文]
  • 插入
  • JSON的
  • 线
  • 列表
  • 降价
  • 报价
  • 桌子
  • 制表符
  • TCL公司

您可以使用".mode"点命令在这些输出之间切换 格式。 默认输出模式为"列表"。在 列表模式下,查询结果的每一行都写在一行 输出,该行中的每一列都由特定的 分隔符字符串。默认分隔符为竖线符号 ("|")。 当您要发送输出时,列表模式特别有用 对另一个程序(如 AWK)的查询以进行其他处理。

bash 复制代码
sqlite> .mode list
sqlite> select * from tbl1;
hello!|10
goodbye|20
sqlite>

键入".mode",不带参数以显示当前模式:

bash 复制代码
sqlite> .mode
current output mode: list
sqlite>

使用".separator"点命令更改分隔符。 例如,将分隔符更改为逗号和 一个空格,你可以这样做:

bash 复制代码
sqlite> .separator ", "
sqlite> select * from tbl1;
hello!, 10
goodbye, 20
sqlite>

下一个".mode"命令可能会将".separator"重置为某个 默认值(取决于其参数)。 因此,每当您 如果要继续使用非标准分隔符,请更改模式。

在"quote"模式下,输出的格式为 SQL 文本。字符串是 用单引号括起来,内部单引号通过加倍转义。 Blob 以十六进制 blob 文字表示法显示 (例如:x'abcd')。 数字显示为 ASCII 文本,NULL 值显示为"NULL"。 所有列都用逗号(或任何替代项)彼此分隔 使用".separator"选择字符)。

bash 复制代码
sqlite> .mode quote
sqlite> select * from tbl1;
'hello!',10
'goodbye',20
sqlite>

在"行"模式下,数据库一行中的每一列 单独显示在一行上。每行由列组成 name、等号和列数据。连续记录是 用空行分隔。下面是线路模式的示例 输出:

bash 复制代码
sqlite> .mode line
sqlite> select * from tbl1;
one = hello!
two = 10

one = goodbye
two = 20
sqlite>

在列模式下,每条记录都显示在单独的行上,其中 数据在列中对齐。例如:

bash 复制代码
sqlite> .mode column
sqlite> select * from tbl1;
one       two
--------  ---
hello!    10
goodbye   20
sqlite>

在"列"模式下(以及"框"、"表"和"降价"模式) 列的宽度会自动调整。但是你可以覆盖它, 使用".width"命令为每列提供指定的宽度。 ".width"的参数是整数,它们是 要用于每列的字符。负数表示对齐。 因此:

bash 复制代码
sqlite> .width 12 -6
sqlite> select * from tbl1;
one              two
------------  ------
hello!            10
goodbye           20
sqlite>

宽度为 0 表示自动选择列宽。 未指定的列宽变为零。因此,命令 不带参数的".width"将所有列宽重置为零,并且 因此,自动确定所有列宽。

"列"模式是一种表格输出格式。其他 表格输出格式为 "box"、"markdown" 和 "table":

bash 复制代码
sqlite> .width
sqlite> .mode markdown
sqlite> select * from tbl1;
|   one   | two |
|---------|-----|
| hello!  | 10  |
| goodbye | 20  |
sqlite> .mode table
sqlite> select * from tbl1;
+---------+-----+
|   one   | two |
+---------+-----+
| hello!  | 10  |
| goodbye | 20  |
+---------+-----+
sqlite> .mode box
sqlite> select * from tbl1;
┌─────────┬─────┐
│   one   │ two │
├─────────┼─────┤
│ hello!  │ 10  │
│ goodbye │ 20  │
└─────────┴─────┘
sqlite>

列式模式接受一些附加选项来控制格式。 "--wrap N "选项(其中 N 是整数)会导致列 换行长度超过 N 个字符的文本。如果出现以下情况,则禁用包装 N 为零。

bash 复制代码
sqlite> insert into tbl1 values('The quick fox jumps over a lazy brown dog.',90);
sqlite> .mode box --wrap 30
sqlite> select * from tbl1 where two>50;
┌────────────────────────────────┬─────┐
│              one               │ two │
├────────────────────────────────┼─────┤
│ The quick fox jumps over a laz │ 90  │
│ y brown dog.                   │     │
└────────────────────────────────┴─────┘
sqlite>

换行发生在正好 N 个字符之后, 这可能是一个词的中间。 要在单词边界换行,请添加"--wordwrap on"选项 (或简称为"-ww"):

bash 复制代码
sqlite> .mode box --wrap 30 -ww
sqlite> select * from tbl1 where two>50;
┌─────────────────────────────┬─────┐
│             one             │ two │
├─────────────────────────────┼─────┤
│ The quick fox jumps over a  │ 90  │
│ lazy brown dog.             │     │
└─────────────────────────────┴─────┘
sqlite>

"--quote"选项使每列中的结果为 像 SQL 文字一样引用,就像在"引用"模式中一样。在线查看 有关其他选项的帮助。

命令".mode box --wrap 60 --quote"对于通用非常有用 数据库查询它是否被赋予了自己的别名。而不是打字 整个 27 个字符的命令,您只需说".mode qbox"即可。

另一个有用的输出模式是"插入"。在插入模式下,输出 格式类似于 SQL INSERT 语句。使用插件 模式生成文本,以后可用于将数据输入到 不同的数据库。

指定插入模式时,必须给出一个额外的参数 这是要插入到的表的名称。例如:

bash 复制代码
sqlite> .mode insert new_table
sqlite> select * from tbl1 where two<50;
INSERT INTO "new_table" VALUES('hello',10);
INSERT INTO "new_table" VALUES('goodbye',20);
sqlite>

其他输出模式包括"csv"、"json"和"tcl"。试试这些 你自己看看他们做了什么。

6. 查询数据库架构

sqlite3 程序提供了几个方便的命令, 对于查看数据库的架构很有用。有 这些命令所做的任何事情都不能由其他人完成 方法。这些命令纯粹作为快捷方式提供。

例如,若要查看数据库中的表列表,需要 可以输入".tables"。

bash 复制代码
sqlite> .tables
tbl1 tbl2
sqlite>

".tables"命令类似于设置列表模式 执行以下查询:

bash 复制代码
SELECT name FROM sqlite_schema
WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'
ORDER BY 1

但是".tables"命令的作用还不止于此。它查询sqlite_schema表 适用于所有附加数据库,而不仅仅是主数据库。它安排 它的输出到整齐的列中。

".indexes"命令的工作方式与列出所有 索引。如果给".indexes"命令一个参数,该参数是 表的名称,则它仅显示该表上的索引。

".schema"命令显示数据库的完整架构, 或者,如果提供了可选的 tablename 参数,则用于单个表:

bash 复制代码
sqlite> .schema
create table tbl1(one varchar(10), two smallint)
CREATE TABLE tbl2 (
  f1 varchar(30) primary key,
  f2 text,
  f3 real
);
sqlite> .schema tbl2
CREATE TABLE tbl2 (
  f1 varchar(30) primary key,
  f2 text,
  f3 real
);
sqlite>

".schema"命令与设置大致相同 列表模式,然后输入以下查询:

bash 复制代码
SELECT sql FROM sqlite_schema
ORDER BY tbl_name, type DESC, name

与 ".tables" 一样,".schema"命令显示 所有附加的数据库。如果只想查看 单个数据库(可能是"main"),然后您可以添加一个参数 更改为".schema"以限制其输出:

bash 复制代码
sqlite> .schema main.*

".schema"命令可以使用"--indent"选项进行扩充, 在这种情况下,它尝试重新格式化各种 CREATE 语句 架构,以便它们更容易被人类阅读。

".databases"命令显示在 当前连接。总会有至少 2 个。第一个 一个是"主",打开原始数据库。第二个是"温度", 用于临时表的数据库。可能还有其他 为使用 ATTACH 语句附加的数据库列出的数据库。 第一个输出列是数据库附加的名称, 第二个结果列是外部文件的文件名。 可能会有第三个结果列,它将是"'r/o'"或 "'r/w'"取决于数据库文件是只读的还是读写的。 并且可能有第四个结果列显示该数据库文件的 sqlite3_txn_state() 结果。

bash 复制代码
sqlite> .databases

".fullschema" 点命令的工作方式类似于 它显示整个数据库架构。但是".fullschema"也 包括统计表"sqlite_stat1"、"sqlite_stat3"的转储, 和"sqlite_stat4"(如果存在)。".fullschema"命令通常 提供精确重新创建查询所需的所有信息 规划特定查询。当报告可疑问题时 SQLite查询规划器给SQLite开发团队,开发人员 被要求提供完整的".fullschema"输出作为一部分 故障报告。请注意,sqlite_stat3 和 sqlite_stat4 表包含索引条目的示例,因此可能包含敏感条目 数据,因此不要发送专有数据库的".fullschema"输出 通过公共频道。

7. 打开数据库文件

".open"命令在首先关闭 以前打开的数据库命令。在最简单的形式中,".open"命令只是 在名为其参数的文件上调用 sqlite3_open()。使用名称 ":memory:" 打开一个新的内存中数据库,该数据库在 CLI 退出或 再次运行".open"命令。 或者不使用名称来打开一个专用的临时磁盘数据库,该数据库 在退出或使用".open"时也会消失。

如果 ".open" 中包含 --new 选项,则数据库会先重置 被打开。任何先前的数据都将被销毁。这是对 先前的数据,并且不要求确认,因此请谨慎使用此选项。

--readonly 选项以只读模式打开数据库。写入将是 禁止。

--deserialize 选项使磁盘文件的全部内容为 读取到内存中,然后使用 sqlite3_deserialize() 接口作为内存中数据库打开。当然,这将需要大量内存 如果您有一个大型数据库。此外,您对数据库所做的任何更改都不会 除非您使用".save"或".backup"明确保存它们,否则将保存回磁盘 命令。

--append 选项使 SQLite 数据库追加到现有的 文件,而不是作为独立文件工作。请参阅 appendvfs 扩展 更多信息。

--zip 选项使指定的输入文件被解释为 ZIP 存档 而不是作为 SQLite 数据库文件。

--hexdb 选项导致从后续数据库读取数据库内容 十六进制格式的输入行,而不是来自磁盘上的单独文件。 可以使用"dbtotxt"命令行工具生成 数据库的相应文本。--hexdb 选项旨在供 用于测试目的的 SQLite 开发人员。我们不知道这方面的任何用例 内部 SQLite 测试和开发之外的选项。

8. 重定向 I/O

8.1. 将结果写入文件

默认情况下,sqlite3 将查询结果发送到标准输出。你 可以使用".output"和".once"命令更改此设置。只要把 输出文件的名称,作为 .output 和所有后续文件的参数 查询结果将写入该文件。或者使用 .once 命令 而不是 .output,输出将仅针对下一个 命令,然后再恢复到控制台。使用不带参数的 .output 再次开始写入标准输出。例如:

bash 复制代码
sqlite> .mode list
sqlite> .separator |
sqlite> .output test_file_1.txt
sqlite> select * from tbl1;
sqlite> .exit
$ cat test_file_1.txt
hello|10
goodbye|20
$

如果".output"或".once"文件名的第一个字符是管道 符号 ("|") 则其余字符被视为命令,并且 输出将发送到该命令。这样可以很容易地通过管道传输结果 对其他进程的查询。例如, Mac 上的"open -f"命令打开文本编辑器以显示以下内容 它从标准输入读取。因此,要查看查询的结果 在文本编辑器中,可以键入:

bash 复制代码
sqlite> .once | open -f
sqlite> SELECT * FROM bigTable;

如果".output"或".once"命令的参数为"-e",则 输出被收集到一个临时文件中,系统文本编辑器是 在该文本文件上调用。因此,命令".once -e"实现了 结果与".once '|open -f'"相同,但具有可移植性的好处 跨所有系统。

如果".output"或".once"命令具有"-x"参数,则会导致 它们将输出累积为临时逗号分隔值 (CSV) 文件,然后调用默认系统实用程序来查看 CSV 文件 (通常是电子表格程序)的结果。这是一种快速的方法 将查询结果发送到电子表格以便于查看:

bash 复制代码
sqlite> .once -x
sqlite> SELECT * FROM bigTable;

".excel" 命令是 ".once -x" 的别名。它的作用完全相同 东西。

8.2. 从文件中读取 SQL

在交互模式下,sqlite3 读取输入文本(SQL 语句 或 dot-commands)。您还可以从以下位置重定向输入 当然,当您启动 sqlite3 时,一个文件,但随后您没有 能够与程序交互。有时,运行 文件中包含的 SQL 脚本,用于从命令行输入其他命令。 为此,提供了".read"点命令。

".read"命令采用一个参数,该参数(通常)是名称 要从中读取输入文本的文件。

bash 复制代码
sqlite> .read myscript.sql

".read"命令暂时停止从键盘读取,而是 从 name.到达文件末尾后, 输入返回键盘。脚本文件可能包含 dot-commands, 就像普通的交互式输入一样。

如果".read"的参数以"|"字符开头,则 将参数作为文件打开,它运行参数(不带前导"|") 作为命令,然后使用该命令的输出作为其输入。因此,如果你 有一个生成 SQL 的脚本,您可以直接使用 类似于以下内容的命令:

bash 复制代码
sqlite> .read |myscript.bat

8.3. 文件I/O功能

命令行 shell 添加了两个应用程序定义的 SQL 函数,它们 便于将文件的内容读取到表列中,并将 列的内容分别添加到文件中。

readfile(X) SQL 函数读取名为 X 并以 BLOB 的形式返回该内容。这可用于将内容加载到 一张桌子。例如:

bash 复制代码
sqlite> CREATE TABLE images(name TEXT, type TEXT, img BLOB);
sqlite> INSERT INTO images(name,type,img)
   ...>   VALUES('icon','jpeg',readfile('icon.jpg'));

writefile(X,Y) SQL 函数将 blob Y 写入名为 X 的文件中 并返回写入的字节数。使用此函数提取 将单个表列的内容放入文件中。例如:

bash 复制代码
sqlite> SELECT writefile('icon.jpg',img) FROM images WHERE name='icon';

请注意,readfile(X) 和 writefile(X,Y) 函数是扩展名 函数,并且未内置到核心 SQLite 库中。这些例程 可作为 SQLite 源代码存储库中的 ext/misc/fileio.c 源文件中的可加载扩展。

8.4. edit() SQL函数

CLI 具有另一个名为 edit() 的内置 SQL 函数。Edit() 需要 一个或两个参数。第一个参数是一个值 - 通常是一个大 要编辑的多行字符串。第二个参数是调用 用于文本编辑器。(它可能包括影响编辑器的选项 行为。如果省略第二个参数,则 VISUAL 环境 变量。edit() 函数将其第一个参数写入 临时文件,调用临时文件的编辑器,重新读取文件 编辑器完成后返回到内存中,然后返回编辑后的文本。

edit() 函数可用于对大文本进行更改 值。例如:

bash 复制代码
sqlite> UPDATE docs SET body=edit(body) WHERE name='report-15';

在此示例中,条目的 docs.body 字段的内容 docs.name 是"report-15"将发送给编辑。编辑器返回后, 结果将写回 docs.body 字段。

edit() 的默认操作是调用文本编辑器。但是通过使用 第二个参数中的替代编辑程序,您也可以让它进行编辑 图像或其他非文本资源。例如,如果要修改 JPEG 恰好存储在表的字段中的映像,您可以运行:

bash 复制代码
sqlite> UPDATE pics SET img=edit(img,'gimp') WHERE id='pic-1542';

编辑程序也可以用作查看器,只需忽略 返回值。例如,要仅查看上图,可以运行:

bash 复制代码
sqlite> SELECT length(edit(img,'gimp')) WHERE id='pic-1542';

8.5. 将文件导入为CSV或其他格式

使用".import"命令导入 CSV(逗号分隔值) 或类似地将数据分隔到 SQLite 表中。 ".import"命令采用两个参数,它们是 要从中读取数据的来源以及 要插入数据的 SQLite 表。source 参数 是要读取的文件的名称,或者,如果它以"|"字符开头, 它指定将运行以生成输入数据的命令。

请注意,在运行 ".import" 命令。这是防止命令行 shell 的谨慎做法 尝试将输入文件文本解释为某种格式以外的格式 文件的结构。如果使用 --csv 或 --ascii 选项, 它们控制导入输入分隔符。否则,分隔符为 那些对当前输出模式有效的。

要导入到不在"main"架构中的表中,--schema 选项 可用于指定表位于其他架构中。这可以 对于 ATTACH 的数据库或导入到 TEMP 表中很有用。

运行 .import 时,其对第一个输入行的处理取决于 取决于目标表是否已存在。如果它不存在, 将自动创建表,并输入第一个输入的内容 row 用于设置表中所有列的名称。在这个 case,表数据内容取自第二个及后续 输入行。如果目标表已存在,则 输入(包括第一个输入)被视为实际数据内容。如果 输入文件包含列标签的初始行,您可以将 .import 命令使用"--skip 1"选项跳过该初始行。

下面是一个示例用法,加载预先存在的临时表 从第一行具有列名的 CSV 文件中:

sql 复制代码
sqlite> .import --csv --skip 1 --schema temp C:/work/somedata.csv tab1

以"ascii"、".import"以外的模式读取输入数据时 根据 RFC 4180 将输入解释为由字段组成的记录 除此例外的规范:输入记录和字段分隔符 由模式或使用 .separator 命令设置。字段是 始终受制于根据 RFC 4180 完成的反向报价删除, ASCII 模式除外。

要导入具有任意分隔符且不带引号的数据, 首先设置 ASCII 模式(".mode ASCII"),然后设置字段 并使用".separator"命令记录分隔符。这 将抑制取消报价。在".import"时,数据将被拆分 根据指定的分隔符进入字段和记录。

8.6. 导出到 CSV

要将 SQLite 表(或表的一部分)导出为 CSV,只需将 将"mode"更改为"csv",然后运行查询以提取所需的行 的表。根据 RFC 4180,输出将格式化为 CSV。

sql 复制代码
sqlite> .headers on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .system c:/work/dataout.csv

在上面的示例中,".headers on"行会导致列标签 打印为输出的第一行。这意味着第一行 生成的 CSV 文件将包含列标签。如果列标签是 不需要,请改为设置".headers off"。(".headers off"设置为 默认值,如果标头以前没有,则可以省略 打开。

行".once *FILENAME"*导致所有查询输出进入 命名文件,而不是在控制台上打印。在示例中 上面,该行会导致 CSV 内容写入名为 "C:/工作/dataout.csv"。

示例的最后一行(".system c:/work/dataout.csv") 与双击 C:/work/dataout.csv 文件具有相同的效果 在 Windows 中。这通常会显示一个电子表格程序 CSV 文件。

该命令仅在 Windows 上编写时有效。 Mac 上的等效行为:

sql 复制代码
sqlite> .system open dataout.csv

在 Linux 和其他 unix 系统上,您需要输入如下内容:

sql 复制代码
sqlite> .system xdg-open dataout.csv

8.6.1. 导出到 Excel

为了简化电子表格的导出,CLI 提供了 ".excel"命令,用于捕获单个查询的输出并发送 该输出到主机上的默认电子表格程序。 像这样使用它:

sql 复制代码
sqlite> .excel
sqlite> SELECT * FROM tab;

上面的命令将查询的输出作为 CSV 写入临时 文件,调用 CSV 文件的默认处理程序(通常是首选 电子表格程序,例如 Excel 或 LibreOffice),然后删除 临时文件。这本质上是一种速记方法 上述".csv"、".once"和".system"命令的序列。

".excel"命令实际上是".once -x"的别名。-x 选项 到 .once 会导致它将结果作为 CSV 写入一个临时文件,该文件 以".csv"后缀命名,然后调用系统默认处理程序 对于 CSV 文件。

还有一个".once -e"命令的工作方式类似,只是 它使用".txt"后缀命名临时文件,以便默认 将调用系统的文本编辑器,而不是默认的 电子表格。

8.6.2. 导出到 TSV(制表符分隔值)

导出为纯 TSV,无需任何字段引用,可以通过以下方式完成 在运行查询之前输入".mode 选项卡"。但是,输出 在选项卡模式下,".import"命令无法正确读取 如果它包含双引号字符。获取 TSV 报价 RFC 4180,以便可以使用".import"以选项卡模式输入, 首先输入".mode csv",然后输入".separator "\t"' 在运行查询之前。

9. 将ZIP档案作为数据库文件访问

除了读取和写入 SQLite 数据库文件外, sqlite3 程序还将读取和写入ZIP存档。 只需指定一个ZIP存档文件名来代替SQLite数据库 filename 或在".open"命令中, sqlite3 会自动检测文件是 ZIP存档而不是SQLite数据库,并将以这种方式打开它。 无论文件后缀如何,这都有效。所以你可以打开 JAR、DOCX、 和 ODP 文件和任何其他真正是 ZIP 的文件格式 archive 和 SQLite 将为您读取它。

ZIP 存档似乎是包含单个表的数据库 使用以下架构:

sql 复制代码
CREATE TABLE zip(
  name,     // Name of the file
  mode,     // Unix-style file permissions
  mtime,    // Timestamp, seconds since 1970
  sz,       // File size after decompression
  rawdata,  // Raw compressed file data
  data,     // Uncompressed file content
  method    // ZIP compression method code
);

因此,例如,如果您想查看压缩效率 (表示为压缩内容相对于 原始未压缩的文件大小)用于ZIP存档中的所有文件, 从"最压缩"到"最不压缩"排序,您可以运行 像这样的查询:

sql 复制代码
sqlite> SELECT name, (100.0*length(rawdata))/sz FROM zip ORDER BY 2;

Or using file I/O functions, you can extract elements of the ZIP archive:

sql 复制代码
sqlite> SELECT writefile(name,content) FROM zip
   ...> WHERE name LIKE 'docProps/%';

9.1. How ZIP archive access is implemented

The command-line shell uses the Zipfile virtual table to access ZIP archives. You can see this by running the ".schema" command when a ZIP archive is open:

sql 复制代码
sqlite> .schema
CREATE VIRTUAL TABLE zip USING zipfile('document.docx')
/* zip(name,mode,mtime,sz,rawdata,data,method) */;

打开文件时,如果命令行客户端发现 文件是ZIP存档而不是SQLite数据库,它实际上打开了 一个内存数据库,然后在该内存数据库中创建 附加到 ZIP 存档。

打开ZIP档案的特殊处理是 命令行 shell,而不是核心 SQLite 库。所以如果你想 在应用程序中打开ZIP存档作为数据库,您将需要 激活 Zipfile 虚拟表模块,然后运行相应的 CREATE VIRTUAL TABLE 语句。

10. 将整个数据库转换为文本文件

使用".dump"命令转换 数据库转换为单个 UTF-8 文本文件。这个文件可以转换 通过管道将数据库送回 SQLite3 中,返回到数据库中。

制作数据库存档副本的一个好方法是:

sql 复制代码
$ sqlite3 ex1 .dump | gzip -c >ex1.dump.gz

这将生成一个名为 ex1.dump.gz 的文件,其中包含所有内容 您需要稍后或在另一个时间重建数据库 机器。要重建数据库,只需键入:

sql 复制代码
$ zcat ex1.dump.gz | sqlite3 ex2

文本格式是纯 SQL,因此您 还可以使用 .dump 命令导出 SQLite 数据库 进入其他常用的 SQL 数据库引擎。喜欢这个:

sql 复制代码
$ createdb ex2
$ sqlite3 ex1 .dump | psql ex2

11.从损坏的数据库中恢复数据

与".dump"命令一样,".recover"尝试将整个 数据库文件的内容转换为文本。不同之处在于,而不是 使用普通 SQL 数据库接口".recover"读取数据 尝试根据直接从中提取的数据重新组合数据库 尽可能多的数据库页。如果数据库已损坏,".recover" 通常能够从数据库的所有未损坏部分恢复数据, 而".dump"在遇到第一个损坏迹象时停止。

如果".recover"命令恢复它无法恢复的一行或多行 属性添加到任何数据库表,输出脚本会创建一个"lost_and_found" 表来存储孤立行。lost_and_found的架构 表格如下:

sql 复制代码
CREATE TABLE lost_and_found(
    rootpgno INTEGER,             -- root page of tree pgno is a part of
    pgno INTEGER,                 -- page number row was found on
    nfield INTEGER,               -- number of fields in row
    id INTEGER,                   -- value of rowid field, or NULL
    c0, c1, c2, c3...             -- columns for fields of row
);

"lost_and_found"表包含每恢复的孤立行的一行 从数据库。此外,每个恢复的索引都有一行 不能归因于任何 SQL 索引的条目。这是因为,在 SQLite 数据库,使用相同的格式来存储 SQL 索引条目和 没有 ROWID 表条目。

内容
rootpgno 即使可能无法将 行到特定的数据库表,它可能是树结构的一部分 在数据库文件中。在本例中,该的根页码 树结构存储在此列中。或者,如果该行所在的页面是 在不是树结构的一部分上找到,此列存储的副本 "PGNO"列中的值 - 该行所在的页面的页码 找到。在许多(尽管不是全部)情况下,所有行都位于 此列中具有相同值lost_and_found表属于 同一张表。
PGNO的 找到此行的页面的页码。
恩菲尔德 此行中的字段数。
同上 如果该行来自 WITHOUT ROWID 表,则此列 包含 NULL。否则,它包含 的 64 位整数 rowid 值 行。
C0、C1、C2... 行中每列的值 存储在这些列中。".recover"命令创建 lost_and_found具有最长列数的表 孤立行。

如果恢复的数据库架构已包含名为 "lost_and_found",则".recover"命令使用名称"lost_and_found0"。如果 "lost_and_found0"这个名字也已经被取了,"lost_and_found1",等等 上。可以通过调用".recover"来覆盖默认名称"lost_and_found" 使用 --lost-and-found 开关。例如,要调用输出脚本 表"orphaned_rows":

sql 复制代码
sqlite> .recover --lost-and-found orphaned_rows

12. 加载扩展

您可以向命令行添加新的自定义应用程序定义的 SQL 函数排序序列虚拟表VFS shell,在运行时使用".load"命令。首先,构建 扩展作为 DLL 或共享库(如运行时可加载扩展文档中所述),然后键入:

sql 复制代码
sqlite> .load /path/to/my_extension

请注意,SQLite 会自动添加相应的扩展后缀 (Windows 上的".dll",Mac 上的".dylib",大多数其他 unix 上的".so")到 扩展名文件名。通常最好指定完整的 扩展名的路径名。

SQLite 根据扩展计算扩展的入口点 文件名。要覆盖此选项,只需添加扩展名即可 作为".load"命令的第二个参数。

可以在 SQLite 源代码树的 ext/misc 子目录中找到几个有用的扩展的源代码。您可以使用这些扩展 按原样,或作为创建自己的自定义扩展以解决以下问题的基础 您自己的特殊需求。

13. 数据库内容的加密哈希

".sha3sum" dot-command 计算数据库内容SHA3 哈希值。需要明确的是,哈希值是在数据库内容上计算的, 不是它在磁盘上的表示形式。这意味着,例如,VACUUM 或类似的数据保留转换不会更改哈希值。

".sha3sum"命令支持选项"--sha3-224"、"--sha3-256"、 "--sha3-384"和"--sha3-512"来定义要使用的 SHA3 种类 对于哈希。默认值为 SHA3-256。

数据库架构(在sqlite_schema表中)通常不是 包含在哈希中,但可以通过"--schema"选项添加。

".sha3sum"命令采用一个可选参数,该参数是 LIKE 模式。如果此选项存在,则仅显示名称匹配的表 LIKE 模式将被哈希处理。

".sha3sum"命令是在命令行 shell 附带的扩展函数"sha3_query()"的帮助下实现的。

14. 数据库内容自检

".selftest"命令尝试验证数据库是否 完好无损,没有腐败。 .selftest 命令在架构中查找名为"selftest"的表 并定义如下:

sql 复制代码
CREATE TABLE selftest(
  tno INTEGER PRIMARY KEY,  -- Test number
  op TEXT,                  -- 'run' or 'memo'
  cmd TEXT,                 -- SQL command to run, or text of "memo"
  ans TEXT                  -- Expected result of the SQL command
);

.selftest 命令读取 selftest 表的行 selftest.tno 顺序。 对于每个"memo"行,它将"cmd"中的文本写入输出。为 每个"运行"行,它将"cmd"文本作为 SQL 运行并比较结果 设置为"ans"中的值,如果结果不同,则显示错误消息。

如果没有自检表,则".selftest"命令运行 PRAGMA integrity_check

".selftest --init"命令如果 ,则附加检查 SHA3 的条目 所有表内容的哈希值。".selftest"的后续运行 将验证数据库是否未以任何方式更改。自 生成测试以验证表的子集是否未更改, 只需运行".selftest --init",然后删除 请参阅不常量的表。

15. SQLite 存档支持

".archive" dot-command 和 "-A" 命令行选项 提供对 SQLite 存档格式的内置支持。该界面类似于 UNIX 系统上的"tar"命令。每次调用".ar" command 必须指定单个命令选项。以下命令 可用于".archive":

选择 多头期权 目的
-c --创造 创建包含指定文件的新存档。
-x --提取 从存档中提取指定的文件。
-我 --插入 将文件添加到现有存档。
-r --删除 从存档中删除文件。
-t --列表 列出存档中的文件。
-u --更新 如果文件已更改,请将文件添加到现有存档中。

除了命令选项外,每次调用".ar"都可以指定 一个或多个修饰符选项。某些修饰符选项需要参数, 有些则不然。可以使用以下修饰符选项:

选择 多头期权 目的
-v --详细 在处理每个文件时列出它。
-f 文件 --file 文件 如果指定,请使用文件 FILE 作为 档案。否则,假设当前"主"数据库是 要操作的存档。
-a 文件 --append 文件 像 --file 一样,使用 file FILE 作为 存档,但使用 apndvfs VFS 打开文件,以便 如果 FILE 已存在,则存档将附加到 FILE 的末尾。
-C DIR --目录 DIR 如果指定,请解释所有相对 路径相对于 DIR,而不是当前工作目录。
-克 --球 使用 glob(Y,X) 匹配参数 针对存档中的名称。
-n --干运行 显示将运行以执行 存档操作,但实际上不会更改任何内容。
-- -- 所有后续的命令行字都是命令参数, 不是选项。

对于命令行用法,请立即添加简短样式的命令行选项 在"-A"之后,没有中间空格。所有后续参数 被视为 .archive 命令的一部分。例如,以下内容 命令是等效的:

sql 复制代码
sqlite3 new_archive.db -Acv file1 file2 file3
sqlite3 new_archive.db ".ar -cv file1 file2 file3"

长款和短款选项可以混合使用。例如,以下是 等效:

sql 复制代码
-- Two ways to create a new archive named "new_archive.db" containing
-- files "file1", "file2" and "file3".
.ar -c --file new_archive.db file1 file2 file3
.ar -f new_archive.db --create file1 file2 file3

或者,".ar"后面的第一个参数可能是串联 所有必填选项的缩写形式(不带"-"字符)。在 在这种情况下,需要它们的选项的参数是从命令行读取的 接下来,任何剩余的单词都被视为命令参数。例如:

sql 复制代码
-- Create a new archive "new_archive.db" containing files "file1" and
-- "file2" from directory "dir1".
.ar cCf dir1 new_archive.db file1 file2 file3

15.1. SQLite Archive Create 命令

创建一个新的存档,覆盖任何现有存档(在当前 "main" db 或由 --file 选项指定的文件中)。每个参数如下 选项是要添加到存档中的文件。导入目录 递 归。有关示例,请参阅上文。

15.2. SQLite Archive Extract命令

从存档中提取文件(到当前工作目录或 添加到由 --directory 选项指定的目录)。 名称与参数匹配的文件或目录, 受 --glob 选项影响,被解压。 或者,如果选项后面没有参数,则提取所有文件和目录。 任何指定的目录都是以递归方式提取的。如果有的话,这是一个错误 在存档中找不到指定的名称或匹配模式。

sql 复制代码
-- Extract all files from the archive in the current "main" db to the
-- current working directory. List files as they are extracted. 
.ar --extract --verbose

-- Extract file "file1" from archive "ar.db" to directory "dir1".
.ar fCx ar.db dir1 file1

-- Extract files with ".h" extension to directory "headers".
.ar -gCx headers *.h

15.3. SQLite Archive List 命令

列出存档的内容。如果未指定任何参数,则所有 文件将列出。否则,只有那些与参数匹配的, 受 --glob 选项影响。现在 --verbose 选项不会更改此命令的行为。那可能 未来的变化。

sql 复制代码
-- List contents of archive in current "main" db..
.ar --list

15.4. SQLite存档插入和更新命令

--update 和 --insert 命令的工作方式与 --create 命令类似,不同之处在于 在开始之前,它们不会删除当前存档。新版本 文件以静默方式替换具有相同名称的现有文件,但除此之外 存档的初始内容(如果有)保持不变。

对于 --insert 命令,列出的所有文件都将插入到归档文件中。 对于 --update 命令,仅当文件之前没有插入时,才会插入文件 存在于存档中,或者它们的"mtime"或"mode"与什么不同 目前在存档中。

兼容节点:仅限 SQLite 版本 3.28.0 (2019-04-16) 之前 支持 --update 选项,但该选项的工作方式类似于 --insert 它总是重新插入每个文件,无论它是否已更改。

15.5. SQLite Archive Remove命令

--remove 命令删除与 提供了受 --glob 选项影响的参数(如果有)。 提供与存档中不匹配的参数是错误的。

15.6. ZIP存档上的操作

如果 FILE 是 ZIP 存档而不是 SQLite 存档,则 ".archive" 命令和"-A"命令行选项仍然有效。这已经完成了 使用 zip文件扩展名。 因此,以下命令大致等效, 仅在输出格式上有所不同:

传统命令 等效sqlite3.exe命令
解压缩archive.zip sqlite3 -axf archive.zip
解压缩 -l archive.zip sqlite3 -Atvf archive.zip
zip -r archive2.zip目录 sqlite3 -acf archive2.zip dir

15.7. 用于实现 SQLite 归档操作的 SQL

各种 SQLite Archive Archive 命令是使用 SQL 语句实现的。 应用程序开发人员可以轻松添加 SQLite Archive Archive 读取和写入 通过运行适当的 SQL 来支持他们自己的项目。

查看使用哪些 SQL 语句实现 SQLite 存档 操作,添加 --dryrun 或 -n 选项。这会导致 SQL 是 显示,但禁止执行 SQL。

用于实现 SQLite Archive 操作的 SQL 语句使用 各种可加载的扩展。这些扩展都可用于 ext/misc/ 子文件夹中的 SQLite 源代码树。 完全SQLite Archive支持所需的扩展包括:

  1. fileio.c --- 此扩展添加了 SQL 函数 readfile() 和 writefile() 从磁盘上的文件中读取和写入内容。fileio.c 扩展还包括用于列表的 fsdir() 表值函数 目录的内容和用于转换的 lsmode() 函数 来自 stat() 系统的数字st_mode整数调用为人类可读 字符串遵循"ls -l"命令的时尚。

  2. sqlar.c --- 此扩展添加了 sqlar_compress() 和 sqlar_uncompress() 压缩和解压缩文件内容所需的函数 因为它是从 SQLite 存档中插入和提取的。

  3. zipfile.c --- 此扩展实现"zipfile(FILE)"表值函数 用于读取ZIP档案。只有需要此扩展 读取ZIP档案而不是SQLite档案时。

  4. appendvfs.c --- 此扩展实现了一个新的 VFS,它允许 SQLite 数据库 追加到其他文件,如可执行文件。这 仅当 --append 选项添加到 .archive 时才需要扩展名 使用命令。

16. SQL参数

SQLite 允许绑定参数出现在任何位置的 SQL 语句中 允许使用文本值。设置这些参数的值 使用sqlite3_bind_...() API 系列。

参数可以是命名的,也可以是未命名的。未命名的参数是单个 问号 ("?")。命名参数是"?",后跟一个数字 (例如:"?15"或"?123")或字符之一""、":"或"@",后跟 字母数字名称(例如:"var 1"、":xyz"、"@bingo")。

此命令行 shell 使未命名的参数保持未绑定状态,这意味着它们 将具有 SQL NULL 值,但可能会为命名参数分配值。 如果存在一个名为"sqlite_parameters"的 TEMP 表,其架构如下:

sql 复制代码
CREATE TEMP TABLE sqlite_parameters(
  key TEXT PRIMARY KEY,
  value
) WITHOUT ROWID;

如果该表中有一个条目与键列完全匹配 参数的名称(包括首字母 "?"、"$"、":" 或 "@" 字符) 然后为参数分配值列的值。如果不存在条目, 参数默认为 NULL。

".parameter"命令的存在是为了简化此表的管理。这 ".parameter init"命令(通常缩写为".param init")创建 temp.sqlite_parameters表(如果尚不存在)。".param 列表" 命令显示temp.sqlite_parameters表中的所有条目。".param 清除" 命令删除temp.sqlite_parameters表。".param set KEY VALUE" 和 ".param unset KEY"命令创建或删除条目 temp.sqlite_parameters表。

传递给".param set KEY VALUE"的 VALUE 可以是 SQL 文本 或任何其他可以计算以生成值的 SQL 表达式或查询。 这允许设置不同类型的值。 如果此类评估失败,则引用并插入提供的 VALUE 作为文本。 因为这种初步评估可能会失败,也可能不会失败,这取决于 VALUE 内容,获取文本值的可靠方法是将其括起来 使用单引号,不受上述命令尾部解析的影响。 例如,(除非打算将值设置为 -1365):

sql 复制代码
.parameter init
.parameter set @phoneNumber "'202-456-1111'"

请注意,双引号用于保护单引号 并确保将引用的文本解析为一个参数。

temp.sqlite_parameters 表仅提供 命令行 shell。temp.sqlite_parameter表对查询没有影响 直接使用 SQLite C 语言 API 运行。个性化应用 应实现自己的参数绑定。您可以搜索 "sqlite_parameters",以查看命令行 shell 如何执行参数绑定,并将其用作 有关如何自己实现它的提示。

17. 索引建议 (SQLite Expert)

注意:此命令是实验性的。它可能会被删除或 接口在将来的某个时候以不兼容的方式修改。

对于大多数重要的 SQL 数据库,性能的关键是创建 正确的 SQL 索引。在此上下文中,"正确的 SQL 索引"是指那些 这会导致应用程序需要优化的查询快速运行。这 ".expert"命令可以通过建议可能 协助处理特定查询,如果它们存在于数据库中。

首先发出".expert"命令,然后发出 SQL 查询 在另一行上。例如,请考虑以下会话:

sql 复制代码
sqlite> CREATE TABLE x1(a, b, c);                  -- Create table in database 
sqlite> .expert
sqlite> SELECT * FROM x1 WHERE a=? AND b>?;        -- Analyze this SELECT 
CREATE INDEX x1_idx_000123a7 ON x1(a, b);

0|0|0|SEARCH TABLE x1 USING INDEX x1_idx_000123a7 (a=? AND b>?)

sqlite> CREATE INDEX x1ab ON x1(a, b);             -- Create the recommended index 
sqlite> .expert
sqlite> SELECT * FROM x1 WHERE a=? AND b>?;        -- Re-analyze the same SELECT 
(no new indexes)

0|0|0|SEARCH TABLE x1 USING INDEX x1ab (a=? AND b>?)

在上面,用户创建数据库模式(单个表 - "x1"), 然后使用".expert"命令来分析查询,在本例中为 "从 x1 中选择 * 其中 a=?还有 b>?shell 工具建议 用户创建一个新索引(索引"x1_idx_000123a7")并输出计划 查询将以 EXPLAIN QUERY PLAN 格式使用。然后,用户创建 具有等效架构的索引,并对同一查询运行分析 再。这一次,shell 工具不推荐任何新索引,并且 输出 SQLite 将用于查询的计划,给定现有的 指标。

".expert"命令接受以下选项:

选择 目的
--详细 如果存在,请为分析的每个查询输出更详细的报告。
--样本百分比 此参数默认为 0,导致 ".expert" 命令 仅根据查询和数据库架构推荐索引。 这类似于 SQLite 查询规划器选择的方式 如果用户尚未运行 ANALYZE 命令,则为查询编制索引 在数据库上生成数据分布统计信息。 如果传递此选项的非零参数,则".expert"命令 为所有索引生成类似的数据分布统计信息 根据当前存储在 每个数据库表。对于具有异常数据分布的数据库, 这可能会带来更好的指数建议,特别是如果 应用程序打算运行 ANALYZE。 对于小型数据库和现代 CPU,通常没有理由不这样做 传递"--sample 100"。但是,收集数据分布 对于大型数据库表,统计信息可能很昂贵。如果 操作速度太慢,请尝试为 --sample 传递较小的值 选择。

本节中描述的功能可以集成到其他 使用 SQLite 专家扩展代码的应用程序或工具。

包含可用的 SQL 自定义函数的数据库架构 通过扩展加载机制可能需要特殊规定才能使用 .expert 功能。因为该功能使用额外的连接来 实现其功能,这些自定义功能必须可用 到那些额外的连接。这可以通过扩展来完成 自动加载静态链接扩展持久可加载扩展中所述的加载/使用选项。

18. 使用多个数据库连接

从版本 3.37.0 (2021-11-27) 开始,CLI 能够 同时打开多个数据库连接。只有一个数据库连接 一次处于活动状态。非活动连接仍处于打开状态,但处于空闲状态。

使用".connection"点命令(通常缩写为".conn")查看 数据库连接列表,并指示当前处于活动状态的数据库连接。 每个数据库连接都由 0 到 9 之间的整数标识。(那里 最多可以同时打开 10 个连接。更改为其他数据库 连接,如果它尚不存在,则通过键入".conn"来创建它 命令后跟其编号。通过键入 ".conn close N",其中 N 是连接号。

尽管底层 SQLite 数据库连接是完全独立的 彼此之间,许多 CLI 设置(例如输出格式)是 在所有数据库连接之间共享。因此,在 一个连接将改变他们所有人。另一方面,一些点命令(如 .open)仅影响当前连接。

19. 其他扩展功能

CLI 是使用多个 SQLite 扩展构建的,这些扩展不是 包含在 SQLite 库中。一些添加功能 前面几节中未描述,即:

  • UINT 整理序列,它处理 嵌入在文本中的无符号整数 它们的价值,以及其他文本,用于排序;
  • 十进制扩展提供的十进制算术;
  • generate_series() 表值函数;
  • 对 base64() 和 base85() 函数进行编码 blob 转换为 base64 或 base85 文本或将其解码为 blob;和
  • 支持 POSIX 扩展正则表达式 绑定到 REGEXP 运算符。

20. 其他点命令

命令行中还有许多其他可用的点命令 壳。请参阅".help"命令以获取任何特定的完整列表 SQLite的版本和内部版本。

21. 在 shell 脚本中使用 sqlite3

在 shell 脚本中使用 sqlite3 的一种方法是使用"echo"或 "cat" 在文件中生成一系列命令,然后调用 sqlite3 同时重定向生成的命令文件中的输入。这 工作正常,在许多情况下都是合适的。但作为 为了增加便利性,sqlite3 允许单个 SQL 命令 在命令行中输入作为第二个参数 数据库名称。当 sqlite3 程序启动时,有两个 参数,则第二个参数传递给 SQLite 库 为了进行处理,查询结果打印在标准输出上 在列表模式下,程序退出。这种机制是设计好的 使 SQLite3 易于与以下程序结合使用 "哎呀"。例如:

sql 复制代码
$ sqlite3 ex1 'select * from tbl1' \
>  | awk '{printf "<tr><td>%s<td>%s\n",$1,$2 }'
<tr><td>hello<td>10
<tr><td>goodbye<td>20
$

22. 标记 SQL 语句的结尾

SQLite 命令通常以分号结尾。在 CLI 中 您还可以使用单词"GO"(不区分大小写)或斜杠字符 "/"本身用于结束命令。这些由 SQL Server 使用 和 Oracle,并由 SQLite CLI 支持 兼容性。这些在 sqlite3_exec() 中不起作用, 因为 CLI 在传递之前将这些输入转换为分号 它们进入 SQLite 核心。

23. 命令行选项

CLI 有许多可用的命令行选项。使用 --help 命令行选项查看列表:

复制代码
$ sqlite3 --help
Usage: ./sqlite3 [OPTIONS] FILENAME [SQL]
FILENAME is the name of an SQLite database. A new database is created
if the file does not previously exist. Defaults to :memory:.
OPTIONS include:
   --                   treat no subsequent arguments as options
   -A ARGS...           run ".archive ARGS" and exit
   -append              append the database to the end of the file
   -ascii               set output mode to 'ascii'
   -bail                stop after hitting an error
   -batch               force batch I/O
   -box                 set output mode to 'box'
   -column              set output mode to 'column'
   -cmd COMMAND         run "COMMAND" before reading stdin
   -csv                 set output mode to 'csv'
   -deserialize         open the database using sqlite3_deserialize()
   -echo                print inputs before execution
   -init FILENAME       read/process named file
   -[no]header          turn headers on or off
   -help                show this message
   -html                set output mode to HTML
   -interactive         force interactive I/O
   -json                set output mode to 'json'
   -line                set output mode to 'line'
   -list                set output mode to 'list'
   -lookaside SIZE N    use N entries of SZ bytes for lookaside memory
   -markdown            set output mode to 'markdown'
   -maxsize N           maximum size for a --deserialize database
   -memtrace            trace all memory allocations and deallocations
   -mmap N              default mmap size set to N
   -newline SEP         set output row separator. Default: '\n'
   -nofollow            refuse to open symbolic links to database files
   -nonce STRING        set the safe-mode escape nonce
   -nullvalue TEXT      set text string for NULL values. Default ''
   -pagecache SIZE N    use N slots of SZ bytes each for page cache memory
   -pcachetrace         trace all page cache operations
   -quote               set output mode to 'quote'
   -readonly            open the database read-only
   -safe                enable safe-mode
   -separator SEP       set output column separator. Default: '|'
   -stats               print memory stats before each finalize
   -table               set output mode to 'table'
   -tabs                set output mode to 'tabs'
   -unsafe-testing      allow unsafe commands and modes for testing
   -version             show SQLite version
   -vfs NAME            use NAME as the default VFS
   -zip                 open the file as a ZIP Archive

CLI 在命令行选项格式方面非常灵活。 允许使用一个或两个前导"-"字符。 因此,"-box"和"--box"的意思是一样的。 命令行选项从左到右处理。 因此,"--box"选项将覆盖先前的"--quote"选项。

大多数命令行选项都是不言自明的,但有一些值得额外 讨论如下。

23.1. --safe 命令行选项

--safe 命令行选项尝试禁用 CLI 的所有功能,这些功能 除了对特定数据库的更改之外,可能会导致对主计算机进行任何更改 在命令行上命名的文件。这个想法是,如果你收到一个大型 SQL 脚本 从未知或不受信任的来源,您可以运行该脚本以查看它的功能 使用 --safe 选项冒着被利用的风险。--safe 选项禁用(除其他外 事情):

  • .open 命令,除非使用了 --hexdb 选项或文件名为 ":memory:"。 这样可以防止脚本读取或写入任何未命名的数据库文件 原始命令行。
  • ATTACH SQL 命令。
  • 具有潜在有害副作用的 SQL 函数,例如 edit()、fts3_tokenizer()、load_extension()、readfile() 和 writefile()。
  • .archive 命令
  • .backup 和 .save 命令。
  • .import 命令
  • .load 命令
  • .log命令。
  • .shell 和 .system 命令。
  • .excel、.once 和 .output 命令。
  • 其他可能产生有害副作用的命令。

基本上,CLI 从磁盘上的文件读取或写入的任何功能 而不是禁用主数据库文件。

23.1.1. 绕过特定命令的 --safe 限制

如果命令行中还包含"--nonce NONCE"选项,则对于某些 大型任意 NONCE 字符串,然后是".nonce NONCE"命令(使用 相同的大随机数字符串)将允许下一个 SQL 语句或 dot-command 以绕过 --safe 限制。

假设您要运行一个可疑脚本,并且该脚本需要一个或 --safe 通常会禁用的两个功能。例如,假设它 需要附加一个额外的数据库。或者假设脚本需要加载 特定扩展名。这可以通过在 (小心 audited) ATTACH 语句或带有适当 ".nonce" 的 ".load" 命令 命令并使用"--nonce"命令行提供相同的随机数值 选择。然后,这些特定命令将被允许正常执行, 但所有其他不安全的命令仍将受到限制。

使用".nonce"是危险的,因为一个错误可以允许 恶意脚本会损坏您的系统。因此,请谨慎使用".nonce", 谨慎地,并且作为没有其他方法获得 脚本在 --safe 模式下运行。

23.2. --unsafe-testing 命令行选项

--unsafe-testing 命令行选项支持将 CLI 用于 SQLite库的内部测试。它对于使用 CLI 作为用于创建、修改或查询 SQLite 数据库的实用程序。 它的预期用途是允许通过直接架构更改进行脚本化测试, 防御措施被击败,某些特殊用途的、无证的、 启用了面向测试的 dot 命令。

需要使用 --unsafe-testing 选项才能诱导的不当行为 仅出于这个原因,通常不会被视为错误。CLI 行为 不支持或定义 --unsafe-testing。

23.3. --no-utf8 和 --utf8 命令行选项

在Windows平台上,当控制台用于输入或输出时, 字符编码之间需要转换,可用或发送到 控制台和 CLI 的内部 UTF-8 文本表示形式。过去的版本 的 CLI 接受了这些选项来启用或禁用翻译 它依赖于 Windows 控制台功能,因此可以使其 在现代版本的操作系统上生成或接受 UTF-8。

当前 CLI 版本(3.44.1 或更高版本)通过读取或写入执行控制台 I/O 来自/发送到 Windows 控制台 API 的 UTF-16。因为这甚至可以正常运行 在返回到 Window 2000 的 Windows 版本上,不再需要任何 对于这些选项。它们仍然被接受,但没有效果。

在所有情况下,非控制台文本 I/O 都是 UTF-8 编码的。

在非 Windows 平台上,这些选项也会被忽略。

24. 从源代码编译 sqlite3 程序

要在 unix 系统和 Windows 上使用 MinGW 编译命令行 shell, 通常的 configure-make 命令有效:

bash 复制代码
sh configure; make

无论您是从规范源构建,configure-make 都有效 从源代码树或合并的捆绑包。很少 依赖。从规范源代码构建时,需要一个有效的 tclsh。 如果使用合并束,则所有预处理工作正常 由 TCLSH 完成将已经执行,并且只有正常构建 工具是必需的。

一个有效的 zlib 压缩库是 需要才能使 .archive 命令运行。

在装有 MSVC 的 Windows 上,将 nmake 与 Makefile.msc 一起使用:

bash 复制代码
nmake /f Makefile.msc

要正确操作 .archive 命令,请将 zlib 源代码复制到 compat/zlib 子目录中 并以这种方式编译:

bash 复制代码
nmake /f Makefile.msc USE_ZLIB=1

24.1. 自己动手构建

sqlite3 命令行界面的源代码位于单个 名为"shell.c"的文件。shell.c 源文件是从其他 来源,但 shell.c 的大部分代码都可以在 src/shell.c.in 中找到。 (通过从规范源代码树中键入"make shell.c"来重新生成 shell.c。编译 shell.c 文件(一起编译 使用 SQLite3 库源代码)生成 可执行文件。例如:

bash 复制代码
gcc -o sqlite3 shell.c sqlite3.c -ldl -lpthread -lz -lm

建议使用以下附加编译时选项,以便 提供功能齐全的命令行 shell:

相关推荐
归寻太乙18 分钟前
C++函数重载完成日期类相关计算
开发语言·c++
尽蝶叙20 分钟前
C++:分苹果【排列组合】
开发语言·c++·算法
憧憬成为原神糕手1 小时前
c++_list
开发语言·c++
zyh200504301 小时前
c++的decltype关键字
c++·decltype
2401_862886781 小时前
蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
前端·c++·python·算法·游戏
后端小张1 小时前
Redis 执行 Lua,能保证原子性吗?
数据库·redis·缓存
离开地球表面_991 小时前
索引失效?查询结果不正确?原来都是隐式转换惹的祸
数据库·后端·mysql
lipviolet1 小时前
Redis系列---Redission分布式锁
数据库·redis·分布式
Zhen (Evan) Wang1 小时前
.NET 6 API + Dapper + SQL Server 2014
数据库·c#·.net
徐霞客3202 小时前
对于C++继承中子类与父类对象同时定义其析构顺序的探究
开发语言·c++