本文章摘自《MySQL Shell 8.0 中文版.pdf》第5章,文档链接:https://www.modb.pro/doc/117504。
本中文版文档采用 机翻及人工 相结合的方式,翻译自官方文档。
5. MySQL Shell 代码执行
5.1. Active Language
MySQL Shell 可以执行 SQL、JavaScript 或 Python 代码,但一次只能执行一种语言。活动模式(Active Language)决定了当前可执行的语言:
- 如果使用
SQL模式,语句将被作为SQL处理,这意味着它们将被发送到MySQL Server执行。 - 如果使用
JavaScript模式,语句将作为JavaScript代码进行处理。 - 如果使用
Python模式,语句将作为Python代码处理。
:::alert-info
【Important】
从版本 8.0.18 开始,MySQL Shell 使用 Python 3。对于包含系统支持的 Python 3 安装的平台,MySQL Shell 使用最新可用版本,最低支持版本为 Python 3.4.3。对于不包含 Python 3 的平台,MySQL Shell 捆绑 Python 3.7.4。MySQL Shell 保持与 Python 2.6 和 Python 2.7 的代码兼容性,因此如果需要这些旧版本,则可以使用适当的 Python 版本从源代码构建 MySQL Shell。
:::
当以交互模式运行 MySQL Shell 时,通过输入以下命令激活特定语言:\sql、\js、\py。
以批处理模式运行 MySQL Shell 时,通过传递 --js、--py 或 --sql 选项来激活特定语言。如果未指定,则默认模式是 JavaScript。
使用 MySQL Shell 将文件 code.sql 的内容作为 SQL 执行。
$> mysqlsh --sql < code.sql
使用 MySQL Shell 将文件 code.js 的内容作为 JavaScript 代码执行。
$> mysqlsh < code.js
使用 MySQL Shell 将文件 code.py 的内容作为 Python 代码执行。
$> mysqlsh --py < code.py
从 MySQL Shell 8.0.16 开始,可通过 \sql <SQL语句> 的方式在 JavaScript 或 Python 处于活动时,执行单个 SQL 语句。例如:
mysql-py> \sql select * from sakila.actor limit 3;
SQL 语句不需要任何额外的引号,并且语句分隔符是可选的。该命令仅接受单行中的单个 SQL 查询。使用这种方式,MySQL Shell 不会切换语言模式。执行 SQL 语句后,MySQL Shell 仍保持 JavaScript 或 Python 模式。
从 MySQL Shell 8.0.18 开始,可以在任何语言处于活动状态时通过 \system <OS命令> 或 \! <OS命令> 的方式执行操作系统命令。例如:
mysql-py> \system echo Hello from MySQL Shell!
MySQL Shell 显示操作系统命令的输出,或者如果无法执行该命令则返回错误。
5.2. 交互式代码执行
MySQL Shell 的默认模式提供您在命令提示符下键入的数据库操作的交互式执行。这些操作可以用 JavaScript、Python 或 SQL 编写,具体取决于当前的 活动语言。执行时,操作结果显示在屏幕上。
与其他语言解释器一样,MySQL Shell 对于语法非常严格。例如,以下 JavaScript 代码片段打开与 MySQL Server 的会话,然后读取并打印集合中的文档:
var mySession = mysqlx.getSession('user:pwd@localhost');
var result = mySession.getSchema('world_x').getCollection('countryinfo').find().execute();
var record = result.fetchOne();
while(record){
print(record);
record = result.fetchOne();
}
如上所示,调用 find() 函数后紧跟着的是 execute() 函数。CRUD 数据库命令只有在调用 execute() 时才会在 MySQL Server 上实际执行。不过,当以交互方式使用 MySQL Shell 时,只要按下 Return 键,就会隐式调用 execute()。然后,获取操作结果并将其显示在屏幕上。何时调用 execute() 的规则如下:
-
当以这种方式使用
MySQL Shell时,调用execute()成为可选项:Collection.add()Collection.find()Collection.remove()Collection.modify()Table.insert()Table.select()Table.delete()Table.update()
-
如果将对象分配给变量,则自动执行将被禁用。在此情况下,必须显示调用
execute()。 -
当处理一行并且函数返回任何可用的
Result对象时,Result对象包含的信息将自动(无需调用execute())显示在屏幕上。返回Result对象的函数包括:SQL执行和CRUD操作(如上所述)mysql和mysqlx模块中会话对象的事务处理和删除(drop)函数:-startTransaction()commit()rollback()dropSchema()dropCollection()ClassicSession.runSql()
根据上述规则,在 MySQL Shell 中以交互方式建立会话、查询、打印集合中的文档所需的语句如下:
mysql-js> var mySession = mysqlx.getSession('user:pwd@localhost');
mysql-js> mySession.getSchema('world_x').getCollection('countryinfo').find();
示例中,不需要调用 execute(),并且会自动打印 Result 对象。
5.2.1. 多行支持
在 Python 或 JavaScript 模式下,当语句块开始时(如函数定义、if/then 语句、for 循环等),会自动启用多行模式。在 SQL 模式下,当发出命令 \ 时,可启动多行模式。一旦启动多行模式,随后输入的语句即可被缓存。如:
mysql-sql> \
... create procedure get_actors()
... begin
... select first_name from sakila.actor;
... end
...
当在另一种语言(JavaScript、Python)处于活动状态时,通过 \sql <SQL语句> 方式执行单个 SQL 语句时,不能使用多行模式。该命令仅接受单行上的单个 SQL 查询。
5.3. 代码自动补全
MySQL Shell 支持按 Tab 键自动补全代码。MySQL Shell 命令 可以在任何语言模式下自动补全。例如,键入 \con,按 Tab 键即可补全 \connect。根据当前 Active Language SQL、JavaScript 和 Python 语言的关键字都可以自动补全。
自动补全支持以下文本对象:
- 在
SQL模式下,自动补全功能会感知当前活动的schema名称、table名称和column名称。 - 在
JavaScript和Python模式中,自动补全功能可以识别对象成员,例如:- 全局对象名称,如
session、db、dba、shell、mysql、mysqlx等。 - 全局对象的成员,如
session.connect()、dba.configureLocalInstance()等。 - 用户定义的全局变量
- 链式(
chained)对象属性引用,如shell.options.verbose。 - 链式(
chained)X DevAPI方法调用,如col.find().where().execute().fetchOne()。
- 全局对象名称,如
默认情况下,自动补全功能处于启用状态,要更改此行为,请参阅 配置自动补全。
激活自动补全功能后,如果光标前的文本正好有一个可能的匹配项,文本就会自动补全。如果自动补全功能发现多个可能的匹配项,则会发出蜂鸣声或使终端闪烁。如果再次按 Tab 键,将显示可能的补全列表。如果未找到匹配项,则不会自动补全。
5.3.1. SQL 自动补全
从 MySQL Shell 8.0.31 开始,在 SQL 模式中,可利用上下文感知功能,自动补全以下内容:
Schemas数据库Tables表Views视图Columns列- 存储过程与函数
Triggers触发器Events事件Engines存储引擎User-defined functions用户自定义函数Runtime functions运行时函数Log file groups日志文件组- 用户变量
- 系统变量
- 表空间
Users用户- 字符集与排序规则
Plugins插件
如果连接到 MySQL Server 实例但未选择 schema,自动补全功能可用于全局对象、字符集、存储引擎、 schema 等。如,在默认的 MySQL 安装中,除非提供 schema 名称中的一个或多个相关字符,否则 USE 会提示检测到的所有 schema 名称:
SQL > use
information_schema mysql performance_schema sys
如果选择了一个 schema,MySQL Shell 就会加载额外的 schema 信息,并可用于自动补全(Tables、Events 等)。如果从一个 schema 切换到另一个 schema,从上一个 schema 加载的对象仍可用于 SQL 自动补全。但是,在会话期间添加的新对象在运行 \rehash 命令之前,都无法用于 SQL 自动补全。
要获取建议列表或从所选 schema 中补全部分单词,请输入初始片段并按 Tab 键 2 次。例如:
- 在
SQL提示符下,输入片段:SE。 - 按
Tab键2次。以下建议将显示在您输入的下方:
SET SELECT
- 在
SQL提示符下,输入片段:SEL。 - 按
Tab键2次。片段自动完成为SELECT。
如果可能的结果有很多,系统会提示是否显示结果。例如:
Display all 118 possibilities? (y or n)
5.3.1.1. SQL 自动补全 API
自动补全 API 通过以下函数暴露给开发者:
JavaScript模式:shell.autoCompleteSql(statement, options)Python模式:shell.auto_complete_sql(statement, options)
5.3.1.2. Statement 与 options
-
statement: "string"
用于自动补全的部分 SQL 语句。 -
OptionsserverVersion: "string"
必选的。服务器语法版本。格式为:major.minor.patch。如serverVersion:"8.0.31"。sqlMode: "string"
必选的。要使用的SQL Mode。以逗号分隔的字符串,如sqlMode: "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"。有关详细信息,请参阅 https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html。statementOffset: number
可选的。语句中插入符号从零开始的偏移位置。默认值是语句的长度。uppercaseKeywords: [true|false]
默认为true,返回的关键字是否大写。filtered: [true|false]
默认为true,是否应使用自动补全的前缀过滤结果中返回的明确候选名称。
该函数使用以下语法返回一个描述语句自动补全候选语句的字典,如下:
{
"context": {
"prefix": string,
"qualifier": list of strings,
"references": list of dictionaries,
"labels": list of strings,
},
"keywords": list of strings,
"functions": list of strings,
"candidates": list of strings,
}
context:自动补全操作的上下文。prefix:自动补全的片段。qualifier:如果有符合条件的名称,则显示。例如:SELECT s:前缀为“s”,不存在限定符。SELECT schema1.t:前缀为 ‘t’,限定符为['schema1']。SELECT schema1.table1.c:前缀为 ‘c’,限定符为['schema1','table1']。SELECT schema1.table1.column1 FR:前缀为“FR”,不存在限定符。
references:在语句中检测到的引用。schema:schema的名称。table:语句中引用的表的名称。alias:表的别名。
labels:标记块中的标签。keywords:候选关键词建议。functions:名称也是关键字的候选MySQL库(运行时)函数。candidates:列出一个或多个受支持的候选对象。schemas,tables,views等。
JS > shell.autoCompleteSql("select * from ",{serverVersion: "8.0.30", sqlMode: "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"})
{
"candidates": [
"schemas",
"tables",
"views"
],
"context": {
"prefix": ""
},
"functions": [
"JSON_TABLE()"
],
"keywords": [
"DUAL",
"LATERAL"
]
}
5.3.2. JavaScript 与 Python 自动补全
在 JavaScript 和 Python 模式中,要补全的字符串,从按下 Tab 键时的当前光标位置开始从右向左排列。方法调用内部的内容会被忽略,但语法必须正确。这意味着字符串、注释和嵌套方法调用都必须正确闭合和平衡。这样才能正确处理链式方法。例如,当发出:
print(db.user.select().where("user in ('foo', 'bar')").e
按 Tab 键将导致自动补全尝试完成文本 db.user.select().where().e 但此无效代码会产生未定义的行为。以 . 分隔的标记之间的任何空白符(包括换行符)都将被忽略。
5.3.3. 配置自动补全
默认情况下,自动补全引擎处于启用状态。本节介绍如何禁用自动补全以及如何使用 MySQL Shell 的 \rehash 命令。自动补全使用 MySQL Shell 感知到的数据库名称对象缓存。启用自动补全后,此名称缓存会自动更新。例如,每当加载 schema 时,自动补全引擎都会根据 schema 中的文本对象更新名称缓存,以便可以自动补全表名称等。
可以通过如下方式,禁用此行为:
- 使用
--no-name-cache命令选项启动MySQL Shell。 - 修改
shell.options的autocomplete.nameCache和devapi.dbObjectHandles键(keys),以使在MySQL Shell运行时禁用自动补全功能。
当自动补全名称缓存被禁用时,可以通过发出 \rehash 手动更新自动补全功能识别的文本对象。这会强制根据当前的活动模式(JavaScript、Python、SQL)重新加载名称缓存。
要在 MySQL Shell 运行时禁用自动补全功能,请使用以下的 shell.options 键(keys):
autocomplete.nameCache: boolean:启用(true)或禁用(false)自动补全名称缓存以供SQL使用。devapi.dbObjectHandles: boolean:启用(true)或禁用(false)自动补全名称缓存以供X DevAPI数据库对象(如db.mytable、db.mycollection)使用。
默认情况下,这两个键(keys)都为 true。如果指定 --no-name-cache 命令选项,则这两个键都被设置为 false。
要在 MySQL Shell 运行时更改 SQL 的自动补全名称缓存,请发出:
shell.options['autocomplete.nameCache']=true
要在 MySQL Shell 运行时更改 JavaScript 和 Python 的自动补全名称缓存,请发出
shell.options['devapi.dbObjectHandles']=true
在任何语言模式(JavaScript、Python、SQL)中,都可以执行 \rehash 命令手动更新名称缓存。
5.4. 编辑代码
MySQL Shell 的\edit 命令(从 MySQL Shell 8.0.18 开始提供)在默认系统编辑器中打开命令进行编辑,然后在 MySQL Shell 中显示编辑后的命令以供执行。也可以使用简写形式 \e 或组合键 Ctrl-X Ctrl-E 调用该命令。如果为命令指定参数,则该参数将被放置在编辑器中。如果不指定参数,MySQL Shell 历史记录中的最后一个命令将被放置在编辑器中。
EDITOR 和 VISUAL 环境变量用于标识默认的系统编辑器。如果无法从这些环境变量中识别默认的系统编辑器,MySQL Shell 在 Windows 上使用 notepad.exe,在其他平台上使用 vi。命令编辑在临时文件中进行,随后 MySQL Shell 会将其删除。
完成编辑后,必须保存文件并关闭编辑器,然后 MySQL Shell 会显示已编辑的文本,可以按 Enter 执行;如果不想继续,则可按 Ctrl-C 取消。
例如,此处用户使用一组自定义列运行 MySQL Shell 内置报告线程,然后在系统编辑器中打开命令以添加某些列的显示名称:
\show threads --foreground -o tid,cid,user,host,command,state,lastwait,lastwaitl \e \show threads --foreground -o tid=thread_id,cid=conn_id,user,host,command,state,lastwait=last_wait_event,lastwaitl=wait_length
5.5. 代码历史
在 MySQL Shell 中执行的代码会存储在历史记录中,然后可以使用 ↑ 和 ↓ 箭头键进行访问。你还可以使用增量历史搜索功能搜索历史记录。可以使用 Ctrl+R 向后搜索,或 Ctrl+S 向前搜索历史记录。搜索激活后,键入字符会搜索历史记录中与之匹配的字符串,并显示第一个匹配字符。使用 Ctrl+S 或 Ctrl+R 查找与当前搜索词匹配的其他字符。输入更多字符可进一步细化搜索。在搜索过程中,可以按箭头键从当前搜索结果开始继续浏览历史记录。按 Enter 键接受显示的匹配结果。使用 Ctrl+C 取消搜索。
MySQL Shell 配置选项 history.maxSize 可设置历史记录中存储条目的最大数量。默认为 1000。如果历史条目数超过了配置的最大值,最旧的条目将被移除并丢弃。如果 history.maxSize 设置为 0,则不存储任何历史条目。
默认情况下,历史记录不会在会话之间保存,因此当 MySQL Shell 时,当前会话中的历史记录就会丢失。通过启用 MySQL Shell 的 history.autoSave 选项,可以在会话之间保存历史记录。如要使这一更改永久有效,请执行以下操作
mysqlsh-js> \option --persist history.autoSave=1
启用 history.autoSave 选项后,历史记录将存储在 MySQL Shell 配置路径中,在 Linux 和 macOS 上是 ~/.mysqlsh 目录,在 Windows 上是 %AppData%\MySQL\mysqlsh 文件夹。通过定义环境变量 MYSQLSH_USER_CONFIG_HOME 可以在所有平台上重设该路径。保存的历史记录由 MySQL Shell 自动创建,只有所有者用户才能读取。如果无法读取或写入历史文件,MySQL Shell 会记录一条错误信息,并跳过读取或写入操作。在 MySQL Shell < 8.0.16,历史条目保存在一个历史文件中,该文件包含以所有 MySQL Shell语言发布的代码。在 MySQL Shell ≥ 8.0.16 中,历史记录按语言类型分别单独保存,文件名分别为 history.sql、history.js 和 history.py。
在 MySQL Shell 执行 \history 命令会按执行顺序显示历史条目及其编号,该编号可与 \history delete <entry_number> 命令一起使用。可以手动删除单个历史条目、指定数字范围的历史条目或历史记录的尾部。 也可以使用 \history clear 手动删除整个历史记录。 退出 MySQL Shell 时,如果配置选项 history.autoSave 为 true,历史文件中保留的历史条目将被保存,它们的编号将被重置为从 1 开始。如果 shell.options["history.autoSave"] 配置选项为 false(默认值),历史文件将被清除。
只有在 MySQL Shell 交互模式输入的代码才会添加到历史记录中。间接或内部执行的代码,如在执行 \source 命令时执行的代码,不会添加到历史记录中。当执行多行代码时,历史记录条目中的换行字符会被去掉。如果多次执行同一代码,则只在历史记录中存储一次,从而减少重复。
可以使用 --histignore 命令选项指定不添加到历史记录中的条目。此外,在 SQL 模式下使用 MySQL Shell 时,可以配置不应添加到历史记录中的字符串。当使用 \sql 命令执行单条 SQL 语句时,如果另一种语言处于活动状态,也会应用此历史忽略列表。
默认情况下,与 IDENTIFIED 或 PASSWORD 匹配的字符串不会添加到历史记录中。要配置更多匹配字符串,请使用 --histignore 命令选项或 shell.options["history.sql.ignorePattern"]。可以指定以冒号(:)分隔的多个字符串。历史命令匹配使用不区分大小写的 glob 模式(glob pattern)匹配。支持的通配符有 *(匹配 0 个或更多字符)和 ?(精确匹配 1 个字符)。默认字符串指定为 “*IDENTIFIED*:*PASSWORD*”。
最后执行的语句始终可通过 ↑ 箭头获得,即使对该语句已应用历史忽略列表。如果对最后执行的语句应用了历史忽略列表,那么一旦输入另一条语句,或在执行语句后立即退出 MySQL Shell,该语句就会从历史记录中删除。
5.6. 批处理代码执行
除了执行交互式代码之外,MySQL Shell 还提供从以下文件中执行批处理代码的功能:
- 加载的以用于处理的文件。
- 包含重定向到标准输入执行的代码的文件。
- 将来自不同源的代码重定向到标准输入进行执行。
:::alert-info
【Tip】
作为批量执行文件的替代方法,还可以从终端控制 MySQL Shell,请参阅 API 命令行集成。
:::
在批处理模式下,无法使用 交互式代码执行 中描述的命令逻辑,只能执行活动语言的有效代码。处理 SQL 代码时,使用以下逻辑逐条执行语句:读取/处理/打印结果。处理非 SQL 代码时,代码完全从输入源加载并作为一个单元执行。使用 --interactive(或-i)命令行选项可配置 MySQL Shell 处理输入源,就像在交互模式下发出输入源一样;这样就能在批处理中使用交互模式提供的所有功能。
:::alert-info
【Note】
在此情况下,无论是什么源,都会逐行读取并使用交互式管道进行处理。
:::
输入将根据 MySQL Shell 中选择的当前编程语言(默认为 JavaScript)进行处理。可以使用 MySQL Shell 的 defaultMode 配置选项更改默认编程语言。扩展名为 .js、.py 和 .sql 的文件总是以相应的语言模式处理,与默认编程语言无关。
此示例演示:如何从文件 code.js 加载 JavaScript 代码以进行批处理:
$> mysqlsh --file code.js
此示例演示:将文件 code.js 中的 JavaScript 代码重定向到标准输入来执行:
$> mysqlsh < code.js
此示例演示:如何将 SQL 代码重定向到标准输入以在 Linux 平台上执行:
$> echo "show databases;" | mysqlsh --sql --uri user@192.0.2.20:33060
:::alert-info
【Note】
要在 Windows 平台上运行此命令,必须删除 echo 命令中字符串周围的引号。
:::
从 MySQL Shell 8.0.22 开始,--pym 命令行选项可用于在 Python 模式下将指定的 Python 模块作为脚本执行。该选项的工作方式与 Python 的 -m 命令行选项相同。
5.6.1. 可执行脚本
在 Linux 上,可以通过在首行包含 #! 及 MySQL Shell 的完整路径和 --file 选项来创建与 MySQL Shell 一起运行的可执行脚本。例如:
#!/usr/local/mysql-shell/bin/mysqlsh --file
print("Hello World\n");
脚本文件必须在文件系统中为可执行文件。运行脚本会调用 MySQL Shell 并执行脚本的内容。
5.6.2. 脚本中的 SQL 执行
X 协议会话中通常使用 sql() 函数执行 SQL 查询,该函数以字符串形式接收 SQL 语句,并返回一个 SqlExecute 对象。该对象用于绑定和执行 SQL 查询并返回结果。然而,传统 MySQL 协议会话中使用 runSql() 函数执行 SQL 查询,该函数接受 SQL 语句及其参数,将指定的参数绑定到指定的 SQL 查询中,然后单步执行查询,并返回结果。
如果需要创建独立于用于连接 MySQL Server 协议的 MySQL Shell 脚本,MySQL Shell 提供了用于 X 协议的 session.runSql() 函数,其工作方式与传统 MySQL 协议会话中的 runSql() 函数相同。在 MySQL Shell 中,只能使用这个函数来代替 sql(),这样你的脚本就能在 X 协议会话或传统 MySQL 协议会话中运行。Session.runSql() 返回一个 SqlResult 对象,该对象与传统 MySQL 协议函数返回的 ClassicResult 对象的规格一致,因此可以用同样的方式处理结果。
:::alert-info
【Note】
Session.runSql() 是 JavaScript 和 Python 中的 MySQL Shell X DevAPI 实现所独有的,并非标准 X DevAPI 的一部分。
:::
要浏览查询结果,可以使用 fetchOneObject() 函数,该函数适用于传统的 MySQL 协议和 X 协议。该函数以脚本对象的形式返回下一个结果。列名用作字典中的键(如果是有效标识符,则用作对象属性),行值用作字典中属性值。对对象所作的更新不会保留在数据库中。
如,MySQL Shell 脚本中的这段代码可与 X 协议会话或传统 MySQL 协议会话配合使用,以检索和输出给定国家/地区的城市名称:
var resultSet = mySession.runSql("SELECT * FROM city WHERE countrycode = ' AUT'");
var row = resultSet.fetchOneObject();
print(row['Name']);
5.7. 输出格式
MySQL Shell 可以以表格、Tab 制表符或垂直格式打印结果,也可以以美化或原始的 JSON 格式打印结果。从 MySQL Shell 8.0.14 开始,MySQL Shell 配置选项 resultFormat 可用于为所有会话或仅当前会话指定永久的默认输出格式,更改后立即生效。有关设置 MySQL Shell 配置选项的说明,请参阅 配置 MySQL Shell 选项。另外,也可以在启动时使用命令行选项 --result-format 或其别名(--table、--tabbed、--vertical)来指定会话的输出格式。有关命令行选项的列表,请参阅 mysqlsh。
如果未指定 resultFormat 配置选项,当 MySQL Shell 处于交互模式时,打印结果集的默认格式是格式化的表格;当 MySQL Shell 处于批处理模式时,打印结果集的默认格式是 Tab 制表符分隔的输出。使用 resultFormat 选项设置默认格式时,该默认格式适用于交互模式和批处理模式。
MySQL Shell 函数 shell.dumpRows() 可以将查询返回的结果集格式化为 MySQL Shell 支持的任何输出格式,并将其转储到控制台。
为了帮助 MySQL Shell 与外部工具集成,从命令行启动 MySQL Shell 时,可以使用 --json 选项控制所有 MySQL Shell 输出的 JSON 封装(wrapping):
- 当开启
JSON封装时,MySQL Shell会生成美化的JSON(默认)或原始JSON,并忽略resultFormat配置选项的值。 - 当关闭
JSON封装或未请求会话时,会按照resultFormat配置选项指定的格式正常输出结果集。
outputFormat 配置选项现已弃用。该选项结合了 JSON 封装(wrapping)和结果打印功能。如果在 MySQL Shell 配置文件或脚本中仍指定该选项,则行为如下:
- 若指定
outputFormat为json或json/raw,则outputFormat分别使用美化或原始JSON激活JSON封装。 - 若指定
outputFormat为table、tabbed或vertical,则outputFormat会关闭JSON封装并将会话的resultFormat配置选项设置为适当的值。
5.7.1. Table 格式
当 MySQL Shell 处于交互模式时,默认使用 table 格式打印结果集。查询结果以格式化表格形式呈现,以便更好地查看并帮助分析。
要在批处理模式下获得此输出格式,请使用 --result-format=table 命令行选项(或其别名 --table)启动 MySQL Shell,或将 MySQL Shell 配置选项 resultFormat 设置为 table。
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','table')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
+------+------------+-------------+---------------+-------------------------+
| ID | Name | CountryCode | District | Info |
+------+------------+-------------+---------------+-------------------------+
| 1523 | Wien | AUT | Wien | {"Population": 1608144} |
| 1524 | Graz | AUT | Steiermark | {"Population": 240967} |
| 1525 | Linz | AUT | North Austria | {"Population": 188022} |
| 1526 | Salzburg | AUT | Salzburg | {"Population": 144247} |
| 1527 | Innsbruck | AUT | Tiroli | {"Population": 111752} |
| 1528 | Klagenfurt | AUT | Kärnten | {"Population": 91141} |
+------+------------+-------------+---------------+-------------------------+
6 rows in set (0.0030 sec)
5.7.2. Tab 分隔格式
在批处理模式下运行 MySQL Shell 时,默认使用 Tab 制表符格式打印结果集,以便为自动分析提供更好的输出。
要在交互模式下获得此输出格式,请使用 --result-format=tabbed 命令行选项(或其别名 --tabbed)启动 MySQL Shell,或将 MySQL Shell 配置选项 resultFormat 设置为 tabbed。
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','tabbed')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
ID Name CountryCode District Info
1523 Wien AUT Wien {"Population": 1608144}
1524 Graz AUT Steiermark {"Population": 240967}
1525 Linz AUT North Austria {"Population": 188022}
1526 Salzburg AUT Salzburg {"Population": 144247}
1527 Innsbruck AUT Tiroli {"Population": 111752}
1528 Klagenfurt AUT Kärnten {"Population": 91141}
6 rows in set (0.0041 sec)
5.7.3. 垂直格式
垂直格式打印结果集,与 \G 查询终止符用于 SQL 查询时的方式相同。当单个数据行过长时,垂直格式更具可读性。
要获得此输出格式,请使用 --result-format=vertical 命令行选项(或其别名 --vertical)启动 MySQL Shell,或将 MySQL Shell 配置选项 resultFormat 设置为 vertical。
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','vertical')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
*************************** 1. row ***************************
ID: 1523
Name: Wien
CountryCode: AUT
District: Wien
Info: {"Population": 1608144}
*************************** 2. row ***************************
ID: 1524
Name: Graz
CountryCode: AUT
District: Steiermark
Info: {"Population": 240967}
*************************** 3. row ***************************
ID: 1525
Name: Linz
CountryCode: AUT
District: North Austria
Info: {"Population": 188022}
*************************** 4. row ***************************
ID: 1526
Name: Salzburg
CountryCode: AUT
District: Salzburg
Info: {"Population": 144247}
*************************** 5. row ***************************
ID: 1527
Name: Innsbruck
CountryCode: AUT
District: Tiroli
Info: {"Population": 111752}
*************************** 6. row ***************************
ID: 1528
Name: Klagenfurt
CountryCode: AUT
District: Kärnten
Info: {"Population": 91141}
6 rows in set (0.0027 sec)
5.7.4. JSON 格式输出
MySQL Shell 提供了许多 JSON 格式选项来打印结果集:
-
json或json/pretty
这些选项都会生成打印美化的JSON。 -
ndjson或json/raw
这些选项都会生成由换行符分隔的原始JSON。 -
json/array
此选项生成包装在JSON数组中的原始JSON。
可以通过使用 --result-format=value 命令行选项启动 MySQL Shell 或设置 MySQL Shell 配置选项 resultFormat 来指定这些输出格式。
在批处理模式下,为了帮助将 MySQL Shell 与外部工具集成,可以在从命令行启动 MySQL Shell 时使用 --json 选项来控制所有输出的 JSON 封装。当 JSON 封装打开时,MySQL Shell 生成美化的 JSON(默认)或原始 JSON,并且忽略 MySQL Shell 配置选项 resultFormat 的值。有关说明,请参阅 JSON 包装。
json或json/pretty
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','json')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
{
"ID": 1523,
"Name": "Wien",
"CountryCode": "AUT",
"District": "Wien",
"Info": {
"Population": 1608144
}
}
{
"ID": 1524,
"Name": "Graz",
"CountryCode": "AUT",
"District": "Steiermark",
"Info": {
"Population": 240967
}
}
{
"ID": 1525,
"Name": "Linz",
"CountryCode": "AUT",
"District": "North Austria",
"Info": {
"Population": 188022
}
}
{
"ID": 1526,
"Name": "Salzburg",
"CountryCode": "AUT",
"District": "Salzburg",
"Info": {
"Population": 144247
}
}
{
"ID": 1527,
"Name": "Innsbruck",
"CountryCode": "AUT",
"District": "Tiroli",
"Info": {
"Population": 111752
}
}
{
"ID": 1528,
"Name": "Klagenfurt",
"CountryCode": "AUT",
"District": "Kärnten",
"Info": {
"Population": 91141
}
}
6 rows in set (0.0031 sec)
ndjson或json/raw
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','ndjson')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
{"ID":1523,"Name":"Wien","CountryCode":"AUT","District":"Wien","Info":{"Population":1608144}}
{"ID":1524,"Name":"Graz","CountryCode":"AUT","District":"Steiermark","Info":{"Population":240967}}
{"ID":1525,"Name":"Linz","CountryCode":"AUT","District":"North Austria","Info":{"Population":188022}}
{"ID":1526,"Name":"Salzburg","CountryCode":"AUT","District":"Salzburg","Info":{"Population":144247}}
{"ID":1527,"Name":"Innsbruck","CountryCode":"AUT","District":"Tiroli","Info":{"Population":111752}}
{"ID":1528,"Name":"Klagenfurt","CountryCode":"AUT","District":"Kärnten","Info":{"Population":91141}}
6 rows in set (0.0032 sec)
json/array
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','json/array')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
[
{"ID":1523,"Name":"Wien","CountryCode":"AUT","District":"Wien","Info":{"Population":1608144}},
{"ID":1524,"Name":"Graz","CountryCode":"AUT","District":"Steiermark","Info":{"Population":240967}},
{"ID":1525,"Name":"Linz","CountryCode":"AUT","District":"North Austria","Info":{"Population":188022}},
{"ID":1526,"Name":"Salzburg","CountryCode":"AUT","District":"Salzburg","Info":{"Population":144247}},
{"ID":1527,"Name":"Innsbruck","CountryCode":"AUT","District":"Tiroli","Info":{"Population":111752}},
{"ID":1528,"Name":"Klagenfurt","CountryCode":"AUT","District":"Kärnten","Info":{"Population":91141}}
]
6 rows in set (0.0032 sec)
5.7.5. JSON 封装
为了帮助将 MySQL Shell 与外部工具集成,可以在从命令行启动 MySQL Shell 时使用 --json 选项来控制所有 MySQL Shell 输出的 JSON 封装。--json 选项仅对指定它的 MySQL Shell 会话有效。
指定 --json、--json=pretty 或 --json=raw 将打开会话的 JSON 封装。使用 --json=pretty 或未指定任何值,会生成打印美化的 JSON。使用 --json=raw,生成原始 JSON。
打开 JSON 封装后,在配置文件或命令行(使用 --result-format 选项或其别名之一)中为 MySQL Shell 配置选项 resultFormat 指定的任何值都将被忽略。
指定 --json=off 将关闭会话的 JSON 封装。当关闭 JSON 封装或会话未请求 JSON 封装时,结果集将以 MySQL Shell 配置选项 resultFormat 指定的格式正常输出。
--json或--json=pretty
$> echo "select * from world_x.city where countrycode='AUT'" | mysqlsh --json --sql --uri user@localhost:33060
or
$> echo "select * from world_x.city where countrycode='AUT'" | mysqlsh --json=pretty --sql --uri user@localhost:33060
{
"hasData": true,
"rows": [
{
"ID": 1523,
"Name": "Wien",
"CountryCode": "AUT",
"District": "Wien",
"Info": {
"Population": 1608144
}
},
{
"ID": 1524,
"Name": "Graz",
"CountryCode": "AUT",
"District": "Steiermark",
"Info": {
"Population": 240967
}
},
{
"ID": 1525,
"Name": "Linz",
"CountryCode": "AUT",
"District": "North Austria",
"Info": {
"Population": 188022
}
},
{
"ID": 1526,
"Name": "Salzburg",
"CountryCode": "AUT",
"District": "Salzburg",
"Info": {
"Population": 144247
}
},
{
"ID": 1527,
"Name": "Innsbruck",
"CountryCode": "AUT",
"District": "Tiroli",
"Info": {
"Population": 111752
}
},
{
"ID": 1528,
"Name": "Klagenfurt",
"CountryCode": "AUT",
"District": "Kärnten",
"Info": {
"Population": 91141
}
}
],
"executionTime": "0.0067 sec",
"affectedRowCount": 0,
"affectedItemsCount": 0,
"warningCount": 0,
"warningsCount": 0,
"warnings": [],
"info": "",
"autoIncrementValue": 0
}
--json=raw
$> echo "select * from world_x.city where countrycode='AUT'" | mysqlsh --json=raw --sql --uri user@localhost:33060
{"hasData":true,"rows":[{"ID":1523,"Name":"Wien","CountryCode":"AUT","District":"Wien","Info":{"Population":1608144}},{"ID":1524,"Name":"Graz","CountryCode":"AUT","District":"Steiermark","Info":{"Population":240967}},{"ID":1525,"Name":"Linz","CountryCode":"AUT","District":"North Austria","Info":{"Population":188022}},{"ID":1526,"Name":"Salzburg","CountryCode":"AUT","District":"Salzburg","Info":{"Population":144247}},{"ID":1527,"Name":"Innsbruck","CountryCode":"AUT","District":"Tiroli","Info":{"Population":111752}},{"ID":1528,"Name":"Klagenfurt","CountryCode":"AUT","District":"Kärnten","Info":{"Population":91141}}],"executionTime":"0.0117 sec","affectedRowCount":0,"affectedItemsCount":0,"warningCount":0,"warningsCount":0,"warnings":[],"info":"","autoIncrementValue":0}
5.7.6. 结果元数据
执行操作时,除了返回任何结果之外,还会返回一些附加信息。当满足以下任一条件时,附加信息包括受影响的行数、警告、持续时间等信息:
JSON格式用于输出MySQL Shell以交互模式运行。
当 JSON 格式用于输出时,元数据将作为 JSON 对象的一部分返回。在交互模式下,元数据在结果之后打印。
5.8. API 命令行集成
MySQL Shell 通过 API 命令行集成提供了大部分功能,使用的语法无需打开交互界面即可访问对象及其函数。这使您能够轻松地将 mysqlsh 与其他工具集成。例如,如果想使用 bash 脚本自动创建 InnoDB Cluster,则可以使用命令行集成来调用 AdminAPI 操作。此功能类似于使用 --execute 选项,但命令行集成使用简化的参数语法,减少了终端可能需要的引用和转义。与批处理模式不同,命令行集成是无状态的。这意味着执行返回对象无法供后续操作使用的操作。命令行集成调用操作或全局对象的函数,然后返回。
5.8.1. 命令行集成概述
本节提供命令行集成的概述和一些基本使用示例。有关更多详细信息,请参阅 命令行集成详细信息。
以下内置的 MySQL Shell 全局对象可在命令行集成中使用:
-
session
表示当前的全局会话。 -
db
当指定了默认数据库(schema),并使用X协议建立了全局会话时,db对象可用,并表示该默认的schema。。请参阅 https://dev.mysql.com/doc/refman/8.0/en/document-store.html。 -
cluster
代表一个InnoDB Cluster。 -
clusterset
代表一个InnoDB ClusterSet。 -
rs
代表一个InnoDB ReplicaSet。 -
shell
提供对各种MySQL Shell函数的访问。如用于配置MySQL Shell选项的shell.options。请参阅 配置 MySQL Shell 选项 -
util
提供了对MySQL Shell工具的访问,如升级检查工具(utl.checkForServerUpgrade())、JSON 导入工具(util.importJSON())和并行表导入工具(util.importTable())。请参阅 MySQL Shell 工具。
有关更多信息,请参阅 MySQL Shell 全局对象
5.8.1.1. 命令行集成语法
:::alert-info
【Important】
从 MySQL Shell 8.0.32 开始,MySQL Shell 默认读取 MySQL Server 选项文件和登录路径。因此,如果连接到使用选项文件的 MySQL Server,默认情况下将使用该选项文件,并尝试使用该配置创建全局会话。如果不想使用选项文件,则必须为命令行指定 --no-defaults。
:::
可以通过启动 mysqlsh 工具并传入特殊的 -- 选项来访问命令行集成。当以这种方式启动 MySQL Shell 时,-- 表示选项列表(例如要连接的服务器、要使用的语言等)的结束,-- 之后的所有内容都将传递给命令行集成。命令行集成支持特定语法,该语法基于 MySQL Shell 交互界面中使用的对象和方法。要使用命令行集成语法执行操作,请在终端中执行以下操作:
mysqlsh [options] -- [shell_object]+ object_method [arguments]
语法元素如下:
-
shell_object
是一个映射到MySQL Shell全局对象的字符串。命令行集成支持嵌套对象。要调用嵌套对象中的函数,请提供以空格分隔的层次结构中的对象列表,以找到所需的对象。 -
object_method
是最后一个shell_object提供的方法名称。方法名称可以按照JavaScript或Python命名约定,或替代的命令行集成友好格式提供,其中所有已知函数都使用小写字母,且单词之间用连字符分隔。object_method的名称会自动从标准JavaScript风格的camelCase(驼峰式) 名称转换而来。例如,createCluster变成create-cluster。 -
arguments
参数是调用object_method时传递给它的参数。
shell_object 必须与公开的全局对象之一匹配,并且任何嵌套对象必须是列表中前一个对象的子对象。 object_method 必须与列表方法中最后一个对象之一匹配,并且必须以有效格式定义(JavaScript、Python 或命令行友好格式)。如果它们与有效对象及其方法不一致,MySQL Shell 将以状态码 10 退出。请参阅 MySQL Shell 命令行集成示例
5.8.1.2. 命令行集成中可用的对象
要找出命令行集成中可用的对象和方法,最好查询正在使用的 MySQL Shell。因为除了与 MySQL Shell 捆绑的标准对象之外,插件的其他对象也可能被暴露。
可通过如下方式,获取命令行集成支持的对象列表。这将显示对象列表以及该对象提供的内容的简短描述。
$ mysqlsh -- --help
获取对象的命令行集成中可用的函数列表:
$ mysqlsh -- object --help
有关详细信息,请参阅 命令行帮助
5.8.1.3. 命令行集成参数语法
参数列表是可选的,所有参数必须遵循本节所述的适合命令行使用的语法。特殊字符(如空格或引号)和引号在传递给 MySQL Shell 之前会由系统 shell(bash、cmd 等)处理。如果你不熟悉你的系统 shell 在解析命令时如何处理这些字符序列,你应该尽量避免使用它们。例如,要传递一个带引号的参数,如 "list, of, names",仅在命令行中使用这种语法是不够的。需要使用系统的 shell 语法来转义这些引号("")。否则,MySQL Shell 可能接收不到实际的引号。请参阅 定义参数。
在参数列表中可以使用两种类型的参数:匿名参数 和 命名参数。匿名参数用于定义简单类型的参数,如字符串、数字、布尔值和空值。命名参数用于定义列表参数值和字典参数中的选项,它们是 键值对,其中的值是简单类型。它们的使用必须遵循以下模式(pattern):
[positional_argument | named_argument]*
语法的所有部分都是可选的,并且可以按任何顺序给出。然后,这些参数将按以下顺序转换为传递给方法调用的参数:
- 来自列表的命名参数会将值附加到产生该命名参数的列表参数中
- 来自字典的命名参数会将值添加到产生该命名参数的字典参数中
- 如果字典参数中存在未定义明确选项的参数,则该参数会接受不属于另一个
List或Dictionary参数的任何已命名参数。 - 为函数调用提供的任何其余参数都将按照提供的顺序进行处理
5.8.1.4. 命令行集成示例
与使用 --execute 选项相比,使用命令行集成调用 MySQL Shell API 函数更简单、更省事。。以下示例展示了如何使用此功能:
- 检查
MySQL Server实例是否适合升级,并将结果以 JSON 格式返回,以便进一步处理:
$ mysqlsh -- util check-for-server-upgrade --user=root --host=localhost --port=3301 --password='password' --outputFormat=JSON --config-path=/etc/mysql/my.cnf
MySQL Shell 交互模式下的等效命令:
mysql-js> util.checkForServerUpgrade({user:'root', host:'localhost', port:3301}, {password:'password', outputFormat:'JSON', configPath:'/etc/mysql/my.cnf'})
- 部署端口为
1234的InnoDB Cluster沙箱实例,并指定用于连接的密码:
$ mysqlsh -- dba deploy-sandbox-instance 1234 --password=password
MySQL Shell 交互模式下的等效命令:
mysql-js> dba.deploySandboxInstance(1234, {password: password})
- 使用监听端口
1234的沙盒实例创建InnoDB Cluster,并指定名称mycluster:
$ mysqlsh root@localhost:1234 -- dba create-cluster mycluster
MySQL Shell 交互模式下的等效命令:
mysql-js> dba.createCluster('mycluster')
- 使用监听端口
1234的沙盒实例检查InnoDB Cluster的状态:
$ mysqlsh root@localhost:1234 -- cluster status
MySQL Shell 交互模式下的等效命令:
mysql-js> cluster.status()
- 配置
MySQL Shell以打开命令历史记录:
$ mysqlsh -- shell options set_persist history.autoSave true
MySQL Shell 交互模式下的等效命令:
mysql-js> shell.options.set_persist('history.autoSave', true);
5.8.2. 命令行集成详情
5.8.2.1. API 函数的命令行集成
MySQL Shell 提供了暴露不同功能的全局对象,例如用于InnoDB Cluster 和 InnoDB ReplicaSet 管理操作的 dba、用于实用函数的 util 等。全局对象提供从 MySQL Shell 脚本模式调用的功能。除了交互式 MySQL Shell 集成之外,还可以使用命令行集成,直接从终端调用对象函数,从而轻松与其他工具集成。
在交互模式下使用 MySQL Shell 附带的 API 时,典型的函数语法如下:
object.functionName(parameter1, parameter2, ..., parameterN)
这些参数定义了向 API 函数提供数据的顺序。在大多数情况下,API 函数希望参数采用特定的数据类型,但也有少数例外情况,即一个特定参数可以处理多种数据类型。API 函数中参数使用的数据类型可以是以下类型之一:
-
Scalars
标量,如string,numbers,booleans,null -
Lists
列表 -
Dictionary
key-value键值对,其中key是字符串 -
Objects
对象
列表参数通常被限制为包含预定义数据类型的元素,例如字符串列表,但是,可能存在支持不同数据类型的项目的列表参数。
字典参数接受 键值对,其中键(key)是字符串。与键关联的值通常应该是预定义的数据类型。但是,在某些情况下,同一键的值可能支持不同的数据类型。因此,字典参数可以是以下类型之一:
- 允许使用预定义的键值对集,在这种情况下,指定不在预定义集中的键会导致错误。
- 不存在预定义的键值对集,字典接受任何键
换句话说,某些字典参数指定了哪些键是有效的。对于这些参数,尝试使用该组之外的键会导致错误。当不存在预定义的值集时,可以使用任何数据类型的任何值。字典参数如果没有预定义的键列表,则可以接受任何键值对,只要该键不在另一个字典参数的预定义集中。
要使用命令行集成调用全局对象暴露的 API 函数,而无需在 MySQL Shell 中启动交互会话,就必须以正确的方式提供所需的数据。这包括定义调用 API 函数的方式,以及将其参数从命令行参数映射到 API 参数的方式。
:::alert-info
【Important】
命令行集成并未公开所有 MySQL Shell 函数。例如,诸如 dba.getCluster() 等函数依赖于返回一个对象,然后在进一步操作中使用该对象。命令行集成不会公开此类操作。
同样,MySQL Shell 命令行集成也不支持将对象作为参数。任何带有对象类型参数的 API 函数都不能与命令行集成一起使用。对象的生命周期仅限于创建它的 MySQL Shell 调用的生命周期。由于 mysqlsh 在通过此 API 语法执行对象方法后会立即退出,因此从 API 调用接收或传入的任何对象都会立即退出作用域。在开发希望与命令行集成的 MySQL Shell 插件时,应考虑到这一点。
:::
从命令行调用 MySQL Shell API 函数的一般格式是:
$ mysqlsh [shell options] -- [shell_object]+ object_function [anonymous_arguments|named arguments]*
shell_object:指定一个全局对象,其中包含供命令行使用的公开函数。支持以空格分隔的列表嵌套对象。object_function:指定应执行的最后一个shell_object的API函数。[anonymous_arguments|named arguments]*:指定传递给object_function调用的参数
对于大多数可用的 API,都需要一个对象,例如:
$ mysqlsh -- shell status
但对于嵌套对象,必须指明对象列表。例如,要调用 shell.options 暴露的函数,如 setPersist(optionName, value),请使用以下语法:
$ mysqlsh -- shell options set-persist defaultMode py
MySQL Shell 插件中定义的嵌套对象可能会发生类似的情况。
传递给函数的参数可以分为以下类型:
- 匿名参数:它们是提供给命令的原始值。例如,在以下调用中的
1、one、true是匿名参数:
$ mysqlsh -- object command 1 one true
- 命名参数:以
--key=value形式提供的键值对。例如,在以下调用中,--sample和--path是命名参数:
$ mysqlsh -- object command 1 one true --sample=3 --path=some/path
鉴于参数的这种划分,从命令行集成调用 API 函数的一般格式是:
$ mysqlsh [shell options] -- object command [anonymous arguments][named arguments]
匿名参数的顺序很重要,因为它们按位置方式处理的。另一方面,命名参数可以出现在任何地方,因为它们会首先被处理,并与相应的参数关联。命名参数被处理完毕后,匿名参数将会以位置方式处理。
5.8.2.2. 定义参数
https://dev.mysql.com/doc/mysql-shell/8.0/en/cli-integration-defining-arguments.html
如 MySQL Shell API 函数的命令行集成 中所述,MySQL Shell 中的大多数 API 都期望所提供的参数具有特定的数据类型。可以使用 JSON 规范提供命令行参数中的值,但需要注意以下事项。某些终端会对数据进行预处理,可能会影响向 MySQL Shell 提供数据的方式,这取决于所使用的终端。例如:
- 如果发现空格,某些终端会分割参数。
- 分割逻辑可能会忽略连续的空格。
- 引号可以被删除。
MySQL Shell 会根据运行终端提供的值进行解释,因此必须以正确格式向终端提供数据。例如:
-
某些终端需要转义引号
-
在下列情况下,字符串参数应加引号:
- 参数中,包含空格
- 参数是一个列表参数,并包含逗号
- 参数中包含转义字符
-
API参数可以接受不同的数据类型,并且值(基于 JSON 规范)可能是错误的数据类型。 -
使用
JSON定义参数时,请为字符串value和字符串key加上引号。避免在key和value收尾加不必要的空白字符。
以下示例说明了一些参数的处理。
- 要传递多个参数(每个参数都是一个字符串),不需要引号:
在本例中,MySQL Shell获取2个参数:参数1为simple,参数2为string。
$ mysqlsh -- object function simple string
- 如果希望将这两个字符串视为单个参数,则必须将它们括在引号(
"")中,如下所示。
在此情况下,MySQL Shell获取一个参数:参数1为simple string。
$ mysqlsh -- object function "simple string"
- 要使用包含反斜杠(
\)等字符的参数,必须将字符串加引号("")。否则该字符将被忽略。例如:
在这种情况下,MySQL Shell获取1个参数:simpletstring,反斜杠(\)字符已被忽略。
$ mysqlsh -- object function simple\tstring
- 为了确保反斜杠(
\)字符可被传递到MySQL Shell,请用引号("")将字符串引起来:
在此情况下,MySQL Shell获得 1 个参数:simple\\tstring。
$ mysqlsh -- object function "simple\tstring"
使用命令行集成时,定义 JSON 数组有其自身的注意事项。例如,在 MySQL Shell 交互模式中,可以将 JSON 数组定义为:
["simple",123]
要在命令行集成中使用相同的数组则需要特定的引号。以下示例说明了如何正确为 JSON 数组使用引号:
- 试图以与交互模式相同的方式传递
JSON数组是行不通的:
在此情况下,MySQL Shell将获得2个参数:参数1是[simple,参数2是123]。
$ mysqlsh -- object function ["simple", 123]
- 在数组中不使用空格会有所帮助,但它仍然是一个无效的
JSON数组:
在此情况下,MySQL Shell将获得1个参数:[simple,123]。
$ mysqlsh -- object function ["simple",123]
- 要创建有效的
JSON数组,需在已加引号的字符串元素中添加转义引号(\"),例如:
在此情况下,MySQL Shell将获得1参数:["simple",123]。
$ mysqlsh -- object function ["\"simple\"",123]
要使用包含 JSON 对象的 JSON 数组,需要以类似的方式加引号。例如,在 MySQL Shell 交互模式中,可以将包含 JSON 对象的 JSON 数组定义为
{"firstName":"John","lastName":"Smith"}
下面的示例说明了如何在命令行集成中正确传递上例中的数组。
- 试图以与交互模式相同的方式传递 JSON 数组是行不通的:
在此情况下,MySQL Shell会获得2个参数:参数1是firstName:John,参数2是lastName:Smith。
$ mysqlsh -- object function {"firstName":"John","lastName":"Smith"}
- 对字符串数据使用转义引号会导致:
在此情况下,MySQL Shell 会获得2个参数:参数1是"firstName":"John",参数2是"lastName":"Smith"。
$ mysqlsh -- object function {"\"firstName\"":"\"John\"", "\"lastName\"":"\"Smith\""}
- 要解决这个问题,需要在
JSON对象最外层添加额外的引号(\"),来引起整个JSON对象:
在这种情况下,MySQL Shell 会获取1个参数:{"firstName":"John","lastName":"Smith"}。
$ mysqlsh -- object function "{"\"firstName\"":"\"John\"","\"lastName\"":"\"Smith\""}"
由于显示的困难以及不同平台中终端的行为方式可能不同的事实,因此支持以下格式。
- 字符串参数
- 列表参数
- 字典参数
- 附加的命名参数
5.8.2.2.1. 字符串参数
仅在以下情况下,才需要为字符串参数加引号:
- 参数中包含空格
- 参数中本身包含逗号并且用于列表参数(以避免拆分)
- 参数中包含转义字符
- 参数是一个数字、
null、true、false,但它应该是一个字符串。在这些情况下,应该使用内部转义引号来引用该值。换句话说,如果字符串值为"true",则应在CLI调用中将其定义为""true""。
5.8.2.2.2. 列表(List)参数
除了 JSON 数组之外,列表参数的参数还可以以下列形式提供::
- 逗号分隔的值列表
- 单独的匿名参数
当处理列表参数时(按位置顺序),所有剩余的匿名参数都是列表的一部分。以下 MySQL Shell CLI 调用是等效的:
- 使用逗号分隔的值列表:
$ mysqlsh root@localhost -- util dump-schemas sakila,employees
- 使用连续的匿名参数:
$ mysqlsh root@localhost -- util dump-schemas sakila employees
- 使用
JSON数组:
$ mysqlsh root@localhost -- util dump-schemas ["\"sakila\"","\"employees\""]
5.8.2.2.3. 字典参数
字典是使用键值对创建的,字典参数中键(Key)的值也可以使用命名参数指定:
--key=value
以下 MySQL Shell CLI 调用说明了如何为 util.dumpInstance() 函数中的 options 参数定义 threads 和 osBucketName 键:
$ mysqlsh -- util dump-instance my-dump --threads=8 --osBucketName=my-bucket
列表键
可以通过以下方式定义字典中列表键的值:
- 将值定义为
JSON数组。 - 将值定义为逗号分隔的值列表。
- 重复定义键的值。
例如,在以下调用中,传递给 util.dumpInstance() 操作的 exceptSchemas 键的定义是等效的:
- 使用
JSON数组:
$ mysqlsh root@localhost -- util dump-instance --outputUrl="my-dump" --excludeSchemas=["\"sakila\"","\"employees\""]
- 使用逗号分隔的值列表:
$ mysqlsh root@localhost -- util dump-instance --outputUrl="my-dump" --excludeSchemas=sakila,employees
- 重复定义多个
--excludeSchemas键:
$ mysqlsh root@localhost -- util dump-instance --outputUrl="my-dump" --excludeSchemas=sakila --excludeSchemas=employees
字典键
支持嵌套字典,但有以下限制:
- 仅支持一层嵌套。
- 不支持内部预定义键的验证。
- 不支持内部预期数据类型的验证。
为嵌套字典中的键定义值的语法如下:
--key=innerKey=value
例如,定义 decodeColumns 键,并将其传递给 util.importTable() 操作:
$ mysqlsh -- util import-table --decodeColumns=myColumn=1
5.8.2.2.4. 额外的俱名参数
如上一节所示,字典参数通过使用 --key=value 语法的命名参数来支持。还有另一种情况,参数必须指定为 命名参数(在列表参数之后定义的参数)。要提供属于列表参数的参数,最便捷方法是使用匿名参数,例如列表参数中的示例所示:
$ mysqlsh root@localhost -- util dump-schemas sakila employees
但是,此示例缺少 outputUrl 参数的参数,该参数对于 util.dumpSchemas() 操作是必需的。由于所有剩余的匿名参数都包含在 schema 列表中,因此无法将outputUrl 指定为匿名参数。例如,以下内容将不起作用:
$ mysqlsh root@localhost -- util dump-schemas sakila employees path/to/dump
在此调用中,路径 path/to/dump 将被解释为 schema 列表中的一项。因此,从命令行调用函数时,在列表参数之后定义的任何参数都必须指定为 命名参数。例如:
$ mysqlsh root@localhost -- util dump-schemas sakila employees --outputUrl=path/to/dump
5.8.2.3. 数据类型处理
一般情况下,参数的数据类型按优先顺序使用以下标准来确定:
- 目标参数的预期数据类型。
- 基于
JSON规范的值的数据类型。 - 用户指定的数据类型。
最后一种情况比较复杂(也比较少见),只适用于命名参数。例如,假设你有一个 MySQL Shell 插件函数,如:
def set_object_attributes(variables)
variables 是一个字典,没有预定义的值集,因此它接受任何键,也就接受任何数据类型的值。要将名为 streetNumber 的字符串属性设置为字符串值 123,请执行以下操作
$ mysqlsh -- plugin set-object-attributes --streetNumber=123
由于没有预期的数据类型,因此根据 JSON 规范,值 123 被解释为数值,但我们希望将其存储为字符串,而不是数字。
:::alert-info
【Note】
目前不存在这样的 API 函数,除非用户创建如上所述的插件。
:::
5.8.2.3.1. 用户数据类型
为了避免 MySQL Shell 尝试猜测输入数据类型的问题,命令行集成支持通过使用以下语法指定命名参数来强制使用特定数据类型:
--key:<type>=value
其中, type 为:
strintuintfloatboollistdictjson
如指定类型为字符串:
$ mysqlsh -- plugin set-object-attributes --streetNumber:str=1234
:::alert-info
【Important】
任何命名参数都可以使用这种格式,但在参数没有预期数据类型时才需要使用。如果参数有预期的数据类型,而你指定了不同的数据类型,则会出错。
:::
5.8.2.3.2. 数据类型解析
当未指定数据类型时,MySQL Shell 会尝试使用以下逻辑进行数据类型解析。该逻辑基于 JSON 规范,但有一些 MySQL Shell 特有的补充和限制:
-
Strings- 支持双引号和单引号字符串。
- 支持十六进制,如
\xNN,其中NN是十六进制数字。这用于以十六进制格式表示ASCII字符。 - 支持垂直制表符转义字符
-
还可以定义以下文字
undefined:将值定义为undefined(CLI中并不真正需要,因此不鼓励使用)。true/false:创建一个bool值null:定义一个null空值
JSON 规范以及上述规则未涵盖的任何值都会被解释为普通字符串。
5.8.2.4. 命令行帮助
使用 --help (-h) CLI 参数从命令行集成调用命令时,可以访问 MySQL Shell 联机帮助。在全局、对象和命令级别支持帮助。
:::alert-info
【Note】
内置帮助 CLI 参数不会映射到任何 API 参数,CLI 中的所有对象和命令都支持该参数。
:::
命令和参数的描述取自目标 API 函数的现有文档。
5.8.2.4.1. 全局 CLI 帮助
要检索可用于 CLI 调用的全局对象列表,请使用以下语法:
$ mysqlsh -- --help
在本例中,-- 启动了命令行集成部分。之后单独使用 --help 或 -h 选项,会列出该接口中可用的全局对象。
5.8.2.4.2. 对象帮助
要从命令行集成访问对象帮助,请使用以下语法:
$ mysqlsh -- object --help
其中 object 是需要帮助的对象,例如 dba 全局对象。此调用显示:
- 对象的简要描述。
- 可用命令的列表及其简短描述。
要检索嵌套对象的帮助,请在 --help 参数之前提供完整的对象列表。例如,要获取有关 shell.options 函数的帮助,请发出:
$ mysqlsh -- shell options --help
5.8.2.4.3. 命令帮助
要显示命令行集成中命令的帮助,请使用以下语法:
$ mysqlsh -- object command --help
此调用显示有关 command 的详细信息,包括:
- 该命令的作用的简要描述。
- 调用命令的签名。
- 匿名参数列表以及每个参数的简要描述。
- 命名参数的列表、它们的预期数据类型以及解释每个参数用途的简短描述。
对于嵌套对象中的命令,例如,应在命令前提供整个对象列表:
$ mysqlsh shell options set-persist --help
对于期望使用特定数据类型的参数,参数会被列为
--name=type
Brief description of the parameter.
类型信息表示参数的预期数据类型,例如:str、int、uint、bool、list、float 或 dict。
例如 dump-schemas 参数的 consistency key:
$ mysqlsh -- util dump-schemas --help
...
--consistent=<bool>
Enable or disable consistent data dumps. Default: true.
...
对于支持不同数据类型的参数,参数会被列为
--name[:type]=value
Brief description of the parameter.
例如,util.importTable() 操作的 columns 选项。
$ mysqlsh -- util import-table --help
...
--columns[:<type>]=<value>
Array of strings and/or integers (default: empty array) - This...
...
5.8.2.5. 对 MySQL Shell 插件的支持
要在命令行集成中使用 MySQL Shell 插件,必须为 CLI 支持明确定义函数。当为命令行集成启用 MySQL Shell 插件中定义的对象时,只有启用的特定函数可用于 CLI 调用。从 MySQL Shell ≥ 8.0.24,当你向对象添加函数成员时,它们支持 cli 布尔值选项。当 cli 设置为 true 时,函数可通过命令行集成使用。cli 选项的默认值为 false,因此除非特别启用,否则不能通过命令行集成使用函数。任何带有启用了 cli 选项的函数的对象都会导致其父对象也可在命令行集成中使用。
要通过命令行集成使函数可用,请在添加扩展对象成员时将 cli 选项设置为 true。例如:
shell.addExtensionObjectMember(object, "exampleFunction", exampleFunction,
{
brief:"Retrieves brief information",
details: ["Retrieves detailed information"],
cli: true,
parameters:
[
{
name: "param_a",
type: "string",
brief: "param_a brief"
}
]
});
然后,可以使用命令行集成中的 exampleFunction() 函数,如下所示:
mysqlsh -- customObj exampleFunction 1
如果使用 MySQL Shell < 8.0.24 版本添加了扩展对象成员,并且想要将其与命令行集成一起使用,则必须启用 cli 选项。使用此处所示的 addExtensionObjectMember 方法再次添加对象成员,这次启用 cli 选项。
5.9. JSON 集成
从 MySQL Shell 8.0.27 开始,可以激活 JSON shell 模式,以帮助将 MySQL Shell 与其他可以使用其功能的应用程序集成。在此模式下,MySQL Shell 接受 JSON 文档格式的命令。
要激活 JSON shell 模式,请定义 MYSQLSH_JSON_SHELL 环境变量。然后可以使用以下命令:
-
{"execute":json-string}
在活动的MySQL Shell模式(JavaScript、Python或SQL)中执行给定代码。代码作为一个完整的单元执行,如果不完整则返回错误。 -
{"command":json-string}
执行给定的MySQL Shell命令(请参阅 MySQL Shell 命令)。 -
{"complete":{"data":json-string[, "offset": uint}}}
根据给定数据和当前MySQL Shell上下文确定自动补全选项。




