执行 SQL 语句

Snowflake CLI 允许您使用 snow sql 命令执行 SQL 查询、临时查询或包含 SQL 查询的文件。

要执行临时查询,请运行类似下面的命令:

snow sql -q "SELECT * FROM FOO"
Copy

要执行包含 SQL 查询的文件,请运行类似下面的命令:

snow sql -f my_query.sql
Copy

snow sql 命令可以执行多个语句,在这种情况下,将返回多个结果集。例如,运行:

snow sql  -q "select 'a', 'b'; select 'c', 'd';"
Copy

结果为以下输出:

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;
$$
;
Copy

某些操作系统会解释 $$,例如进程 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"
Copy

执行时,该命令将替换 <% 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"
Copy

此示例生成以下 SQL 查询:

grant usage on database dev to eng_rl
Copy

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 %>"
Copy

在此示例中,snow sql 命令用于在项目定义文件中查找变量定义,并提取值,而不在命令行上显示它们。snowflake.yml 文件应位于当前工作目录中,或位于使用 -p 选项指定的位置中。

有关在项目定义文件中存储这些值的更多信息,请参阅 在 SQL 中使用变量

异步运行 SQL 查询

Snowflake CLI 允许您异步运行一个或多个 SQL 查询。snow sql 命令不会等待结果,而是在 Snowflake 中安排查询并返回查询 ID。查询完成后,您可以使用 !result 查询命令或 SQL RESULT_SCAN 命令获得结果。

要异步运行 SQL 查询,请用 ;> 而不是 ; 结束查询,如下所示:

snow sql -q 'select "My async query" ;>'
Copy

以下示例异步运行单个查询:

snow sql -q "select 'This is async query';>"
Copy
select 'This is async query'
+--------------------------------------+
| scheduled query ID                   |
|--------------------------------------|
| 01bc3011-080f-f2d7-0001-c1be14bae7c2 |
+--------------------------------------+

然后,您可以在 !result 查询命令中使用返回的查询 ID,用于显示查询结果:

snow sql -q '!result 01bc3011-080f-f2d7-0001-c1be14bae7c2'
Copy
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';>"
Copy
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 查询。

小技巧

如果您使用双引号 ("") 而非单引号 ('') 将 SQL 查询引起来,则可能需要根据您使用的 shell 转义感叹号 (!)。

在本地文件或 URLs 中执行 SQL

您可以在 SQL 查询中使用 !source 查询命令,以执行本地文件或基于 URL 的文件中的 SQL。例如,以下命令执行名为 my_sql_code.sql 的本地文件中的所有 SQL 命令:

snow sql -q '!source my_sql_code.sql'
Copy

您还可以在 SQL 文件中嵌套 !source 命令,例如:

select emp_id FROM employees;
!source code_file_2.sql
Copy

在本示例中,该命令执行 SELECT 查询,然后执行 code_file_2.sql 文件中的 SQL 命令。在执行 !source 查询之前,Snowflake CLI 会执行以下操作:

  • 评估变量替换和模板。

  • 读取所有嵌套文件的内容,确保不发生递归。

当变量和模板解析完毕且未检测到递归时,命令会将代码发送到 Snowflake 以执行。

备注

如果您在 !source 查询周围使用双引号 (""),而不是单引号 (''),您可能需要转义 ! (\!),具体取决于您使用的 shell。

以下示例说明了执行源文件的不同方法。

  • 执行本地文件中的代码

    本示例假定您在本地 SQL 文件中有一个简单的查询。

    cat code_to_execute.sql
    
    Copy
    select 73;
    

    要执行文件中的代码,请输入以下命令:

    snow sql -q '!source code_to_execute.sql'
    
    Copy
    select 73;
    +----+
    | 73 |
    |----|
    | 73 |
    +----+
    
  • 执行基于 URL 的文件中的代码。

    本示例假定您在 URL 的 SQL 文件中拥有相同的简单查询。

    要执行文件中的代码,请输入以下命令:

    snow sql -q '!source https://trusted-host/trusted-content.sql'
    
    Copy
    select 73;
    +----+
    | 73 |
    |----|
    | 73 |
    +----+
    
  • 执行使用变量替换和模板的代码。

    本示例假定您在本地 SQL 文件中有一个使用模板变量的查询。

    cat code_with_variable.sql
    
    Copy
    select '<% ctx.env.Message %>';
    

    要执行文件中的代码,请输入定义变量值的以下命令:

    snow sql -q '!source code_&value.sql;' -D value=with_variable --env Message='Welcome !'
    
    Copy
    select 'Welcome !';
    +-------------+
    | 'WELCOME !' |
    |-------------|
    | Welcome !   |
    +-------------+
    

备注

!source 命令支持传统 !load 别名。

列出所有 SQL 查询

!queries 查询命令列出了对一个账户的所有查询。默认情况下,该命令将列出当前会话中最近执行的 25 个查询。

