执行 SQL 语句¶
The snow sql command lets you execute ad-hoc SQL queries or files containing SQL queries using the following options:
To execute an ad-hoc query, use the
-qcommand-line option. For example, to execute a simple SQL SELECT query, as shown in the following example:snow sql -q "SELECT * FROM FOO;"
To execute a file containing a SQL query, use the
-fcommand-line option to specify the path to the file. For example, to execute a file containing a SQL query, as shown in the following example:snow sql -f my_query.sql
The snow sql command also can execute multiple statements; in that case, multiple result sets are returned. For example running:
snow sql -q "select 'a', 'b'; select 'c', 'd';"
结果为以下输出:
select 'a', 'b';
+-----------+
| 'A' | 'B' |
|-----+-----|
| a | b |
+-----------+
select 'c', 'd';
+-----------+
| 'C' | 'D' |
|-----+-----|
| c | d |
+-----------+
您还可以在 Snowflake CLI 中执行 脚本块,但要注意 $$ 分隔符。
例如:
EXECUTE IMMEDIATE $$
-- Snowflake Scripting code
DECLARE
radius_of_circle FLOAT;
area_of_circle FLOAT;
BEGIN
radius_of_circle := 3;
area_of_circle := pi() * radius_of_circle * radius_of_circle;
RETURN area_of_circle;
END;
$$
;
某些操作系统会解释 $$,例如进程 ID (PID),而不是将其识别为脚本块分隔符。为解决此限制,您可以使用以下替代方案:
如果您仍然想在命令行上指定脚本块,可以转义
$$分隔符,如\$\$中所示。您还可以将带有默认
$$分隔符的脚本块放入单独的文件中,并使用snow sql -f <filename>命令进行调用。
有关更多信息,请参阅 snow sql 命令。
为 SQL 模板使用变量¶
在某些情况下,您可能需要根据上下文更改 SQL 查询。snow sql 命令支持客户端变量替换,允许您在提交查询之前在命令中使用在本地解析的变量。 变量在 SQL 字符串中采用形式 -<% variable_name %>, and the -D (or --variable) 选项指定变量的值。
备注
您当前可以使用 SnowSQL
&variable_name和<% variable_name %>syntax for templates. However, Snowflake recommends using the<% variable_name %>语法。
例如,要使用客户端变量指定数据库,可以输入类似下面的命令:
snow sql -q "select * from <% database %>.logs" -D "database=dev"
执行时,该命令将替换 <% database %> 变量中的值 dev 以创建 dev.logs 文件名,然后将 select * from dev.logs SQL 查询发送到 Snowflake 进行处理。
您还可以指定多个变量输入,如下所示:
snow sql \
-q "grant usage on database <% database %> to <% role %>" \
-D "database=dev" \
-D "role=eng_rl"
此示例生成以下 SQL 查询:
grant usage on database dev to eng_rl
--enable-templating 选项允许您指定在 SQL 查询中解析哪些模板语法。Snowflake CLI 支持以下语法:
STANDARD:支持标准的 Snowflake CLI 变量语法 (<% variable_name %>)。默认启用。LEGACY:支持 SnowSQL 变量语法 (&{ variable_name }或&variable_name)。默认启用。JINJA:支持 jinja 变量语法 ({{ variable_name }})。默认禁用。ALL:允许所有支持的语法。默认禁用。NONE:不支持模板。默认禁用。
以下示例说明了支持模板的不同方法:
禁用模板,这样两个查询变量都无法解析:
snow sql --enable-templating NONE -q "select '<% not_resolved %> ¬_resolved'"
允许 JINJA 和 STANDARD 模板,同时禁用 LEGACY 模板:
snow sql --enable-templating JINJA --enable-templating STANDARD -q "select '<% resolved %> {{ resolved }} ¬_resolved'"
启用所有语法,因此 SQL 查询可以解析所有三种语法:
snow sql --enable-templating ALL -q "select '<% resolved %> {{ resolved }}'" snow sql --enable-templating ALL -q "select '&resolved {{ resolved }}'"
备注
JINJA 变量(如果已启用)将在 STANDARD 和 LEGACY 变量之后解析。
在 snowflake.yml 项目定义文件中存储变量¶
将变量指定为 snow sql 命令行选项可能并不总是实用的,或者您可能不想在命令行中指定敏感值。在这种情况下,您可以在 snowflake.yml 项目定义文件中定义变量和值。然后您可以以 <% ctx.env.<variable_name> %> 形式指定变量名称,而不是使用 -D "<变量> = <value>" 选项。
使用上一部分的示例,您可以将数据库和角色变量存储在 snowflake.yml 文件中,并将查询更改为:
snow sql -q "grant usage on database <% ctx.env.database %> to <% ctx.env.role %>"
在此示例中,snow sql 命令用于在项目定义文件中查找变量定义,并提取值,而不在命令行上显示它们。snowflake.yml 文件应位于当前工作目录中,或位于使用 -p 选项指定的位置中。
有关在项目定义文件中存储这些值的更多信息,请参阅 在 SQL 中使用变量。
Executing SQL queries asynchronously¶
Snowflake CLI lets you execute one or more SQL queries asynchronously. Instead of waiting for a result, the snow sql command schedules the queries at Snowflake and returns a query ID. After a query finishes, you can get the result using the !result query command or the SQL RESULT_SCAN command.
To execute a SQL query asynchronously, end the query with ;> instead of ;, as shown:
snow sql -q 'select "My async query" ;>'
The following example executes a single query asynchronously:
snow sql -q "select 'This is async query';>"
select 'This is async query'
+--------------------------------------+
| scheduled query ID |
|--------------------------------------|
| 01bc3011-080f-f2d7-0001-c1be14bae7c2 |
+--------------------------------------+
然后,您可以在 !result 查询命令中使用返回的查询 ID,用于显示查询结果:
snow sql -q '!result 01bc3011-080f-f2d7-0001-c1be14bae7c2'
path-to-private-key-file
+-----------------------+
| 'THIS IS ASYNC QUERY' |
|-----------------------|
| This is async query |
+-----------------------+
您还可以在查询字符串中异步和同步执行多项查询,如下所示:
snow sql -q "select 'This is async query';> select 'Not an async query'; select 'Another async query';>"
select 'This is async query'
+--------------------------------------+
| scheduled query ID |
|--------------------------------------|
| 01bc3b8c-0109-2e81-0000-0f2d0e5a4a32 |
+--------------------------------------+
select 'Not an async query';
+----------------------+
| 'NOT AN ASYNC QUERY' |
|----------------------|
| Not an async query |
+----------------------+
select 'Another async query'
+--------------------------------------+
| scheduled query ID |
|--------------------------------------|
| 01bc3b8c-0109-2e81-0000-0f2d0e5a4a36 |
+--------------------------------------+
使用 SQL 查询命令¶
Snowflake CLI 提供以下命令供您在 SQL 查询中使用:
!source,在本地文件或 URLs 中执行 SQL。
!queries,列出所有 SQL 查询。
!result,显示 SQL 查询的结果。
!abort,中止活动的 SQL 查询。
!edit, which opens an external editor to modify and execute SQL commands.
小技巧
如果您使用双引号 ("") 而非单引号 ('') 将 SQL 查询引起来,则可能需要根据您使用的 shell 转义感叹号 (!)。
在本地文件或 URLs 中执行 SQL¶
您可以在 SQL 查询中使用 !source 查询命令,以执行本地文件或基于 URL 的文件中的 SQL。例如,以下命令执行名为 my_sql_code.sql 的本地文件中的所有 SQL 命令:
snow sql -q '!source my_sql_code.sql'
您还可以在 SQL 文件中嵌套 !source 命令,例如:
select emp_id FROM employees;
!source code_file_2.sql
在本示例中,该命令执行 SELECT 查询,然后执行 code_file_2.sql 文件中的 SQL 命令。在执行 !source 查询之前,Snowflake CLI 会执行以下操作:
评估变量替换和模板。
读取所有嵌套文件的内容,确保不发生递归。
当变量和模板解析完毕且未检测到递归时,命令会将代码发送到 Snowflake 以执行。
备注
如果您在 !source 查询周围使用双引号 (""),而不是单引号 (''),您可能需要转义 ! (\!),具体取决于您使用的 shell。
以下示例说明了执行源文件的不同方法。
执行本地文件中的代码
本示例假定您在本地 SQL 文件中有一个简单的查询。
cat code_to_execute.sqlselect 73;要执行文件中的代码,请输入以下命令:
snow sql -q '!source code_to_execute.sql'
select 73; +----+ | 73 | |----| | 73 | +----+
执行基于 URL 的文件中的代码。
本示例假定您在 URL 的 SQL 文件中拥有相同的简单查询。
要执行文件中的代码,请输入以下命令:
snow sql -q '!source https://trusted-host/trusted-content.sql'
select 73; +----+ | 73 | |----| | 73 | +----+
执行使用变量替换和模板的代码。
本示例假定您在本地 SQL 文件中有一个使用模板变量的查询。
cat code_with_variable.sqlselect '<% ctx.env.Message %>';要执行文件中的代码,请输入定义变量值的以下命令:
snow sql -q '!source code_&value.sql;' -D value=with_variable --env Message='Welcome !'
select 'Welcome !'; +-------------+ | 'WELCOME !' | |-------------| | Welcome ! | +-------------+
备注
!source 命令支持传统 !load 别名。
列出所有 SQL 查询¶
!queries 查询命令列出了对一个账户的所有查询。默认情况下,该命令将列出当前会话中最近执行的 25 个查询。
例如,以下 !queries 查询命令返回特定用户的三个最新查询:
snow sql -q '!queries user=user1 amount=3'+-------------------------------------------------------------------------------------------------------------------------------------+ | QUERY ID | SQL TEXT | STATUS | DURATION_MS | |--------------------------------------+--------------------------------------------------------------------+-----------+-------------| | 01bc3040-080f-f4f9-0001-c1be14bb603a | select current_version(); | SUCCEEDED | 3858 | | 01bc303d-080f-f4e9-0001-c1be14bb1812 | SELECT SYSTEM$CANCEL_QUERY('01bc3011-080f-f2d7-0001-c1be14bae7c2') | SUCCEEDED | 564 | | 01bc3011-080f-f2d7-0001-c1be14bae7c2 | select 'This is async query' | SUCCEEDED | 931 | +-------------------------------------------------------------------------------------------------------------------------------------+
您可以使用以下筛选器来缩小返回的查询列表:
筛选器 |
默认值 |
描述 |
|---|---|---|
amount(整数) |
25 |
要返回的最近查询数(默认值:25)。 |
session(布尔值) |
不适用 |
如果提供,则仅返回在当前会话中执行的查询。 |
warehouse(字符串) |
无 |
返回仅在指定仓库上执行的查询。 |
user(字符串) |
无 |
返回仅由指定用户执行的查询。 |
duration(毫秒) |
0 |
仅返回至少花费指定毫秒数的查询。 |
start_date(字符串) |
无 |
仅返回在指定日期之后执行的查询。预计将以 ISO 格式提供日期(例如 |
end_date(字符串) |
无 |
仅返回在指定日期之前执行的查询。预计将以 ISO 格式提供日期(例如 |
start(整数) |
无 |
仅返回在指定 Unix 时间戳(毫秒)之后执行的查询。 |
end(整数) |
无 |
仅返回在指定 Unix 时间戳(毫秒)之前执行的查询。 |
status(枚举) |
无 |
仅返回处于以下状态之一的查询:
|
type |
无 |
仅返回以下类型的查询:
|
以下示例使用不同的筛选器返回查询:
返回在当前会话中最近执行的 25 项查询:
snow sql -q 'select 42; select 15; !queries session'
返回账户中最近执行的 20 项查询:
snow sql -q '!queries amount=20'
返回账户中最近执行且耗时超过 200 毫秒的 20 项查询:
snow sql -q '!queries amount=20 duration=200'
返回指定仓库中最近执行的 25 项查询:
snow sql -q '!queries warehouse=mywh'
返回已完成的 SQL 查询结果¶
!result 查询命令根据其查询 ID 返回已完成查询的结果。您可以通过以下方式获取查询 ID:
snow sql -q '!result 01bc3011-080f-f2d7-0001-c1be14bae7c2'
+-----------------------+
| 'THIS IS ASYNC QUERY' |
|-----------------------|
| This is async query |
+-----------------------+
中止活动 SQL 查询¶
!abort 查询命令会根据查询 ID 中止活动的查询。您可以通过以下方式获取查询 ID:
snow sql -q '!abort 01bc3011-080f-f2d7-0001-c1be14bae7c2'
+-------------------------------------------------------------+
| SYSTEM$CANCEL_QUERY('01BC3011-080F-F2D7-0001-C1BE14BAE7C2') |
|-------------------------------------------------------------|
| Identified SQL statement is not currently executing. |
+-------------------------------------------------------------+
Open an external editor to modify and execute SQL commands¶
The !edit query command opens an external editor where you can modify SQL commands to execute when you exit the editor. The editor is specified in the EDITOR environment variable or, if the environment variable is not set, the default system editor is used.
要在外部编辑器中输入命令,请按照以下步骤操作:
如果尚未在 shell 中定义,请将
EDITOR环境变量设置为首选文本编辑器。Enter the
snow sqlcommand:snow sql在
>提示时,输入!edit命令:> !edit该命令打开指定的文本编辑器。
Enter your SQL commands in the editor, as shown:
SELECT current_user() ;
保存文件并退出编辑器。
将显示您输入的命令,如下所示:
✓ Edited SQL loaded into prompt. Modify as needed or press Enter to execute. > select current_user();
要执行命令,请选择
ENTER。将显示命令输出,如下所示:
+----------------+ | CURRENT_USER() | |----------------| | USER1 | +----------------+
在单个事务中输入多个命令¶
--single-transaction 选项允许您输入多个 SQL 命令,并将它们作为一个“要么全部执行,要么全部回滚”的命令集合来执行。将命令作为一个事务执行,可以确保所有命令都成功完成后才提交更改。如果其中任何一个命令失败,之前已成功命令所做的更改也不会被保留。
以下示例展示了事务执行成功和失败的情况:
命令执行成功
snow sql -q "insert into my_tbl values (123); insert into my_tbl values (124);" --single-transaction
BEGIN; +----------------------------------+ | status | |----------------------------------| | Statement executed successfully. | +----------------------------------+ insert into my_tbl values (123); +-------------------------+ | number of rows inserted | |-------------------------| | 1 | +-------------------------+ insert into my_tbl values (124); +-------------------------+ | number of rows inserted | |-------------------------| | 1 | +-------------------------+ COMMIT +----------------------------------+ | status | |----------------------------------| | Statement executed successfully. | +----------------------------------+
然后,您可以验证命令是否已提交到数据库中:
snow sql -q "select count(*) from my_tbl"
select count(*) from my_tbl +----------+ | COUNT(*) | |----------| | 2 | +----------+
单个事务失败
snow sql -c patcli -q "insert into my_tbl values (123); insert into my_tbl values (124); select BAD;" --single-transaction
BEGIN; +----------------------------------+ | status | |----------------------------------| | Statement executed successfully. | +----------------------------------+ insert into my_tbl values (123); +-------------------------+ | number of rows inserted | |-------------------------| | 1 | +-------------------------+ insert into my_tbl values (124); +-------------------------+ | number of rows inserted | |-------------------------| | 1 | +-------------------------+ select BAD; ╭─ Error ───────────────────────────────────────────────────────────────────────────────╮ │ 000904 (42000): 01bc3b84-0810-0247-0001-c1be14ee11ce: SQL compilation error: error │ │ line 1 at position 7 │ │ invalid identifier 'BAD' │ ╰───────────────────────────────────────────────────────────────────────────────────────╯
然后,您可以验证命令是否未提交到数据库中:
snow sql -q "select count(*) from my_tbl"select count(*) from my_tbl +----------+ | COUNT(*) | |----------| | 0 | +----------+
在交互模式下输入 SQL 命令¶
snow sql 命令支持交互模式,允许您一次输入一个 SQL 命令。交互模式提供以下功能:
语法突出显示
输入时代码补全
可搜索的历史记录
按 CTRL-R: 可以搜索命令历史记录:
多行输入
如果按下 ENTER 键时,当前行末尾没有分号 (
;),光标会移动到下一行,等待输入更多命令,直到语句以分号结束为止。
要使用交互模式,请输入 snow sql 命令,然后输入 ENTER,如下所示:
snow sql
该命令会打开一个带有 > 提示符的子 shell,您可以在其中交互式地输入 SQL 命令:
$ snow sql
╭───────────────────────────────────────────────────────────────────────────────────╮
│ Welcome to Snowflake-CLI REPL │
│ Type 'exit' or 'quit' to leave │
╰───────────────────────────────────────────────────────────────────────────────────╯
>
然后,您可以输入 SQL 命令,如下所示:
> create table my_table (c1 int);
+-------------------------------------+
| status |
|-------------------------------------|
| Table MY_TABLE successfully created.|
+-------------------------------------+
备注
每条 SQL 语句必须以分号 (;) 结尾。
要退出交互模式,请输入 exit、quit 或 CTRL-D。