例如,以下 !queries 查询命令返回特定用户的三个最新查询:

snow sql -q '!queries user=user1 amount=3'
Copy
+-------------------------------------------------------------------------------------------------------------------------------------+
| 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 格式提供日期(例如 2025-01-01T09:00:00

end_date(字符串)

仅返回在指定日期之前执行的查询。预计将以 ISO 格式提供日期(例如 2025-01-01T09:00:00

start(整数)

仅返回在指定 Unix 时间戳(毫秒)之后执行的查询。

end(整数)

仅返回在指定 Unix 时间戳(毫秒)之前执行的查询。

status(枚举)

仅返回处于以下状态之一的查询:

  • RUNNING

  • SUCCEEDED

  • FAILED

  • BLOCKED

  • QUEUED

  • ABORTED

type

仅返回以下类型之一的查询:

  • SELECT

  • INSERT

  • UPDATE

  • DELETE

  • MERGE

  • MULTI_TABLE_INSERT

  • COPY

  • COMMIT

  • ROLLBACK

  • BEGIN_TRANSACTION

  • SHOW

  • GRANT

  • CREATE

  • ALTER

以下示例使用不同的筛选器返回查询:

  • 返回在当前会话中最近执行的 25 项查询:

    snow sql -q 'select 42; select 15; !queries session'
    
    Copy
  • 返回账户中最近执行的 20 项查询:

    snow sql -q '!queries amount=20'
    
    Copy
  • 返回账户中最近执行且耗时超过 200 毫秒的 20 项查询:

    snow sql -q '!queries amount=20 duration=200'
    
    Copy
  • 返回指定仓库中最近执行的 25 项查询:

    snow sql -q '!queries warehouse=mywh'
    
    Copy

返回已完成的 SQL 查询结果

!result 查询命令根据其查询 ID 返回已完成查询的结果。您可以通过以下方式获取查询 ID:

snow sql -q '!result 01bc3011-080f-f2d7-0001-c1be14bae7c2'
Copy
+-----------------------+
| 'THIS IS ASYNC QUERY' |
|-----------------------|
| This is async query   |
+-----------------------+

中止活动 SQL 查询

!abort 查询命令会根据查询 ID 中止活动的查询。您可以通过以下方式获取查询 ID:

snow sql -q '!abort 01bc3011-080f-f2d7-0001-c1be14bae7c2'
Copy
+-------------------------------------------------------------+
| SYSTEM$CANCEL_QUERY('01BC3011-080F-F2D7-0001-C1BE14BAE7C2') |
|-------------------------------------------------------------|
| Identified SQL statement is not currently executing.        |
+-------------------------------------------------------------+

在单个事务中输入多个命令

--single-transaction 选项允许您输入多个 SQL 命令,并将它们作为一个“要么全部执行,要么全部回滚”的命令集合来执行。将命令作为一个事务执行,可以确保所有命令都成功完成后才提交更改。如果其中任何一个命令失败,之前已成功命令所做的更改也不会被保留。

以下示例展示了事务执行成功和失败的情况:

  • 命令执行成功

    snow sql -q "insert into my_tbl values (123); insert into my_tbl values (124);" --single-transaction
    
    Copy
    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"
    
    Copy
    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
    
    Copy
    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"
Copy
select count(*) from my_tbl
+----------+
| COUNT(*) |
|----------|
| 0        |
+----------+

在交互模式下输入 SQL 命令

snow sql 命令支持交互模式,允许您一次输入一个 SQL 命令。交互模式提供以下功能:

  • 语法突出显示

    交互模式语法突出显示
  • 输入时代码补全

    交互模式代码补全
  • 可搜索的历史记录

    CTRL-R: 可以搜索命令历史记录:

    交互模式可搜索的历史记录
  • 多行输入

    如果按下 ENTER 键时,当前行末尾没有分号 (;),光标会移动到下一行,等待输入更多命令,直到语句以分号结束为止。

    交互模式多行输入

要使用交互模式,请输入 snow sql 命令,然后输入 ENTER,如下所示:

snow sql
Copy

该命令会打开一个带有 > 提示符的子 shell,您可以在其中交互式地输入 SQL 命令:

$ snow sql
  ╭───────────────────────────────────────────────────────────────────────────────────╮
  │ Welcome to Snowflake-CLI REPL                                                     │
  │ Type 'exit' or 'quit' to leave                                                    │
  ╰───────────────────────────────────────────────────────────────────────────────────╯
  >

然后,您可以输入 SQL 命令,如下所示:

> create table my_table (c1 int);
Copy
+-------------------------------------+
| status                              |
|-------------------------------------|
| Table MY_TABLE successfully created.|
+-------------------------------------+

备注

每条 SQL 语句必须以分号 (;) 结尾。

要退出交互模式,请输入 exitquitCTRL-D

语言: 中文